/* ==========================================================================
   ANIMATIONS — keyframes and CSS-driven motion
   All motion here is calm: long durations, soft easing, no bounce.
   ========================================================================== */

@keyframes rippleOut {
  to { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}
@keyframes cueDrop {
  0%   { transform: translateY(-100%); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: translateY(240%); opacity: 0; }
}
@keyframes eq {
  from { height: 3px; } to { height: 12px; }
}
@keyframes flicker {
  0%, 100% { transform: scale(1) translateY(0); opacity: 1; }
  38%      { transform: scale(1.06, .96) translateY(-.5px); opacity: .92; }
  62%      { transform: scale(.97, 1.05) translateY(.5px); opacity: 1; }
}
@keyframes float-slow {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-14px); }
}
@keyframes drift {
  0%   { transform: translate(0, 0); opacity: 0; }
  15%  { opacity: .85; }
  100% { transform: translate(var(--dx, 20px), -110px); opacity: 0; }
}
@keyframes spinSlow { to { transform: rotate(360deg); } }
@keyframes shimmer  { to { background-position: 200% 0; } }

/* Reusable classes */
.anim-flicker  { animation: flicker 3.4s ease-in-out infinite; transform-origin: 50% 100%; }
.anim-float    { animation: float-slow 7s ease-in-out infinite; }
.anim-spin     { animation: spinSlow 90s linear infinite; }
.anim-shimmer  { background-size: 200% 100%; animation: shimmer 4.5s linear infinite; }

/* Hero particle drift (CSS fallback; GSAP takes over when available) */
.hero__particles i { animation: drift var(--dur, 14s) linear infinite; animation-delay: var(--delay, 0s); }

/* Image mask reveal — used by ScrollTrigger, safe as a pure-CSS fallback */
.mask-reveal { clip-path: inset(0 0 100% 0); }
.mask-reveal.is-in { clip-path: inset(0 0 0 0); transition: clip-path 1.25s var(--e-arch); }

/* Skeleton shimmer for lazily-loaded imagery */
.img-load { background: linear-gradient(100deg, #EFEAE0 30%, #F8F5EF 50%, #EFEAE0 70%); background-size: 200% 100%; animation: shimmer 1.6s linear infinite; }
img.is-loaded { animation: none; background: none; }

/* Reduced motion — everything settles instantly, nothing is lost */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .mask-reveal { clip-path: none; }
  .hero__particles, .intro__particles { display: none; }
}
