@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
@keyframes sweep{0%{background-position:200% 0}100%{background-position:-200% 0}}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes rise{0%{transform:translateY(100vh) translateX(0);opacity:0}10%{opacity:.6}90%{opacity:.6}100%{transform:translateY(-10vh) translateX(40px);opacity:0}}
@keyframes pulse-glow{0%,100%{box-shadow:0 0 20px var(--blue-glow)}50%{box-shadow:0 0 40px var(--blue-glow),0 0 80px rgba(127,182,255,.3)}}

/* ===== Animation System =====
   Safe default: content IS visible (no class or .no-js).
   .js class added by animations.js AFTER IntersectionObserver is
   set up.  Hiding rules only apply once the reveal system is ready,
   so there is zero flash-of-hidden-content window. */

/* Transitions are always present */
.fade-up{transition:opacity .9s var(--ease),transform .9s var(--ease)}
.fade-in{transition:opacity 1.2s var(--ease)}
.scale-in{transition:opacity .8s var(--ease),transform .8s var(--ease)}
[data-stagger]>*{transition:opacity .8s var(--ease),transform .8s var(--ease)}

/* No-JS safety: forced visible */
.no-js .fade-up,
.no-js .fade-in,
.no-js .scale-in,
.no-js [data-stagger] > *{opacity:1;transform:none}

/* JS active: hidden initially, revealed by IntersectionObserver */
.js .fade-up{opacity:0;transform:translateY(30px)}
.js .fade-in{opacity:0}
.js .scale-in{opacity:0;transform:scale(.96)}
.js [data-stagger]>*{opacity:0;transform:translateY(20px)}

/* Revealed state */
.fade-up.in{opacity:1;transform:none}
.fade-in.in{opacity:1}
.scale-in.in{opacity:1;transform:none}
[data-stagger].in>*{opacity:1;transform:none}
[data-stagger].in>*:nth-child(1){transition-delay:.05s}
[data-stagger].in>*:nth-child(2){transition-delay:.15s}
[data-stagger].in>*:nth-child(3){transition-delay:.25s}
[data-stagger].in>*:nth-child(4){transition-delay:.35s}
[data-stagger].in>*:nth-child(5){transition-delay:.45s}
[data-stagger].in>*:nth-child(6){transition-delay:.55s}

.pulse{animation:pulse-glow 3.5s ease-in-out infinite}
