/* Envelope opening scene for the formal edition.
   Sequence (driven by .opening on <html>, see envelope.js):
     seal lifts -> flap folds back -> letter rises -> scene fades to the page.
   Layer order inside .envelope, bottom to top:
     inside (liner) < flap once open < letter < pocket < flap while closed < seal */

.scene { display: none; }

.sealed body,
.opening body { overflow: hidden; }

.sealed .scene,
.opening .scene {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  padding: 24px 16px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .45 0 0 0 0 .38 0 0 0 0 .25 0 0 0 .05 0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(ellipse at 50% 40%, var(--paper) 0%, var(--ivory) 55%, #ece5d5 100%);
}

/* The invitation underneath waits, then eases in as the scene fades. */
.sealed body > :not(.scene),
.opening body > :not(.scene) {
  opacity: 0;
  transform: translateY(18px);
}

.scene__stage {
  /* Sized so the open flap (60% of the envelope's height above it) still fits
     once the stage slides down while opening. */
  --w: min(86vw, 540px, calc((100svh - 80px) / 1.65 * 1.38));
  position: relative;
  width: var(--w);
  transition: translate .9s cubic-bezier(.45, 0, .2, 1) .3s;
  animation: env-arrive 1.2s cubic-bezier(.2, .7, .2, 1) both;
}

@keyframes env-arrive {
  from { opacity: 0; transform: translateY(30px) rotate(-1.5deg); }
  to   { opacity: 1; transform: none; }
}

.scene__hint {
  margin: 0;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold);
  animation: hint-pulse 2.8s ease-in-out 1.4s infinite both;
}
@keyframes hint-pulse {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}

/* ------------------------------------------------------------ envelope --- */
.envelope {
  position: relative;
  aspect-ratio: 7.25 / 5.25;
  /* Perspective here but no preserve-3d, so z-index still orders the layers. */
  perspective: 1400px;
  cursor: pointer;
}

.envelope__shadow {
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: -5%;
  height: 12%;
  background: radial-gradient(ellipse at center, rgba(29, 36, 54, .28), transparent 70%);
  filter: blur(6px);
  z-index: -1;
}

.envelope__inside {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: url("assets/liner.svg") center / 64px repeat;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .2);
}

/* The card tucked inside: only its top shows once the flap is open. */
.envelope__letter {
  position: absolute;
  left: 5%;
  right: 5%;
  top: 5%;
  height: 90%;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 7%;
  text-align: center;
  background: var(--paper);
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .18);
  transition: transform 1.5s cubic-bezier(.32, .72, .2, 1) 1.05s;
}
.envelope__letter::before {
  content: "";
  position: absolute;
  inset: 3.5%;
  border: 1px solid var(--gold-light);
}
.envelope__letter p { margin: 0; }
.envelope__letter-over {
  font-family: var(--sans);
  font-size: clamp(7px, 1.6vw, 10px);
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold);
}
.envelope__letter-name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(17px, 4.4vw, 31px);
  line-height: 1.12;
  max-width: 11ch;
  text-wrap: balance;
  color: var(--navy);
}
.envelope__letter-title {
  font-family: var(--serif);
  font-size: clamp(12px, 2.6vw, 18px);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--navy);
}

/* Front of the envelope: side folds with a V notch, then the bottom fold. */
.envelope__pocket {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.envelope__sides,
.envelope__bottom {
  position: absolute;
  inset: 0;
}
.envelope__sides {
  background: linear-gradient(90deg, #182030, #212a3f 50%, #182030);
  clip-path: polygon(0 0, 50% 54%, 100% 0, 100% 100%, 0 100%);
}
.envelope__bottom {
  background: linear-gradient(180deg, #273049, #1f2739);
  clip-path: polygon(0 100%, 50% 44%, 100% 100%);
  filter: drop-shadow(0 -1px 2px rgba(0, 0, 0, .35));
}
/* Postage: a stamp in the corner with the postmark struck beside it. */
.envelope__postage {
  position: absolute;
  top: 6%;
  right: 5%;
  width: 17%;
  /* Above the flap: the stamp belongs to the face of the envelope, and our
     flap is drawn over the front, so it would otherwise be buried. */
  z-index: 6;
  pointer-events: none;
}
.envelope__stamp {
  display: block;
  width: 100%;
  height: auto;
  transform: rotate(2.5deg);
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .35));
}
.envelope__postmark {
  position: absolute;
  right: 78%;
  top: 2%;
  width: 124%;
  height: auto;
  transform: rotate(-9deg);
}

.envelope__to {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12%;
  margin: 0;
  text-align: center;
  font-family: "Pinyon Script", "Snell Roundhand", cursive;
  font-size: clamp(24px, 6.4vw, 42px);
  line-height: 1;
  color: var(--gold-light);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .3);
}

/* Top flap. clip-path would flatten 3D on the rotating element itself, so
   each face carries its own clipped child. */
.envelope__flap {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 60%;
  z-index: 5;
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  transition:
    transform .9s cubic-bezier(.5, 0, .25, 1) .35s,
    z-index 0s linear .8s;
}
.envelope__flap-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
}
.envelope__flap-face > div {
  position: absolute;
  inset: 0;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.envelope__flap-face--front { filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .4)); }
.envelope__flap-face--front > div { background: linear-gradient(180deg, #1c2335, #2a3350); }
.envelope__flap-face--back { transform: rotateX(180deg); }
.envelope__flap-face--back > div { background: url("assets/liner.svg") center top / 64px repeat; }

/* ---------------------------------------------------------------- seal --- */
.seal {
  position: absolute;
  left: 50%;
  top: 60%;
  z-index: 6;
  width: 23%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .35));
  transition: transform .45s cubic-bezier(.3, 0, .2, 1), opacity .4s ease .1s;
}
.seal svg { display: block; width: 100%; height: 100%; }
.seal:hover { transform: translate(-50%, -50%) scale(1.05); }
.seal:focus-visible { outline: 2px solid var(--gold); outline-offset: 6px; }

/* --------------------------------------------------------------- open --- */
.opening .seal {
  opacity: 0;
  transform: translate(-50%, -80%) scale(1.15);
}
.opening .scene__stage { translate: 0 calc(var(--w) / 1.38 * .42); }
.opening .envelope__flap {
  transform: rotateX(180deg);
  z-index: 2;
}
.opening .envelope__letter { transform: translateY(-86%) scale(1.04); }
.opening .scene__hint { animation: none; opacity: 0; transition: opacity .3s; }

.opening .scene {
  opacity: 0;
  visibility: hidden;
  transition: opacity .9s ease 3.3s, visibility 0s linear 4.2s;
}
/* Starts as the scene finishes fading, so the two never double-expose. */
.opening body > :not(.scene) {
  opacity: 1;
  transform: none;
  transition: opacity .9s ease 4s, transform .9s ease 4s;
}
.opening body { overflow: auto; }

/* envelope.js moves focus here after opening; it isn't interactive. */
.invite__name:focus { outline: none; }
