/* ==========================================================================
   animations.css — Keyframes + scroll-reveal classes + route transitions
   ========================================================================== */

@keyframes floaty {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}
@keyframes ripple {
  0% { transform: scale(1); opacity: 0.7; }
  100% { transform: scale(1.8); opacity: 0; }
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(0.96); }
}
@keyframes indeterminate {
  0% { transform: translateX(-160%); }
  100% { transform: translateX(420%); }
}
@keyframes spinSlow {
  to { transform: rotate(360deg); }
}
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* ----------------------- Scroll reveal system --------------------------- */
/* Elements tagged [data-reveal] start hidden; .is-visible animates them in.
   When JS/Motion is unavailable, a no-JS fallback shows them (see bottom). */
[data-reveal] {
  opacity: 0;
  transform: translateY(34px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
  will-change: opacity, transform;
}
[data-reveal="left"] { transform: translateX(-40px); }
[data-reveal="right"] { transform: translateX(40px); }
[data-reveal="scale"] { transform: scale(0.92); }
[data-reveal="fade"] { transform: none; }

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

/* Stagger helper: set --i on children */
[data-stagger] > * {
  transition-delay: calc(var(--i, 0) * 90ms);
}

/* ------------------------- Route transitions ---------------------------- */
.app {
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.app.is-leaving {
  opacity: 0;
  transform: translateY(12px) scale(0.99);
}
.app.is-entering {
  opacity: 0;
  transform: translateY(-12px);
}

/* Hover lift utility */
.hover-lift {
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.hover-lift:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}

/* Floating decorative blobs */
.float-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
  animation: floaty 8s var(--ease-in-out) infinite;
}

/* Shimmer skeleton */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--surface-2) 25%,
    var(--stone) 37%,
    var(--surface-2) 63%
  );
  background-size: 200% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--radius);
}

/* No-JS / reduced-motion safety: always show revealed content */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}
.no-js [data-reveal] {
  opacity: 1;
  transform: none;
}
