/* Scroll-reveal + hero entrance. Added to every page by build/build.py.
   Everything here is gated on html.motion, which the inline head script only sets
   when the browser supports IntersectionObserver and the visitor hasn't asked for
   reduced motion, so content is never hidden without the script to reveal it. */

/* Replaces the canvas's own section-level .reveal (Chromium-only scroll timeline). */
.reveal { animation: none !important; }

@keyframes cxRise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

/* Hero: staggered entrance on load (CSS only, so nothing flashes before JS runs). */
html.motion .hero > .container > *,
html.motion .hero > div[style*="position:relative"] > * { animation: cxRise 0.9s cubic-bezier(.2,.7,.2,1) both; }
html.motion .hero > * > :nth-child(1) { animation-delay: 0.05s; }
html.motion .hero > * > :nth-child(2) { animation-delay: 0.18s; }
html.motion .hero > * > :nth-child(3) { animation-delay: 0.28s; }
html.motion .hero > * > :nth-child(4) { animation-delay: 0.38s; }
html.motion .hero > * > :nth-child(n+5) { animation-delay: 0.48s; }

/* Scroll reveal: site.js tags elements with [data-reveal] and adds .is-in on entry. */
html.motion [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.8s cubic-bezier(.2,.7,.2,1), transform 0.8s cubic-bezier(.2,.7,.2,1);
  transition-delay: var(--reveal-delay, 0s);
}
html.motion [data-reveal="fade"] { transform: none; }
html.motion [data-reveal].is-in { opacity: 1; transform: none; }

@media (max-width: 640px) {
  html.motion [data-reveal] { transform: translateY(18px); transition-duration: 0.6s; }
}
