/*
  Lightweight CSS-only animation utilities for micro-interactions.
  Scroll-driven reveals (fade/parallax/stagger) are orchestrated by
  GSAP ScrollTrigger in js/scroll-reveal.js, which toggles the
  .is-visible class below — keeping the *what* (CSS) separate from
  the *when* (JS).
*/

[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}

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

[data-reveal='scale'] {
  transform: scale(0.92);
}

[data-reveal='scale'].is-visible {
  transform: scale(1);
}

[data-reveal='left'] {
  transform: translateX(-32px);
}

[data-reveal='left'].is-visible {
  transform: translateX(0);
}

[data-reveal='right'] {
  transform: translateX(32px);
}

[data-reveal='right'].is-visible {
  transform: translateX(0);
}

/* Below ~800px, --container-pad (the horizontal inset every
   [data-reveal='left'/'right'] element sits inside) shrinks to
   its 20px floor — less than this ±32px pre-reveal offset. So
   before an element scrolls into view and gains .is-visible,
   its own box is pushed past the viewport edge and the whole
   page gains a horizontal scrollbar. Capping the offset below
   the smallest container padding keeps the slide-in intact
   while it can never escape the viewport. Same specificity as
   the unconditional rules above and placed after them, so it
   wins for the pre-reveal state; .is-visible (higher
   specificity) still resets to translateX(0) untouched. */
@media (max-width: 820px) {
  [data-reveal='left'] {
    transform: translateX(-16px);
  }

  [data-reveal='right'] {
    transform: translateX(16px);
  }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-14px); }
}

.float {
  animation: float 5s var(--ease-in-out) infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.spin {
  animation: spin 0.8s linear infinite;
}

@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 rgba(211, 59, 44, 0.45); }
  100% { box-shadow: 0 0 0 16px rgba(211, 59, 44, 0); }
}

.pulse-ring {
  animation: pulse-ring 1.8s var(--ease-out) infinite;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in {
  animation: fade-in var(--duration-slow) var(--ease-out);
}

@keyframes checkmark-draw {
  to { stroke-dashoffset: 0; }
}

.checkmark-path {
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: checkmark-draw 0.5s var(--ease-out) 0.15s forwards;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .float,
  .pulse-ring {
    animation: none;
  }
}
