/* ===========================================================================
   MOTION SYSTEM — norml.studio
   ---------------------------------------------------------------------------
   Reusable reveal-on-scroll entrance for any element: add  data-reveal.
   Elements that start BELOW the fold fade + rise into place as they scroll
   into view. Content already in the first screen is left instant (animating a
   heading while its neighbours sit static reads as "weird", and fading in
   above-the-fold content hurts LCP). Driven by src/components/MotionReveal.tsx
   (one IntersectionObserver); the motion is the CSS below. Reduced-motion safe.
   Full guide: .claude/docs/06-motion.md

   Page-to-page motion = INSTANT client-side navigation (<Link>) + these scroll
   reveals on the new page — deliberately NOT a full-page crossfade. (The old
   cross-document View Transition waited on the network before animating, which
   felt laggy; see .claude/docs/06-motion.md.)

   Usage:
     <h2 data-reveal>…</h2>                  single element, fades + rises in
     <div data-reveal="stagger">…</div>      direct children, one after another
     <p data-reveal style="--reveal-delay:120ms">  hold before it starts

   Mechanics: MotionReveal adds  data-reveal-pending  (hidden) to off-screen
   elements after paint, then  data-revealed  when they enter view. Both attrs
   coexist while it animates — pending carries the transition, revealed the
   target. Don't nest a data-reveal inside a data-reveal="stagger".
   =========================================================================== */

/* PAGE ENTRANCE — the whole page content fades + rises in as ONE coherent unit
   on each load / client navigation (src/components/PageTransition.tsx). Keeps
   the first screen from having one element animate while its neighbours sit
   static. Header is outside the wrapper, so it stays put. No forwards-fill, so
   no transform lingers afterward (keeps sticky/position contexts clean). */
@media (prefers-reduced-motion: no-preference) {
  /* OUT: current content leaves fast, accelerating away + drifting up (ease-in). */
  .ns-page-exit {
    animation: ns-page-exit 170ms cubic-bezier(0.4, 0, 1, 1) forwards;
  }
  /* IN: new content arrives, decelerating + rising from just below (ease-out).
     The shared upward drift makes the out flow straight into the in. */
  .ns-page-enter {
    animation: ns-page-enter 0.4s cubic-bezier(0.2, 0, 0, 1) backwards;
  }
  @keyframes ns-page-exit {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(-6px); }
  }
  @keyframes ns-page-enter {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

@media (prefers-reduced-motion: no-preference) {

  /* Hidden / pre-reveal state — single elements, and stagger children. */
  [data-reveal-pending]:not([data-reveal="stagger"]),
  [data-reveal="stagger"][data-reveal-pending] > * {
    opacity: 0;
    transform: translateY(16px);
    transition:
      opacity 0.5s cubic-bezier(0.2, 0, 0, 1),
      transform 0.5s cubic-bezier(0.2, 0, 0, 1);
    transition-delay: var(--reveal-delay, 0ms);
  }

  /* Revealed state — settle to natural position (ease-out: a crisp arrival). */
  [data-revealed]:not([data-reveal="stagger"]),
  [data-reveal="stagger"][data-revealed] > * {
    opacity: 1;
    transform: translateY(0);
  }

  /* Stagger cadence — 70ms per child, on top of any --reveal-delay (12 steps). */
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(1)  { transition-delay: calc(var(--reveal-delay, 0ms) + 0ms);   }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(2)  { transition-delay: calc(var(--reveal-delay, 0ms) + 70ms);  }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(3)  { transition-delay: calc(var(--reveal-delay, 0ms) + 140ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(4)  { transition-delay: calc(var(--reveal-delay, 0ms) + 210ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(5)  { transition-delay: calc(var(--reveal-delay, 0ms) + 280ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(6)  { transition-delay: calc(var(--reveal-delay, 0ms) + 350ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(7)  { transition-delay: calc(var(--reveal-delay, 0ms) + 420ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(8)  { transition-delay: calc(var(--reveal-delay, 0ms) + 490ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(9)  { transition-delay: calc(var(--reveal-delay, 0ms) + 560ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(10) { transition-delay: calc(var(--reveal-delay, 0ms) + 630ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(11) { transition-delay: calc(var(--reveal-delay, 0ms) + 700ms); }
  [data-reveal="stagger"][data-reveal-pending] > *:nth-child(12) { transition-delay: calc(var(--reveal-delay, 0ms) + 770ms); }
}
