/* ==========================================================================
   Motion — subtle, fast, and fully disabled for reduced-motion users.
   Reveal classes only hide content once JS has confirmed it can reveal it
   (html.js-anim), so nothing is ever stuck invisible.
   ========================================================================== */

.js-anim [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--delay, 0s);
}
.js-anim [data-reveal="fade"] { transform: none; }
.js-anim [data-reveal="scale"] { transform: scale(0.97) translateY(12px); }
.js-anim [data-reveal].is-visible { opacity: 1; transform: none; }

@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
.float-anim { animation: floatY 6s ease-in-out infinite; }
.float-anim--slow { animation-duration: 8s; animation-delay: -2s; }

@keyframes panelIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

@keyframes pulseDot {
  0% { box-shadow: 0 0 0 0 rgba(18, 184, 134, 0.5); }
  70% { box-shadow: 0 0 0 8px rgba(18, 184, 134, 0); }
  100% { box-shadow: 0 0 0 0 rgba(18, 184, 134, 0); }
}
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); animation: pulseDot 2s infinite; flex: none; }

@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;
  }
  html { scroll-behavior: auto; }
  .js-anim [data-reveal] { opacity: 1; transform: none; }
}
