/* =========================================================
   Motion system — transform/opacity only, GPU-friendly
   ========================================================= */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes slow-spin { to { transform: rotate(360deg); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-up { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes pop-in { from { opacity: 0; transform: scale(.86); } to { opacity: 1; transform: none; } }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes shimmer { to { transform: translateX(100%); } }
@keyframes text-shimmer { to { background-position: -200% 0; } }
@keyframes ripple { to { transform: scale(1); opacity: 0; } }
@keyframes progress-crawl { 0% { transform: scaleX(0); } 30% { transform: scaleX(.45); } 100% { transform: scaleX(.9); } }
@keyframes heart-pop { 0% { transform: scale(1); } 30% { transform: scale(1.38); } 55% { transform: scale(.9); } 100% { transform: scale(1); } }
@keyframes bookmark-drop { 0% { transform: translateY(0); } 35% { transform: translateY(-4px) scale(1.1); } 70% { transform: translateY(1px) scale(.96); } 100% { transform: none; } }
@keyframes count-bump { 0% { transform: translateY(0); opacity: 1; } 40% { transform: translateY(-6px); opacity: 0; } 41% { transform: translateY(6px); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes burst { 0% { transform: rotate(var(--a)) translateY(0) scale(1); opacity: 1; } 100% { transform: rotate(var(--a)) translateY(-22px) scale(.2); opacity: 0; } }
@keyframes toast-in { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateX(24px) scale(.98); } }
@keyframes toast-progress { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes typing { 0%, 60%, 100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-4px); opacity: 1; } }
@keyframes orb { 0%, 100% { transform: scale(1) rotate(0); filter: hue-rotate(0); } 50% { transform: scale(1.08) rotate(180deg); filter: hue-rotate(-12deg); } }
@keyframes ember { from { transform: translate(0, 0) scale(1); } to { transform: translate(-40px, 30px) scale(1.15); } }
@keyframes ai-reveal { from { opacity: 0; transform: translateY(14px); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
@keyframes grow-x { from { transform: scaleX(0); } }
@keyframes bar-rise { from { transform: scaleY(0); } }
@keyframes ring-draw { from { stroke-dashoffset: var(--circ); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes word-in { from { opacity: 0; filter: blur(3px); } to { opacity: 1; filter: none; } }

/* Page entrance */
.page { animation: page-in 380ms var(--ease-out) both; }
body.is-leaving .page { opacity: 0; transform: translateY(4px); transition: opacity 140ms var(--ease-in-out), transform 140ms var(--ease-in-out); }

/* Scroll reveal (IntersectionObserver adds .is-visible) */
.js .reveal { opacity: 0; transform: translateY(14px) scale(.985); transition: opacity 560ms var(--ease-out), transform 640ms var(--ease-out); transition-delay: var(--reveal-delay, 0ms); }
.js .reveal.is-visible { opacity: 1; transform: none; }

/* Streaming-like word reveal for AI text */
.stream-word { animation: word-in 320ms var(--ease-out) both; }

/* Accessibility: honour reduced motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal { opacity: 1; transform: none; }
}
