/* ============================================================
   ANIMATIONS.CSS — keyframes + scroll-reveal states
   ============================================================ */

/* ---------- Keyframes ---------- */
@keyframes spin-pulse {
  0%, 100% { transform: rotate(0deg) scale(1); opacity: 1; }
  50% { transform: rotate(180deg) scale(1.15); opacity: .6; }
}

@keyframes scroll-dot {
  0% { top: 8px; opacity: 1; }
  70% { opacity: 1; }
  100% { top: 24px; opacity: 0; }
}

@keyframes ripple-anim {
  to { transform: scale(2.6); opacity: 0; }
}

@keyframes pulse-ring {
  0% { transform: scale(1); opacity: .7; }
  100% { transform: scale(1.35); opacity: 0; }
}

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

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

/* ---------- Scroll Reveal ---------- */
.reveal {
  opacity: 0;
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  will-change: transform, opacity;
}

.reveal[data-reveal="fade-up"] { transform: translateY(36px); }
.reveal[data-reveal="fade-right"] { transform: translateX(-40px); }
.reveal[data-reveal="fade-left"] { transform: translateX(40px); }
.reveal[data-reveal="zoom"] { transform: scale(.92); }
.reveal[data-reveal="fade"] { transform: none; }

.reveal.is-visible {
  opacity: 1;
  transform: translate(0, 0) scale(1);
}

/* Stagger children of grids automatically via inline transition-delay set by JS (scroll.js) */

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