:root {
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Reveal helpers (IntersectionObserver adds .is-visible) */
[data-animate] {
  opacity: 0;
  transform: translateY(12px);
}
.is-visible[data-animate],
.is-visible [data-animate] {
  opacity: 1;
  transform: none;
}

/* Fade / slide */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes fadeInLeft {
  from {
    opacity: 0;
    transform: translateX(-18px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
@keyframes fadeInRight {
  from {
    opacity: 0;
    transform: translateX(18px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.is-visible[data-animate="fadeInUp"] {
  animation: fadeInUp 0.7s var(--ease-out) both;
}
.is-visible[data-animate="fadeInLeft"] {
  animation: fadeInLeft 0.7s var(--ease-out) both;
}
.is-visible[data-animate="fadeInRight"] {
  animation: fadeInRight 0.7s var(--ease-out) both;
}

/* Glitch (404) */
@keyframes glitch {
  0% {
    transform: translate(0);
    clip-path: inset(0 0 0 0);
  }
  10% {
    transform: translate(-2px, 1px);
    clip-path: inset(10% 0 70% 0);
  }
  20% {
    transform: translate(2px, -1px);
    clip-path: inset(60% 0 10% 0);
  }
  30% {
    transform: translate(-1px, -1px);
    clip-path: inset(25% 0 50% 0);
  }
  40% {
    transform: translate(1px, 2px);
    clip-path: inset(70% 0 10% 0);
  }
  50% {
    transform: translate(0);
    clip-path: inset(0 0 0 0);
  }
  100% {
    transform: translate(0);
    clip-path: inset(0 0 0 0);
  }
}
.glitch {
  position: relative;
  display: inline-block;
}
.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  opacity: 0.75;
  animation: glitch 1.2s infinite;
}
.glitch::before {
  transform: translate(2px, 0);
  color: var(--accent);
  mix-blend-mode: screen;
  animation-delay: 0.15s;
}
.glitch::after {
  transform: translate(-2px, 0);
  color: var(--primary);
  mix-blend-mode: screen;
  animation-delay: 0.25s;
}

/* Shimmer / skeleton loading */
@keyframes shimmer {
  0% {
    background-position: -400px 0;
  }
  100% {
    background-position: 400px 0;
  }
}
.shimmer {
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.05) 0%,
    rgba(255, 255, 255, 0.11) 45%,
    rgba(255, 255, 255, 0.05) 100%
  );
  background-size: 800px 100%;
  animation: shimmer 1.6s ease-in-out infinite;
}

/* Button pulse glow */
@keyframes pulseGlow {
  0% {
    box-shadow: 0 0 0 rgba(0, 212, 255, 0.0);
  }
  50% {
    box-shadow: 0 26px 80px rgba(0, 212, 255, 0.25), 0 26px 80px rgba(108, 99, 255, 0.20);
  }
  100% {
    box-shadow: 0 0 0 rgba(0, 212, 255, 0.0);
  }
}
.pulse-glow {
  animation: pulseGlow 2.4s ease-in-out infinite;
}

/* Floating particle-ish motion (CSS) */
@keyframes floatSlow {
  0% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(0, -10px, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

/* Counter helper (JS-driven, this is just a subtle emphasis) */
.stat-card.is-counting {
  box-shadow: 0 18px 60px rgba(108, 99, 255, 0.14);
}

/* Card hover glow handled in style.css via .hover-glow */

/* Misc */
@keyframes scrollDot {
  0% {
    opacity: 0;
    transform: translate(-50%, 0);
  }
  40% {
    opacity: 1;
  }
  80% {
    opacity: 0;
    transform: translate(-50%, 10px);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, 0);
  }
}
@keyframes scrollArrow {
  0%,
  100% {
    transform: rotate(45deg) translate(0, 0);
    opacity: 0.5;
  }
  50% {
    transform: rotate(45deg) translate(3px, 3px);
    opacity: 1;
  }
}
@keyframes checkPop {
  from {
    opacity: 0;
    transform: scale(0.8) rotate(-45deg);
  }
  to {
    opacity: 1;
    transform: scale(1) rotate(-45deg);
  }
}
@keyframes barPulse {
  0%,
  100% {
    filter: brightness(0.9);
  }
  50% {
    filter: brightness(1.15);
  }
}

