/* ============================================================
   THE STROOP STUDY — motion.css
   Restrained, print-minded motion. A one-time staggered load
   reveal and a couple of micro-interactions. CSS classes only;
   main.js toggles state classes, never inline styles.
   Every effect collapses under prefers-reduced-motion (token
   durations already fall to 0ms; this file also disables transforms).
   ============================================================ */

/* ── One-time load reveal ─────────────────────────────────────────
   Elements marked [data-reveal] start slightly low and clear.
   main.js adds .reveal-ready to <html> once (after first paint);
   an IntersectionObserver then adds .is-in per element, with a
   small stagger via --rev-i set in JS. No reveal = no JS = visible. */

:root {
  --rev-shift: 14px;
  --rev-dur: var(--dur-slow);
  --rev-step: 70ms;
}

/* Default (no JS, or reveal disabled): fully visible, no transform. */
[data-reveal] { opacity: 1; transform: none; }

/* Once JS confirms it can animate, arm the initial hidden state. */
html.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(var(--rev-shift));
  will-change: opacity, transform;
  transition:
    opacity var(--rev-dur) var(--ease),
    transform var(--rev-dur) var(--ease);
  transition-delay: calc(var(--rev-i, 0) * var(--rev-step));
}

html.reveal-ready [data-reveal].is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Children that should cascade within a revealed block. */
html.reveal-ready [data-reveal-group].is-in > * {
  animation: rev-rise var(--rev-dur) var(--ease) backwards;
}
html.reveal-ready [data-reveal-group].is-in > *:nth-child(1) { animation-delay: 40ms; }
html.reveal-ready [data-reveal-group].is-in > *:nth-child(2) { animation-delay: 110ms; }
html.reveal-ready [data-reveal-group].is-in > *:nth-child(3) { animation-delay: 180ms; }
html.reveal-ready [data-reveal-group].is-in > *:nth-child(4) { animation-delay: 250ms; }
html.reveal-ready [data-reveal-group].is-in > *:nth-child(5) { animation-delay: 320ms; }
html.reveal-ready [data-reveal-group].is-in > *:nth-child(n+6) { animation-delay: 380ms; }

@keyframes rev-rise {
  from { opacity: 0; transform: translateY(var(--rev-shift)); }
  to   { opacity: 1; transform: none; }
}

/* ── The hero motif settles in, letterpress-soft ─────────────────── */
html.reveal-ready .stroop-word {
  animation: stroop-set var(--dur-slow) var(--ease) backwards;
}
html.reveal-ready .stroop-word:nth-child(1) { animation-delay: 220ms; }
html.reveal-ready .stroop-word:nth-child(2) { animation-delay: 320ms; }
html.reveal-ready .stroop-word:nth-child(3) { animation-delay: 420ms; }
@keyframes stroop-set {
  from { opacity: 0; transform: translateY(0.12em) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

/* ── A figure fading in after D3 draws (D adds .fig-drawn) ────────── */
[data-fig].fig-drawn > svg { animation: fig-in var(--dur) var(--ease) backwards; }
@keyframes fig-in { from { opacity: 0; } to { opacity: 1; } }

/* ── Anchored-section focus flash for keyboard users ─────────────── */
:target { scroll-margin-top: 6rem; }
.section:target::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 2px var(--accent-weak);
  animation: tgt var(--dur-slow) var(--ease) forwards;
}
@keyframes tgt { from { opacity: 1; } to { opacity: 0; } }

/* ── Honor the user's reduced-motion preference, fully ───────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  html.reveal-ready [data-reveal],
  html.reveal-ready [data-reveal].is-in,
  html.reveal-ready [data-reveal-group].is-in > *,
  html.reveal-ready .stroop-word,
  [data-fig].fig-drawn > svg {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  .section:target::before { display: none; }
}
