/* =========================================
   ANIMATIONS.CSS
   Centralised animation primitives.
   JS adds .is-visible / .is-active to
   trigger transitions defined here.
   ========================================= */

/* =========================================
   REDUCED MOTION
========================================= */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration:   0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration:  0.01ms !important;
    scroll-behavior:      auto !important;
  }
}

/* =========================================
   FADE-IN BASE
   Shared by all scroll-reveal elements.
   .is-visible added by animations.js
========================================= */

.fade-in {
  opacity:   0;
  transform: translateY(22px);
  transition:
    opacity   0.65s var(--ease-out),
    transform 0.65s var(--ease-out);
}

.fade-in.is-visible {
  opacity:   1;
  transform: translateY(0);
}

/* ── STAGGER DELAYS ──────────────────────── */

.fade-in:nth-child(1) { transition-delay: 0ms;   }
.fade-in:nth-child(2) { transition-delay: 80ms;  }
.fade-in:nth-child(3) { transition-delay: 160ms; }
.fade-in:nth-child(4) { transition-delay: 240ms; }
.fade-in:nth-child(5) { transition-delay: 320ms; }
.fade-in:nth-child(6) { transition-delay: 400ms; }

/* =========================================
   SLIDE-IN LEFT / RIGHT
   Used by timeline entries (.tl-reveal)
   CSS overrides set direction per element
========================================= */

.tl-reveal {
  opacity:    0;
  transition:
    opacity   0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
}

.tl-reveal.is-visible {
  opacity:   1;
  transform: translateX(0) !important;
}

/* =========================================
   SECTION FADE-UP
   Generic section-level entrance
========================================= */

.section-reveal {
  opacity:   0;
  transform: translateY(32px);
  transition:
    opacity   0.8s var(--ease-out),
    transform 0.8s var(--ease-out);
}

.section-reveal.is-visible {
  opacity:   1;
  transform: translateY(0);
}

/* =========================================
   SCALE-IN
   For cards, metric tiles, thumbnails
========================================= */

.scale-in {
  opacity:   0;
  transform: scale(0.96) translateY(16px);
  transition:
    opacity   0.6s var(--ease-out),
    transform 0.6s var(--ease-out);
}

.scale-in.is-visible {
  opacity:   1;
  transform: scale(1) translateY(0);
}

/* =========================================
   CASE STUDY SECTIONS
   Gentle fade-up per section
========================================= */

.cs-section.fade-in {
  opacity:   0;
  transform: translateY(28px);
  transition:
    opacity   0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
  transition-delay: 0ms;   /* override nth-child stagger */
}

.cs-section.fade-in.is-visible {
  opacity:   1;
  transform: translateY(0);
}

/* =========================================
   METRIC CARDS
   Used inside .cs-metrics-row
========================================= */

.cs-metric-card.fade-in {
  opacity:   0;
  transform: translateY(20px);
  transition:
    opacity   0.55s var(--ease-out),
    transform 0.55s var(--ease-out);
  transition-delay: 0ms;   /* JS sets individual delays */
}

.cs-metric-card.fade-in.is-visible {
  opacity:   1;
  transform: translateY(0);
}

/* =========================================
   KEYFRAME ANIMATIONS
   Used directly in CSS where no JS trigger
   is needed (looping effects, decorative)
========================================= */

/* Pulsing dot (Available badge in contact) */
@keyframes pulse-dot {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%       { transform: scale(1.5); opacity: 0.6; }
}

/* Marquee scroll (testimonials strip) */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Blink (typewriter cursor) */
@keyframes blink {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Orb float (background) */
@keyframes orb-drift {
  0%   { transform: translate(0, 0)    scale(1.00); }
  33%  { transform: translate(40px, -30px) scale(1.04); }
  66%  { transform: translate(-20px, 20px) scale(0.97); }
  100% { transform: translate(0, 0)    scale(1.00); }
}

/* Subtle shimmer (bento cards hover) */
@keyframes shimmer {
  from { background-position: -200% center; }
  to   { background-position:  200% center; }
}

/* Spin (loading states) */
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* =========================================
   PAGE REVEAL
   .is-revealed added to .page-wrapper
   by preloader.js after load
========================================= */

.page-wrapper {
  opacity:    0;
  transition: opacity 0.4s ease;
}

.page-wrapper.is-revealed {
  opacity: 1;
}