/* Motion contract. Only transform/opacity animate (plus one-time stroke-dashoffset).
   Everything below is gated on html.js + prefers-reduced-motion: no-preference,
   so no-JS and reduced-motion always render final states. */

/* ---------- Fade in ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js [data-fade] {
    transition: opacity 700ms cubic-bezier(.25, .1, .25, 1) var(--fade-delay, 0ms),
                transform 700ms cubic-bezier(.25, .1, .25, 1) var(--fade-delay, 0ms);
  }
  .js [data-fade]:not(.is-visible) { opacity: 0; transform: translate3d(var(--fade-x, 0px), var(--fade-y, 30px), 0); }
  /* Stacked chapters never use fade, regardless of .is-visible. */
  .js #story.is-stacked [data-chapter][data-fade] { opacity: 1; transition: none; }
}

/* ---------- Hero ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js [data-hero-line] { transition: transform 700ms cubic-bezier(.2, .8, .2, 1) var(--line-delay, 0ms); }
  .js:not(.hero-ready) [data-hero-line] { transform: translate3d(0, 100%, 0); }

  .js .hero-rule { transform-origin: left center; transition: transform 400ms cubic-bezier(.2, .8, .2, 1) 780ms; }
  .js:not(.hero-ready) .hero-rule { transform: scaleX(0); }

  .js [data-hero-fade] {
    transition: opacity 600ms cubic-bezier(.25, .1, .25, 1) var(--hero-delay, 0ms),
                transform 600ms cubic-bezier(.25, .1, .25, 1) var(--hero-delay, 0ms);
  }
  .js:not(.hero-ready) [data-hero-fade] { opacity: 0; transform: translate3d(0, 30px, 0); }

  /* One-time draw. Main sets --path-length per path. */
  .js .draw-path { stroke-dasharray: var(--path-length); stroke-dashoffset: var(--path-length); }
  .js.hero-ready .draw-path { stroke-dashoffset: 0; transition: stroke-dashoffset 1800ms cubic-bezier(.4, 0, .2, 1) 200ms; }
}

/* ---------- Spotlight ---------- */
.spotlight { display: none; }
@media (min-width: 1024px) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .js .spotlight { display: block; }
}
.spotlight {
  position: absolute; top: 0; left: 0; width: 520px; height: 520px; z-index: 1; pointer-events: none; overflow: hidden;
  opacity: 0; transition: opacity 300ms ease; will-change: transform, opacity;
  -webkit-mask-image: radial-gradient(circle closest-side, #000 40%, transparent 100%);
  mask-image: radial-gradient(circle closest-side, #000 40%, transparent 100%);
}
.spotlight.is-active { opacity: 1; }
.spotlight-inner { position: absolute; top: 0; left: 0; will-change: transform; }

/* ---------- Number roll ---------- */
.number-reel { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .js [data-roll-number].is-rolling .number-real,
  .js [data-roll-number].is-rolled .number-real {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .js [data-roll-number].is-rolling .number-reel,
  .js [data-roll-number].is-rolled .number-reel { display: inline-flex; align-items: flex-start; line-height: 1em; }
}
.digit-window { display: inline-block; overflow: hidden; height: 1em; line-height: 1em; }
.digit-strip { display: flex; flex-direction: column; line-height: 1em; will-change: transform;
  transition: transform var(--digit-dur, 1100ms) cubic-bezier(.2, .8, .2, 1) var(--digit-delay, 0ms); }
.digit-strip > span { display: block; height: 1em; line-height: 1em; }
.digit-static { display: inline-block; line-height: 1em; }

/* ---------- Marquee (main sets translateX from scroll) ---------- */
.marquee-track { will-change: transform; }

/* ---------- Copy label swap ---------- */
.copy-label { display: inline-block; transition: opacity 150ms ease, transform 150ms ease; }
.copy-label.is-swapping { opacity: 0; transform: translate3d(0, -6px, 0); }

/* ---------- Story fallback progress ---------- */
.story-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 55; background: var(--signal);
  transform: scaleX(0); transform-origin: left center; opacity: 0; transition: opacity 200ms ease; pointer-events: none;
}
.story-progress.is-active { opacity: 1; }
#story.is-stacked .story-progress { display: none; }
.rail { display: none; }
#story.is-stacked .chapter-nav { position: relative; padding-left: 16px; }
#story.is-stacked .rail { display: block; position: absolute; left: 0; top: 0; bottom: 0; width: 1px; background: var(--hair); }
#story.is-stacked .rail-fill { display: block; width: 2px; height: 100%; background: var(--signal); transform: scaleY(0); transform-origin: top; }
#story.is-stacked .chapter-index li { border-bottom: 1px solid var(--hair); width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .marquee-track { transform: none !important; }
  .copy-label { transition: none; }
}
