/* ============================================================================
   Dark Neon — animations.css
   CSS-only motion. ALL motion is gated by:
     - @media (prefers-reduced-motion: no-preference)  (OS / user preference)
     - html[data-motion="auto"]                        (site setting; reduced/off opt out)
   Without JS, .reveal stays fully visible (progressive enhancement). Only
   transform/opacity/box-shadow are animated (GPU). No flashing > 3/s (WCAG 2.3.1).
   ============================================================================ */

/* ── Keyframes (definitions are harmless when unused) ── */
@keyframes gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@keyframes neon-pulse { 0%, 100% { box-shadow: 0 0 10px color-mix(in srgb, var(--color-primary) 40%, transparent); } 50% { box-shadow: var(--neon-glow); } }
@keyframes shimmer { 0% { background-position: -150% 0; } 100% { background-position: 250% 0; } }
@keyframes ball-pop { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes confetti-fall { 0% { transform: translateY(-10%) rotate(0deg); opacity: 1; } 100% { transform: translateY(420px) rotate(540deg); opacity: 0; } }
@keyframes float-soft { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

/* ── Skeleton shimmer (always usable; only the sweep animates under motion) ── */
.shimmer {
  background: linear-gradient(100deg, var(--color-surface) 30%, color-mix(in srgb, var(--color-primary) 18%, var(--color-surface)) 50%, var(--color-surface) 70%);
  background-size: 200% 100%;
}

/* Confetti pieces are created by motion.js; base style here. */
.confetti__piece { position: absolute; top: 0; width: 8px; height: 12px; border-radius: 2px; opacity: 0; will-change: transform, opacity; }

/* ── Motion-enabled block ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {

  /* Scroll reveal: hidden initial state ONLY when JS is available, so no-JS shows content. */
  @media (scripting: enabled) {
    html[data-motion="auto"] .reveal {
      opacity: 0;
      transform: translateY(26px);
      transition: opacity var(--motion-slow) var(--easing), transform var(--motion-slow) var(--easing);
      transition-delay: calc(var(--i, 0) * 70ms);
      will-change: opacity, transform;
    }
    html[data-motion="auto"] .reveal.is-visible { opacity: 1; transform: none; }
  }

  /* Animated brand gradient (hero background, etc.) */
  html[data-motion="auto"] .gradient-shift {
    background-size: 200% 200%;
    animation: gradient-shift 14s ease-in-out infinite;
  }

  /* Gentle neon pulse utility (used sparingly) */
  html[data-motion="auto"] .neon-pulse { animation: neon-pulse 3.5s ease-in-out infinite; }

  /* Skeleton sweep */
  html[data-motion="auto"] .shimmer { animation: shimmer 1.6s linear infinite; }

  /* Number / symbol reveal with stagger (visualises already-computed result) */
  html[data-motion="auto"] [data-reveal-balls] .ball,
  html[data-motion="auto"] [data-reveal-balls] .instant-cell {
    animation: ball-pop var(--motion-base) var(--easing) both;
    animation-delay: calc(var(--d, 0) * 110ms);
  }

  /* Hover lift is defined with transitions in style.css (GPU transform + shadow). */
}

/* ── Reduced / off: make sure nothing moves ─────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* When the manager forces reduced/off via settings.motion, JS also sets data-motion;
   ensure reveals are visible and decorative loops are stopped. */
html[data-motion="reduced"] .gradient-shift,
html[data-motion="off"] .gradient-shift,
html[data-motion="reduced"] .neon-pulse,
html[data-motion="off"] .neon-pulse,
html[data-motion="reduced"] .shimmer,
html[data-motion="off"] .shimmer { animation: none !important; }
html[data-motion="reduced"] .reveal,
html[data-motion="off"] .reveal { opacity: 1 !important; transform: none !important; }
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation: none !important;
}
