/* ==========================================================================
   FaasTrader — animations.css
   Keyframes + the visual states GSAP/ScrollTrigger (js/animations.js) tweens
   between. If JS never runs, .reveal-ready elements still fade in via the
   plain CSS fallback below, so the page never looks broken without JS.
   ========================================================================== */

@keyframes bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-10px); } }

@keyframes btn-ripple{ to{ transform:scale(3); opacity:0; } }

@keyframes spin-slow{ to{ transform:rotate(360deg); } }

@keyframes pulse-glow{
  0%,100%{ box-shadow:0 0 0 0 rgba(22,163,74,.35); }
  50%{ box-shadow:0 0 0 10px rgba(22,163,74,0); }
}

/* Reveal primitives — GSAP sets these via inline transform/opacity when present;
   this class-based version is the no-JS / JS-not-yet-loaded fallback. */
.reveal{ opacity:0; transform:translateY(24px); transition:opacity .7s var(--ease-out), transform .7s var(--ease-out); }
.reveal.in{ opacity:1; transform:translateY(0); }

.reveal-stagger > *{ opacity:0; transform:translateY(18px); transition:opacity .6s var(--ease-out), transform .6s var(--ease-out); }
.reveal-stagger.in > *{ opacity:1; transform:translateY(0); }
.reveal-stagger.in > *:nth-child(n){ transition-delay: calc((var(--i, 0)) * 60ms); }

/* Hero word-by-word reveal target */
.word{ display:inline-block; }

.to-top, #progress{ transition: all var(--dur-base) var(--ease-out); }

@media (prefers-reduced-motion: reduce){
  .reveal, .reveal-stagger > *{ opacity:1 !important; transform:none !important; transition:none !important; }
  .float-card{ animation:none !important; }
  html{ scroll-behavior:auto; }
  *{ scroll-behavior:auto !important; animation-duration:.001ms !important; }
}
