/* =========================================================
   Total Cleanz — Animations
   Keyframes + reveal-on-scroll utilities
   ========================================================= */

/* ---------- Keyframes ---------- */
@keyframes gradientShift {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

@keyframes orbFloat {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33%      { transform: translate(40px, -30px) scale(1.05); }
  66%      { transform: translate(-30px, 40px) scale(0.95); }
}

@keyframes bounceY {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(8px); }
}

@keyframes bubbleFloat {
  0%, 100% { transform: translate(-50%, -50%) translateY(0); }
  50%      { transform: translate(-50%, -50%) translateY(-12px); }
}

@keyframes slideInUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 6px rgba(74,59,143,0.18); }
  50%      { box-shadow: 0 0 0 10px rgba(74,59,143,0.08); }
}

@keyframes drawTitle {
  from { opacity: 0; transform: translateY(28px); letter-spacing: 0.05em; }
  to   { opacity: 1; transform: translateY(0); letter-spacing: -0.03em; }
}

/* Active nav dot pulse */
.nav-dot.active .dot { animation: pulseDot 2.4s ease-in-out infinite; }

/* Intro hero entrance — staggered */
.section-intro .intro-eyebrow {
  opacity: 0;
  animation: slideInUp 0.7s 0.2s var(--ease-out) forwards;
}
.section-intro .logo-wordmark {
  opacity: 0;
  animation: slideInUp 0.8s 0.45s var(--ease-out) forwards;
}
.section-intro .intro-title .line-1 {
  display: block;
  opacity: 0;
  animation: drawTitle 1s 0.7s var(--ease-out) forwards;
}
.section-intro .intro-title .line-2 {
  display: block;
  opacity: 0;
  animation: drawTitle 1s 0.95s var(--ease-out) forwards;
}
.section-intro .intro-sub {
  opacity: 0;
  animation: slideInUp 0.9s 1.2s var(--ease-out) forwards;
}
.section-intro .scroll-cue {
  opacity: 0;
  animation: fadeIn 0.8s 1.6s var(--ease-out) forwards;
}

/* =========================================================
   Reveal-on-scroll
   Items get .reveal in markup; JS adds .in-view when intersecting.
   ========================================================= */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity 0.85s var(--ease-out),
    transform 0.85s var(--ease-out);
  will-change: opacity, transform;
}
.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}

/* Slight horizontal variants for grid children — handled per-section */
.grid-2 > .reveal:nth-child(1) { transform: translateX(-30px) translateY(30px); }
.grid-2 > .reveal:nth-child(1).in-view { transform: translateX(0) translateY(0); }
.grid-2 > .reveal:nth-child(2) { transform: translateX(30px) translateY(30px); }
.grid-2 > .reveal:nth-child(2).in-view { transform: translateX(0) translateY(0); }

/* Ensure media (video frames, stat cards) scale-in subtly */
.video-frame.reveal {
  transform: scale(0.96) translateY(30px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out);
}
.video-frame.reveal.in-view { transform: scale(1) translateY(0); }

.stat-card.reveal {
  transform: scale(0.95) translateY(30px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out);
}
.stat-card.reveal.in-view { transform: scale(1) translateY(0); }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .section-intro * { animation: none !important; opacity: 1 !important; }
  .nav-dot.active .dot { animation: none !important; }
}
