/* Motion: signaling only. Fast, subtle, purposeful. Decorative animation is dead. */

.hero-swap { animation: hero-swap var(--motion-fast) var(--ease-out); }
@keyframes hero-swap {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.sheet-enter { animation: sheet-up var(--motion-sheet-up) var(--ease-out); }
@keyframes sheet-up {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: translateY(0); }
}

.toast-enter { animation: toast-rise var(--motion-med) var(--ease-out); }
@keyframes toast-rise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.fade-enter { animation: fade-in var(--motion-fast) var(--ease-out); }
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.rescue-enter { animation: fade-in var(--motion-med) var(--ease-out); }

.row-expand { animation: row-in var(--motion-med) var(--ease-out); overflow: hidden; }
@keyframes row-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* New list insertions animate once. Re-renders never stagger. */
.insert-once { animation: fade-in var(--motion-med) var(--ease-out); }

/* Skeleton shimmer: communicates "loading", dies at the 600ms error handoff. */
.skel::after { animation: shimmer 1200ms linear infinite; }
@keyframes shimmer {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

/* Listening ring: this animation communicates state, so it ships. */
.mic-btn.listening::after { animation: listen-pulse 1200ms linear infinite; }
@keyframes listen-pulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 0.2; }
}

/* Reduced motion is the authority. One media query collapses everything to
   instant or crossfade. The listening ring becomes a static ring. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .mic-btn.listening::after { animation: none; opacity: 0.6; }
  .skel::after { animation: none; }
}
