/* ==========================================================================
   PINWHEEL — Animations (2026 redesign)
   Smooth scroll reveal + subtle hover. Nothing heavy, nothing constant.
   ========================================================================== */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

.hero-eyebrow, .hero h1, .hero .lede, .hero-ctas, .hero-figure {
  animation: rise-in 0.7s var(--ease) both;
}
.hero h1 { animation-delay: 0.08s; }
.hero .lede { animation-delay: 0.16s; }
.hero-ctas { animation-delay: 0.24s; }
.hero-figure { animation-delay: 0.1s; }

/* Generic scroll-triggered reveal, toggled by IntersectionObserver in JS.
   Content is visible by default (no-JS, slow script, crawler, screenshot
   tool). Only once the ".js" class (set synchronously in <head>) is present
   do we hide elements pending reveal — and animations.js carries its own
   timeout safety net so nothing can stay hidden if the observer never
   fires. See animations.js. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.js [data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .hero-eyebrow, .hero h1, .hero .lede, .hero-ctas, .hero-figure { animation: none; }
  [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* Accordion expand */
.faq-item[open] p { animation: rise-in 0.25s var(--ease) both; }

/* Mobile nav */
body.nav-open .nav-primary a {
  animation: rise-in 0.4s var(--ease) both;
}
