/* ============================================================
 * motion.css — EIQ Prism motion language
 * ============================================================
 *
 * One rule: motion is dignified, not consumer-app twitchy. Reach
 * for opacity + small Y-axis slide; never bounce, never spring,
 * never scale-from-zero. The bar is editorial / Bloomberg / FT, not
 * Stripe-marketing.
 *
 * Application:
 *   <h2 class="reveal">Section title</h2>
 *   <div class="panel reveal" data-stagger="1">…</div>
 *   <div class="panel reveal" data-stagger="2">…</div>
 *
 * motion.js (IntersectionObserver) adds .is-visible once on first
 * intersect. The opacity + transform transition runs from there.
 * Already-visible elements at page load also receive .is-visible
 * after observer attaches, so above-the-fold content still reveals.
 *
 * Respects @media (prefers-reduced-motion: reduce) by collapsing
 * every effect to a no-op — content appears static, no transition.
 * ============================================================ */

.reveal {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Stagger: each higher data-stagger index delays by 60ms.
 * Up to 8 — beyond that the page feels lazy. If a list needs more
 * than 8 elements staggered, stop at 8 and let the rest snap in. */
.reveal[data-stagger="1"] { transition-delay:  60ms; }
.reveal[data-stagger="2"] { transition-delay: 120ms; }
.reveal[data-stagger="3"] { transition-delay: 180ms; }
.reveal[data-stagger="4"] { transition-delay: 240ms; }
.reveal[data-stagger="5"] { transition-delay: 300ms; }
.reveal[data-stagger="6"] { transition-delay: 360ms; }
.reveal[data-stagger="7"] { transition-delay: 420ms; }
.reveal[data-stagger="8"] { transition-delay: 480ms; }

/* Hover transitions — applied uniformly to interactive surfaces so
 * the entire site shares one easing curve. Buttons that override
 * background should still inherit this for color/border. */
a, .nav-link, button, .btn-primary, .btn-secondary, .btn-capsule, .btn-text {
  transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}

/* Honour the OS-level reduced-motion preference. The reveal is the
 * only motion we own; collapsing it here also disables Chart.js's
 * entry animation via motion.js. */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.is-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
