/* ═══════════════════════════════════════════════════════════════
   D4D Site Platform — motion (reveal system CSS)
   Pairs with reveal.js. Requires tokens.css.

   THE DOUBLE GATE (R's pattern — the only fully safe one of the
   four reference implementations):
     Gate 1 — the hidden state (.is-prep) is applied by JS ONLY.
              Base CSS never hides content: no JS, no hiding, and
              the page reads exactly as authored ("readable before
              JS executes" is true by construction, not by promise).
     Gate 2 — every animation style lives inside
              @media (prefers-reduced-motion: no-preference).
              reveal.js additionally early-returns under reduced
              motion, so the classes are never even applied.

   Opt-in from components:
     class="reveal"                     one element
     class="reveal-group"               parent; reveal.js opts in each
                                        child and staggers them 0…N−1
     data-d="3"                         manual stagger index override

   Presentation is G's blur+stagger: 26px rise, 5px blur, 85ms per
   stagger step, house ease.

   QA kill switch: ?noanim=1 — reveal.js sets data-noanim on <html>
   and never arms; the rule at the bottom also freezes every other
   animation (marquee, orbs, sheen) for clean screenshots. */

@media (prefers-reduced-motion: no-preference) {
  .reveal.is-prep {
    opacity: 0;
    transform: translateY(26px);
    filter: blur(5px);
  }
  .reveal.is-in {
    opacity: 1;
    transform: none;
    filter: blur(0);
    transition:
      opacity .8s var(--ease),
      transform .9s var(--ease),
      filter .8s var(--ease);
    transition-delay: calc(var(--d, 0) * 85ms);
  }
}

/* ?noanim=1 — deterministic frames for QA and screenshot diffing */
:root[data-noanim] *,
:root[data-noanim] *::before,
:root[data-noanim] *::after {
  animation: none !important;
  transition: none !important;
}
