/* ============================
   Animation Keyframes
   ============================ */

/* === Fade Animations === */
@keyframes fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-12px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInScale {
  from {
    opacity: 0;
    transform: scale(0.97);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Stagger animation utility classes */
.stagger-container > * {
  opacity: 0;
  animation: fadeInUp 280ms cubic-bezier(0, 0, 0.2, 1) forwards;
}

.stagger-container > *:nth-child(1) {
  animation-delay: 30ms;
}

.stagger-container > *:nth-child(2) {
  animation-delay: 70ms;
}

.stagger-container > *:nth-child(3) {
  animation-delay: 110ms;
}

.stagger-container > *:nth-child(4) {
  animation-delay: 150ms;
}

.stagger-container > *:nth-child(5) {
  animation-delay: 185ms;
}

.stagger-container > *:nth-child(6) {
  animation-delay: 220ms;
}

.stagger-container > *:nth-child(7) {
  animation-delay: 250ms;
}

.stagger-container > *:nth-child(8) {
  animation-delay: 280ms;
}

@media (prefers-reduced-motion: reduce) {
  .stagger-container > * {
    animation: none;
    opacity: 1;
  }
}

/* === SPA View Transitions (content-only) === */

/* Outgoing page: quick, subtle fade + slight scale to create depth */
@keyframes spaExit {
  0% {
    opacity: 1;
    transform: scale(1) translateY(0);
    filter: blur(0);
  }

  40% {
    opacity: 0.6;
  }

  100% {
    opacity: 0;
    transform: scale(0.995) translateY(-4px);
    filter: blur(1px);
  }
}

/* Incoming page: crisp entrance with subtle upward settle */
@keyframes spaEnter {
  0% {
    opacity: 0;
    transform: translateY(6px);
  }

  60% {
    opacity: 1;
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Root transition: disable to prevent full-page flash */
html.swup-native::view-transition-old(root) {
  animation: none;
}

html.swup-native::view-transition-new(root) {
  animation: none;
}

/* Content container transitions */
html.swup-native::view-transition-old(route-content),
html.swup-native::view-transition-old(route-shell) {
  animation: spaExit 140ms cubic-bezier(0.4, 0, 1, 1) both;
}

html.swup-native::view-transition-new(route-content),
html.swup-native::view-transition-new(route-shell) {
  animation: spaEnter 220ms cubic-bezier(0, 0, 0.2, 1) 40ms both;
}

/* Stacking during transition — old page on top, fading out cleanly */
html.swup-native::view-transition-old(route-content) {
  z-index: 2;
}

html.swup-native::view-transition-new(route-content) {
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  html.swup-native::view-transition-old(route-content),
  html.swup-native::view-transition-old(route-shell),
  html.swup-native::view-transition-new(route-content),
  html.swup-native::view-transition-new(route-shell) {
    animation: none;
  }
}

/* === Slide Animations === */

/* slideUp and slideInUp are identical - use slideInUp */
@keyframes slideInUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* slideDown and slideInDown are identical - use slideInDown */
@keyframes slideInDown {
  from {
    opacity: 0;
    transform: translateY(-12px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* === Pulse Animations === */
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.75;
  }
}

@keyframes loadingPulse {
  0%,
  100% {
    opacity: 0.8;
  }

  50% {
    opacity: 1;
  }
}

@keyframes icon-pop {
  0% {
    transform: scale(0.8);
    opacity: 0.4;
  }

  60% {
    transform: scale(1.06);
    opacity: 1;
  }

  100% {
    transform: scale(1);
  }
}

/* === Spin Animation (single definition) === */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* === Shake Animation === */
@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }

  25% {
    transform: translateX(-3px);
  }

  75% {
    transform: translateX(3px);
  }
}

@keyframes value-flash {
  0% {
    background-color: rgb(var(--primary-rgb) / 12%);
  }

  100% {
    background-color: transparent;
  }
}

.value-flash {
  animation: value-flash 600ms ease-out;
}

@keyframes ripple {
  0% {
    transform: scale(0);
    opacity: 0.3;
  }

  70% {
    opacity: 0.1;
  }

  100% {
    transform: scale(2.5);
    opacity: 0;
  }
}

/* Reduced motion support defined in core/utilities.css */
