/* intro.css -- the envelope video intro (ported from hardik-nandini animations.css,
 * itself pukhraj-poorva's). js/intro.js drives the classes:
 *   .is-playing   tapped: the pill retires, the clip plays
 *   .is-leaving   the 2000ms dissolve: opacity + scale push toward the guest and a
 *                 warm ivory bloom, while the door slide fades up underneath
 * JS removes the node on transitionend (opacity) with a fallback that MUST outlast
 * --intro-fade (js/intro.js REMOVE_FALLBACK_MS) -- change one, change both.
 * No logo page and no seal overlay (the clip's own seal is baked in).
 */
.intro {
  --intro-bg: #a4958c;          /* the clip's final-frame edge colour */
  --intro-fade: 2000ms;
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--intro-bg);
  overflow: hidden;
  transform: scale(1);
  isolation: isolate;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.intro__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--intro-bg);
}

/* Sealed-envelope <img> stand-in for the video's poster: Chrome drops the poster
 * at play() ~430ms before the first frame presents, which flashes the background.
 * JS hides this the frame the video paints (requestVideoFrameCallback). */
.intro__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.intro__poster.is-hidden { display: none; }

/* Wider than a phone: show the whole envelope as a centred column (the clip is
 * 1080x1920) on its own edge colour instead of cropping it to the seal. */
@media (min-aspect-ratio: 3/4) {
  .intro__video, .intro__poster { object-fit: contain; }
}

.intro__open {
  position: absolute;
  /* Horizontally centred near the bottom (clear of the seal), as on hardik-nandini.
     Inset + auto margins, not translateX: the pulse keyframes own `transform`. */
  left: 0;
  right: 0;
  bottom: calc(clamp(26px, 8vh, 76px) + env(safe-area-inset-bottom, 0px));
  width: max-content;
  margin: 0 auto;
  transform: translateZ(0);
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.72em 1.5em;
  border: 0;
  border-radius: 999px;
  background: rgba(74, 52, 36, 0.55);
  box-shadow: 0 8px 26px rgba(40, 24, 12, 0.28);
  color: #fff8f0;
  font-family: "Quattrocento", Georgia, "Times New Roman", serif;
  font-size: clamp(1rem, 3.8vw, 1.2rem);
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  animation: sr-pulse 2.6s ease-in-out infinite;
}
.intro__open-dot {
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  background: #ffd9a8;
  box-shadow: 0 0 10px rgba(255, 201, 132, 0.9);
}
.intro__open:focus-visible { outline: 3px solid #fff8f0; outline-offset: 3px; }
@keyframes sr-pulse {
  0%, 100% { transform: translateZ(0) scale(1); }
  50%      { transform: translateZ(0) scale(1.045); }
}

/* Once playback starts, retire the affordance (opacity only). */
.intro.is-playing { cursor: default; }
.intro.is-playing .intro__open {
  opacity: 0;
  pointer-events: none;
  animation: none;
  transition: opacity 240ms ease;
}

/* Exit: a slow dissolve on a curve that keeps light in the frame for the whole
 * fade, a gentle scale push-through, and a warm ivory bloom that swells once so
 * the envelope opens INTO light. */
.intro::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(ellipse at 50% 42%, rgba(255, 247, 232, 0.95), rgba(255, 247, 232, 0) 70%);
}
.intro.is-leaving::before { animation: sr-intro-bloom var(--intro-fade) ease-in-out both; }
@keyframes sr-intro-bloom {
  0%   { opacity: 0; }
  30%  { opacity: 0.85; }
  100% { opacity: 0; }
}
.intro.is-leaving {
  opacity: 0;
  transform: scale(1.07);
  pointer-events: none;
  transition:
    opacity var(--intro-fade) cubic-bezier(0.45, 0.05, 0.25, 1),
    transform var(--intro-fade) cubic-bezier(0.22, 1, 0.36, 1);
}

/* The door slide waits unseen under the envelope, then fades up out of a slight
 * overscale as the envelope melts. intro.js owns this (adds .sr-enter, removes it
 * on animationend so no transform stays on the stage). Opacity is full by 45%; the
 * tail is a pure scale settle. */
html.is-locked .scene--door .stage { opacity: 0; }
.scene--door .stage.sr-enter {
  transform-origin: 50% calc(var(--sr-vh, 100vh) / 2);
  animation: sr-door-enter 2.8s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes sr-door-enter {
  from { opacity: 0; transform: scale(1.05); }
  45%  { opacity: 1; }
  to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .intro__open { animation: none; }
  .intro.is-leaving { transform: none; transition: opacity 250ms ease; }
  .intro::before, .intro.is-leaving::before { animation: none; opacity: 0; }
  .scene--door .stage.sr-enter { animation: none; }
}
