/* ============================================================
   MOTION - motion is emotion. Everything glides, nothing snaps.

   Three tiers, degrading gracefully:
   1. No JS  → document fully composed; CSS-only entrance fades
               where scroll-driven animations are supported.
   2. JS     → IntersectionObserver reveals (.is-visible) +
               per-chapter scroll progress (--p: 0→1) for parallax.
   3. Reduced motion → still-photography edit: short fades only.
   ============================================================ */

/* --- Reveal grammar ---
   data-reveal="fade"   : opacity
   data-reveal="focus"  : blur-to-focus (the mist lifting)
   data-reveal="rise"   : settles upward like a laid photograph
   data-reveal="veil"   : clip-path curtain, for full frames
   Optional --reveal-delay staggers within a composition.       */

[data-reveal] {
  opacity: 0;
  transition:
    opacity var(--dur-breath) var(--glide),
    transform var(--dur-breath) var(--glide),
    filter var(--dur-breath) var(--glide),
    clip-path var(--dur-breath) var(--glide);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="focus"] {
  filter: none;
}
[data-reveal="rise"] {
  transform: translateY(1rem);
}
[data-reveal="rise-tilt"] {
  transform: translateY(1rem) rotate(0.3deg);
}
/* veil: the curtain lifts on the child image, not the observed element -
   a fully clipped target reports zero intersection and would never reveal */
[data-reveal="veil"] {
  opacity: 1;
}
[data-reveal="veil"] img {
  clip-path: inset(0 0 100% 0);
  transition: clip-path calc(var(--dur-breath) * 1.15) var(--glide);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="veil"] .media__video {
  clip-path: inset(0 0 100% 0);
  transition:
    opacity 1.45s var(--drift),
    clip-path calc(var(--dur-breath) * 1.15) var(--glide);
  transition-delay: 0ms, var(--reveal-delay, 0ms);
}

.is-visible[data-reveal] {
  opacity: 1;
  transform: none;
  filter: none;
}
.is-visible[data-reveal="veil"] img {
  clip-path: inset(0 0 0% 0);
}
.is-visible[data-reveal="veil"] .media__video {
  clip-path: inset(0 0 0% 0);
}

/* --- Parallax planes: driven by --p (0→1 across each stage) --- */
.par-bg {
  transform: translateY(calc(var(--p) * -4vh)) scale(calc(1 + var(--p) * 0.06));
}
.par-mid {
  transform: translateY(calc(var(--p) * -9vh));
}
.par-fore {
  transform: translateY(calc(var(--p) * -16vh));
}
.par-ghost {
  transform: translateY(calc(var(--p) * 12vh));
}

/* Fog drifts sideways at its own pace - independent foreground life */
.fog {
  position: absolute;
  inset: -20% -30%;
  background:
    radial-gradient(60% 45% at 28% 62%, var(--veil), transparent 70%),
    radial-gradient(50% 38% at 76% 30%, var(--veil), transparent 72%);
  opacity: calc(0.9 - var(--p) * 0.55);
  transform: translateX(calc(var(--p) * 9vw));
  filter: blur(2px);
}

/* Colossal titles stay clear while the visitor scrolls past */
.stage .t-colossal {
  filter: none;
  opacity: 1;
}

/* Frames dim slightly as the camera moves past them */
.stage__pin .media--full::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  background: var(--canvas);
  opacity: calc(max(var(--p) - 0.72, 0) * 2.6);
  pointer-events: none;
  transition: none;
}

/* Light leak - a slow golden sweep for the dusk chapter */
.leak {
  position: absolute;
  inset: -30%;
  background: radial-gradient(42% 30% at calc(18% + var(--p) * 55%) 68%, rgba(232, 176, 125, 0.24), transparent 70%);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* The breathing cue ("BEGIN ⎯") */
@keyframes breathe {
  0%, 100% { opacity: 0.45; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(0.4rem); }
}
.begin-cue {
  position: absolute;
  z-index: 4;
  bottom: clamp(1.5rem, 5vh, 3rem);
  left: 50%;
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.875rem;
}
.begin-cue::after {
  content: "";
  width: 1px;
  height: 3.25rem;
  background: currentColor;
  animation: breathe 4.5s var(--drift) infinite;
}

/* Prologue - house lights dim, the wordmark letter-spaces open */
@keyframes prologue-fade {
  0% { opacity: 1; visibility: visible; }
  72% { opacity: 1; }
  100% { opacity: 0; visibility: hidden; }
}
@keyframes prologue-track {
  from { letter-spacing: 0.04em; opacity: 0; filter: none; }
  30% { opacity: 1; }
  to { letter-spacing: 0.16em; opacity: 1; filter: none; }
}
.prologue {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding-inline: clamp(1rem, 4vw, 3rem);
  background: var(--navy);
  animation: prologue-fade 2.1s var(--drift) 0.1s both;
  pointer-events: none;
}
.prologue .wordmark {
  color: var(--ivory);
  max-width: calc(100vw - clamp(2rem, 8vw, 8rem));
  font-size: clamp(2.25rem, 5.7vw, 5.8rem);
  letter-spacing: clamp(0.06em, 0.8vw, 0.16em);
  text-align: center;
  white-space: nowrap;
  animation: prologue-track 1.8s var(--glide) 0.1s both;
}
.prologue-mobile-break {
  display: inline;
}

@media (max-width: 640px) {
  .prologue .wordmark {
    max-width: calc(100vw - 2rem);
    font-size: clamp(1.85rem, 9vw, 2.45rem);
    line-height: 1.08;
    letter-spacing: clamp(0.08em, 1.15vw, 0.14em);
    white-space: normal;
  }

  .prologue-mobile-break {
    display: block;
    height: 0.28em;
  }
}

/* ------------------------------------------------------------
   Tier 1 - no JS: everything visible; scroll-driven fades where
   the platform offers them for free.
   ------------------------------------------------------------ */
.no-js [data-reveal],
.no-js [data-reveal="veil"] img {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: none;
  transition: none;
}
@supports (animation-timeline: view()) {
  .no-js [data-reveal] {
    animation: nojs-enter both;
    animation-timeline: view();
    animation-range: entry 5% entry 45%;
  }
  @keyframes nojs-enter {
    from { opacity: 0; }
    to { opacity: 1; }
  }
}
.no-js .stage {
  height: auto;
}
.no-js .stage__pin {
  position: relative;
  min-height: 100svh;
  height: auto;
}
.no-js .stage .t-colossal {
  filter: none;
  opacity: 1;
}
.no-js .fog {
  opacity: 0.5;
  transform: none;
}

/* ------------------------------------------------------------
   Tier 3 - reduced motion: the still-photography edit.
   Composed, legible, calm. Fades only, and brief.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  [data-reveal],
  [data-reveal="veil"] img {
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
    transition: opacity 0.3s ease !important;
  }
  .par-bg, .par-mid, .par-fore, .par-ghost,
  .stage .t-colossal,
  .fog,
  .leak {
    transform: none !important;
    filter: none !important;
    opacity: 1;
    animation: none !important;
  }
  .fog { opacity: 0.4; }
  .leak { opacity: 0.5; }
  .stage {
    height: auto !important;
  }
  .stage__pin {
    position: relative;
    min-height: 100svh;
    height: auto;
  }
  .begin-cue::after,
  .prologue,
  .prologue .wordmark {
    animation: none !important;
  }
  .prologue {
    display: none;
  }
}
