/* ==========================================================================
   VENUS — MOTION FOUNDATION
   Global, reusable motion primitives. Animate transform/opacity only.
   PROGRESSIVE ENHANCEMENT: initial-hidden states are gated on the `.js` class
   (added synchronously in <head>). Without JS, nothing is hidden — content is
   always visible. Reduced-motion collapses everything to the final state.
   Spec: 05_MOTION_INTERACTION_SYSTEM, 08_ACCESSIBILITY_PERFORMANCE.
   Mechanism: reveal.js adds .is-visible to [data-reveal] elements in view
   (immediately for above-the-fold, on scroll via IntersectionObserver below).
   ========================================================================== */

/* Page-load fade (M1) — pure CSS, no JS dependency (never stuck hidden). */
.js body { animation: pageIn var(--dur-standard) var(--ease-out) both; }
@keyframes pageIn { from { opacity: 0; } to { opacity: 1; } }

/* Reveal base state — only when JS is present. */
.js [data-reveal] {
  opacity: 0;
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
  will-change: opacity, transform;
}
.js [data-reveal="slide-up"] { transform: translateY(var(--reveal-shift)); }
.js [data-reveal="image"]    { transform: scale(1.02); clip-path: inset(0 0 8% 0); }
/* Horizontal entrances only at >=lg, where columns are half-width and have room.
   Below lg (stacked, full-width columns) a translateX would push past the
   viewport edge, so those widths get a pure opacity fade instead — no overflow. */
@media (min-width: 992px) {
  .js [data-reveal="slide-left"]  { transform: translateX(calc(var(--reveal-shift) * 1.5)); }   /* enters from the right */
  .js [data-reveal="slide-right"] { transform: translateX(calc(var(--reveal-shift) * -1.5)); }  /* enters from the left */
}

/* Revealed state (JS-applied) */
[data-reveal].is-visible {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

/* Stagger: children reveal in sequence. reveal.js sets --stagger-index. */
.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition: opacity var(--dur-reveal) var(--ease-out),
              transform var(--dur-reveal) var(--ease-out);
  transition-delay: calc(var(--stagger-index, 0) * 70ms);
}
[data-stagger].is-visible > * { opacity: 1; transform: none; }

/* Hover transitions live on components (buttons, cards, nav) via tokens;
   this file owns only the scroll/entrance primitives. */

/* --------------------------------------------------- Reduced-motion fallback
   Collapse every entrance/auto motion to its final state. Single global guard;
   reveal.js also short-circuits when the media query matches. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js body { animation: none; }
  .js [data-reveal],
  .js [data-stagger] > * { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}
