/* ============================================================
   ALGO — ANIMATION STYLESHEET
   Vanilla-JS-driven, class-toggled keyframe animations
   ============================================================ */

/* ---------- Scroll reveal base states (toggled by animation.js) ---------- */
[data-reveal] {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  will-change: opacity, transform;
}
[data-reveal="fade-up"] { transform: translateY(28px); }
[data-reveal="fade-in"] { transform: none; }
[data-reveal="slide-left"] { transform: translateX(40px); }
[data-reveal="slide-right"] { transform: translateX(-40px); }
[data-reveal="zoom-in"] { transform: scale(0.92); }

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* Stagger children of a reveal group */
[data-reveal-group] > * { transition-delay: calc(var(--stagger-index, 0) * 90ms); }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ---------- Fade ---------- */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.anim-fade { animation: fadeIn var(--dur-slow) var(--ease-out) both; }

/* ---------- Loading spinner / page loader ---------- */
.page-loader {
  position: fixed; inset: 0; z-index: 999;
  background: var(--c-bg);
  display: flex; align-items: center; justify-content: center;
  transition: opacity var(--dur-slow) var(--ease-out), visibility var(--dur-slow);
}
.page-loader.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
.loader-ring {
  width: 46px; height: 46px;
  border: 3px solid var(--c-surface-2);
  border-top-color: var(--c-accent-2);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}

/* ---------- Typing effect caret ---------- */
.typing-caret::after {
  content: '|';
  margin-left: 2px;
  color: var(--c-accent-2);
  animation: blink 1s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* ---------- Counter number pulse on completion ---------- */
@keyframes countPop { 0% { transform: scale(1); } 50% { transform: scale(1.08); } 100% { transform: scale(1); } }
.stat .value.is-done { animation: countPop 2s var(--ease-out); }

/* ---------- Hover micro-interactions ---------- */
.hover-lift { transition: transform var(--dur-fast) var(--ease-out); }
.hover-lift:hover { transform: translateY(-4px); }

/* ---------- Parallax layer (transform driven by animation.js scroll listener) ---------- */
[data-parallax] { will-change: transform; }

/* ---------- Page transition overlay ---------- */
.page-transition {
  position: fixed; inset: 0; z-index: 998;
  background: var(--c-accent);
  transform: translateY(-100%);
  pointer-events: none;
}
.page-transition.is-active { animation: pageSweep var(--dur-slow) var(--ease-out) forwards; }
@keyframes pageSweep {
  0% { transform: translateY(-100%); }
  50% { transform: translateY(0); }
  100% { transform: translateY(100%); }
}

/* ---------- Ambient gradient drift on hero background ---------- */
@keyframes drift {
  0%, 100% { background-position: 0% 0%, 100% 0%; }
  50% { background-position: 8% 6%, 92% -4%; }
}
.hero-grid-bg { animation: drift 14s ease-in-out infinite; }
