/* Motion: cross-page view transitions, entrance + scroll-driven reveals, keyframes.
   Rules: transform/opacity only, and everything collapses under prefers-reduced-motion. */

/* ---------- Cross-document view transitions (MPA page morphs) ---------- */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: 420ms; animation-timing-function: var(--ease-out); }
::view-transition-old(root) { animation-name: page-out; }
::view-transition-new(root) { animation-name: page-in; }

::view-transition-group(nav-pill),
::view-transition-group(page-title),
::view-transition-group(portrait) { animation-duration: 520ms; animation-timing-function: var(--ease-out); }
::view-transition-group(*) { animation-timing-function: var(--ease-out); }

/* Theme switch: JS sets this class during a same-document transition and animates a circular clip. */
:root.theme-anim::view-transition-old(root),
:root.theme-anim::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* Depth-of-field: the outgoing page drifts back out of focus, the new one racks into focus. */
@keyframes page-out { to { opacity: 0; scale: 0.985; filter: blur(8px); } }
@keyframes page-in { from { opacity: 0; scale: 1.015; filter: blur(8px); } }

/* ---------- Entrance (page load) ---------- */
.rise {
  animation: rise var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--d, 0) * var(--beat) + var(--beat));
}
.hero-name .char {
  animation: char-in 900ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--beat) / 2 + var(--beat));
}

@keyframes rise { from { opacity: 0; translate: 0 24px; } }
@keyframes char-in {
  from { opacity: 0; translate: 0 0.45em; rotate: 6deg; filter: blur(8px); }
}

/* ---------- Scroll-driven reveals ----------
   Native where supported (no JS); JS adds .reveal-io + IntersectionObserver elsewhere. */
@supports (animation-timeline: view()) {
  .reveal {
    animation: reveal linear both;
    animation-timeline: view();
    animation-range: entry 5% entry 85%; /* fully revealed before it's fully on screen, even at page bottom */
  }
  .reveal-stagger > * {
    animation: reveal linear both;
    animation-timeline: view();
    animation-range: entry calc(5% + var(--i, 0) * 4%) entry calc(75% + var(--i, 0) * 4%);
  }
  .parallax {
    animation: parallax linear both;
    animation-timeline: view();
  }
  .hero-content {
    animation: hero-away linear both;
    animation-timeline: scroll(root);
    animation-range: 0 90vh;
  }
  .scroll-progress {
    position: fixed;
    inset: 0 0 auto;
    z-index: 60;
    height: 2px;
    background: var(--accent);
    transform-origin: 0 50%;
    animation: progress linear both;
    animation-timeline: scroll(root);
  }
}
@keyframes reveal { from { opacity: 0; translate: 0 40px; scale: 0.98; } }
@keyframes parallax { from { translate: 0 6%; } to { translate: 0 -6%; } }
@keyframes hero-away { to { opacity: 0.15; translate: 0 -8vh; scale: 0.97; } }
@keyframes progress { from { scale: 0 1; } to { scale: 1 1; } }

/* IntersectionObserver fallback (browsers without scroll timelines). */
.reveal-io { opacity: 0; translate: 0 40px; transition: opacity 800ms var(--ease-out), translate 800ms var(--ease-out); transition-delay: calc(var(--i, 0) * var(--beat)); }
.reveal-io.is-in { opacity: 1; translate: 0 0; }

/* ---------- Ambient keyframes ---------- */
@keyframes drift {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-8%, 6%) scale(1.1); }
  100% { transform: translate(6%, -4%) scale(0.95); }
}
@keyframes ping { 75%, 100% { transform: scale(2.6); opacity: 0; } }
@keyframes cue { 0% { translate: 0 -100%; } 60%, 100% { translate: 0 100%; } }
@keyframes marquee { to { transform: translateX(calc(-50% - 1.5rem)); } }
@keyframes spin { to { rotate: 1turn; } }

/* ---------- Reduced motion: keep feedback, drop movement ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .reveal-stagger > *, .parallax, .hero-content, .reveal-io { animation: none !important; opacity: 1 !important; translate: none !important; }
  .marquee-track { animation: none !important; }
  .card { transform: none !important; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
