/* Site-wide motion layer (pairs with js/motion.js).
   Everything that hides content is gated on html.mx-armed, which JS only adds
   when IntersectionObserver exists and reduced motion is off - so without JS,
   or with reduced motion, nothing here can leave content invisible.
   Only transform and opacity are animated. */

/* ---------- Scroll reveal ---------- */
.mx-armed .mx-reveal {
  transition:
    opacity 420ms cubic-bezier(0.23, 1, 0.32, 1),
    transform 420ms cubic-bezier(0.23, 1, 0.32, 1);
  transition-delay: var(--mx-delay, 0ms);
}
.mx-armed .mx-reveal:not(.mx-in) {
  opacity: 0;
  transform: translateY(12px);
}
/* Used when content is already above/inside the viewport after a restored
   scroll position: show it at once instead of fading in a visible element. */
.mx-armed .mx-reveal.mx-instant {
  transition: none;
}

/* ---------- Hero entrance on inner pages ---------- */
.mx-armed .mx-hero {
  animation: mx-hero-in 480ms cubic-bezier(0.23, 1, 0.32, 1) both;
  animation-delay: var(--mx-hero-delay, 0ms);
}
@keyframes mx-hero-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Cross-page transition (Chrome) ----------
   The header keeps its own snapshot so it stays put while the rest of the
   page crossfades. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
}

@media (prefers-reduced-motion: reduce) {
  .mx-armed .mx-reveal:not(.mx-in) { opacity: 1 !important; transform: none !important; }
  .mx-armed .mx-reveal,
  .mx-armed .mx-hero { transition: none !important; animation: none !important; }
}
