/* ==========================================================
   animations.css — keyframes, hero intro, scroll reveals,
   reduced-motion fallbacks
   ========================================================== */

/* ---------- hero intro (runs once after data loads) ---------- */
.hero-title .line > span { transform: translateY(110%); }
.hero-kicker, .hero-lede, .hero-actions, .hero-stats { opacity: 0; transform: translateY(18px); }

.is-ready .hero-title .line > span { animation: riseIn 1s var(--ease) forwards; }
.is-ready .hero-title .line:nth-child(2) > span { animation-delay: .12s; }
.is-ready .hero-kicker { animation: fadeUp .8s var(--ease) .05s forwards; }
.is-ready .hero-lede   { animation: fadeUp .8s var(--ease) .35s forwards; }
.is-ready .hero-actions{ animation: fadeUp .8s var(--ease) .5s forwards; }
.is-ready .hero-stats  { animation: fadeUp .8s var(--ease) .65s forwards; }

/* ---------- scroll reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(40px) scale(.985);
  filter: blur(6px);
  transition: opacity .9s var(--ease), transform .9s var(--ease), filter .9s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; filter: none; }

.kpi {
  opacity: 0;
  transform: translateY(30px) rotateX(10deg);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.kpi.is-visible { opacity: 1; transform: none; }
.kpi.is-settled { transition: transform .25s ease-out; transition-delay: 0s; }

/* ---------- keyframes ---------- */
@keyframes riseIn   { to { transform: translateY(0); } }
@keyframes fadeUp   { to { opacity: 1; transform: none; } }
@keyframes chargeFill {
  to { background-size: 100% 100%; -webkit-text-stroke-color: transparent; }
}
@keyframes ping {
  0%   { box-shadow: 0 0 0 0 rgba(55, 226, 213, .7); }
  80%, 100% { box-shadow: 0 0 0 10px rgba(55, 226, 213, 0); }
}
@keyframes drift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(-6vmax, 8vmax) scale(1.15); }
}
@keyframes cablePulse {
  0%   { top: -16px; opacity: 0; }
  20%  { opacity: 1; }
  100% { top: 56px; opacity: 0; }
}
@keyframes plugBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}
@keyframes drawLine { to { stroke-dashoffset: 0; } }
@keyframes chartSwap {
  from { opacity: 0; transform: translateY(12px) scale(.98); filter: blur(4px); }
  to   { opacity: 1; transform: none; filter: none; }
}
@keyframes insightIn {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}
@keyframes orbPulse {
  0%, 100% { transform: scale(1); opacity: .8; }
  50%      { transform: scale(1.2); opacity: 1; }
}
@keyframes barSpark {
  0%   { left: -40px; }
  60%, 100% { left: 100%; }
}
@keyframes listIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes boltFlicker {
  0%, 100% { opacity: 1; }
  45% { opacity: .35; }
  50% { opacity: 1; }
  55% { opacity: .5; }
}

@keyframes modalIn {
  from { opacity: 0; transform: translate(var(--from-x, 0), var(--from-y, 0)) scale(.4); }
  to   { opacity: 1; transform: none; }
}
@keyframes modalOut { to { opacity: 0; transform: scale(.96); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  html { scroll-behavior: auto; }
  .reveal, .kpi { opacity: 1; transform: none; filter: none; }
  .hero-title .line > span, .hero-kicker, .hero-lede, .hero-actions, .hero-stats { opacity: 1; transform: none; }
  .stroke-text { background-size: 100% 100%; -webkit-text-stroke-color: transparent; }
  .cue-pulse { display: none; }
}
