/* =============================================================================
   Motion: entrances, stagger, page transitions, scroll reveals, reduced motion
   ============================================================================= */

@layer motion {
  /* Every movement is multiplied by --m (1 = full motion, 0 = reduced: fades only). */
  @keyframes rise-in {
    from { opacity: 0; translate: 0 calc(18px * var(--m)); filter: blur(calc(6px * var(--m))); }
  }

  @keyframes fade-in {
    from { opacity: 0; }
  }

  /* Opacity only: a transform here would trap position:fixed overlays inside the page. */
  @keyframes page-enter {
    from { opacity: 0; }
  }

  /* Each route's wrapper is re-created on navigation, so this replays per page. */
  .page { animation: page-enter var(--dur-4) var(--ease-out) both; }

  .fade-in { animation: fade-in var(--dur-3) var(--ease-out) both; }

  /* ---- Stagger: children rise in one after another */
  .stagger > * {
    animation: rise-in var(--dur-4) var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * var(--stagger-step));
  }
  .stagger > :nth-child(1)  { --i: 1; }
  .stagger > :nth-child(2)  { --i: 2; }
  .stagger > :nth-child(3)  { --i: 3; }
  .stagger > :nth-child(4)  { --i: 4; }
  .stagger > :nth-child(5)  { --i: 5; }
  .stagger > :nth-child(6)  { --i: 6; }
  .stagger > :nth-child(7)  { --i: 7; }
  .stagger > :nth-child(8)  { --i: 8; }
  .stagger > :nth-child(9)  { --i: 9; }
  .stagger > :nth-child(10) { --i: 10; }
  .stagger > :nth-child(11) { --i: 11; }
  .stagger > :nth-child(n + 12) { --i: 12; }

  /* ---- Scroll-driven reveal where supported; otherwise content is simply visible */
  @supports (animation-timeline: view()) {
    .reveal {
      animation: rise-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
  }
}

/* ---- Motion preference -------------------------------------------------------
   Auto (default) follows the OS "reduce motion" setting; the in-app setting can force Full or Reduced.
   Reduced keeps fades and colour shifts but removes movement, drifting backgrounds and particles. */
:root, .app { --m: 1; }

@media (prefers-reduced-motion: reduce) {
  :root, .app:not([data-motion="full"]) { --m: 0; }
  .app:not([data-motion="full"]) .aurora__particles,
  .app:not([data-motion="full"]) .aurora__grain { display: none; }
  .app:not([data-motion="full"]) .aurora__mesh,
  .app:not([data-motion="full"]) .aurora__ribbon,
  .app:not([data-motion="full"]) .marquee__track,
  .app:not([data-motion="full"]) .np__art { animation-play-state: paused; }
  .app:not([data-motion="full"]) .glow-card { --tilt-max: 0deg; }
}

.app[data-motion="reduce"] { --m: 0; }
.app[data-motion="reduce"] .aurora__particles,
.app[data-motion="reduce"] .aurora__grain { display: none; }
.app[data-motion="reduce"] .aurora__mesh,
.app[data-motion="reduce"] .aurora__ribbon,
.app[data-motion="reduce"] .marquee__track,
.app[data-motion="reduce"] .np__art { animation-play-state: paused; }
.app[data-motion="reduce"] .glow-card { --tilt-max: 0deg; }
