/* ==========================================================================
   GolPredict.com — animations.css
   Scope: Todos los keyframes, transiciones complejas y micro-interacciones.
   Este archivo se carga al final de la cascada CSS.
   Depende de: main.css (variables) + components.css (clases trigger)
   Regla: si prefers-reduced-motion está activo, main.css ya neutraliza todo.
   ========================================================================== */


/* ==========================================================================
   1. ENTRADA DE VISTAS (DOM Router transitions)
   router.js agrega/quita la clase .view--active. La animación
   de entrada siempre es suave; la de salida es instantánea (display:none).
   ========================================================================== */

@keyframes view-enter {
  0%   { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0);    }
}

/* Vista que sale: fade rápido para no bloquear la que entra */
@keyframes view-exit {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

.view--active {
  animation: view-enter 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}


/* ==========================================================================
   2. CARDS DE PARTIDOS — Entrada escalonada (staggered)
   JS asigna --card-index: 0..5 a cada fixture-card para el delay.
   ========================================================================== */

@keyframes card-enter {
  0%   { opacity: 0; transform: translateY(14px) scale(0.97); }
  100% { opacity: 1; transform: translateY(0)    scale(1);    }
}

/* La fixture-card ya declara su propia animación con var(--card-index).
   Este keyframe es la definición compartida referenciada en components.css. */


/* ==========================================================================
   3. PUNTOS GANADOS — Número sube y desaparece (score pop)
   Se activa cuando scoring-engine.js asigna puntos a una card evaluada.
   ========================================================================== */

@keyframes score-pop {
  0%   { opacity: 0; transform: translateY(0)    scale(0.6); }
  40%  { opacity: 1; transform: translateY(-6px) scale(1.2); }
  70%  { opacity: 1; transform: translateY(-8px) scale(1.0); }
  100% { opacity: 1; transform: translateY(-4px) scale(1.0); }
}

.points-earned--animate {
  animation: score-pop 0.5s var(--transition-bounce) forwards;
}

/* Partícula flotante que sube y se desvanece (instanciada desde JS) */
@keyframes float-up-fade {
  0%   { opacity: 1; transform: translateY(0)   scale(1);    }
  80%  { opacity: 0.8; }
  100% { opacity: 0; transform: translateY(-40px) scale(0.8); }
}

.float-particle {
  position: absolute;
  pointer-events: none;
  z-index: var(--z-dropdown);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--fw-regular);
  animation: float-up-fade 1.2s ease-out forwards;
}
.float-particle--exact  { color: var(--accent-green); }
.float-particle--trend  { color: var(--accent-blue);  }
.float-particle--miss   { color: var(--accent-red);   }
.float-particle--bonus  { color: #ff8c00; font-size: var(--text-lg); }


/* ==========================================================================
   4. RESULTADO EXACTO — Explosión de confeti (CSS puro)
   Se monta en la fixture-card al recibir .fixture-card--exact.
   Genera 8 partículas con colores y ángulos variados.
   JS añade la clase .confetti-trigger al contenedor de la card.
   ========================================================================== */

@keyframes confetti-fly {
  0%   { opacity: 1; transform: translate(0, 0) rotate(0deg) scale(1); }
  100% { opacity: 0; transform: translate(var(--cx), var(--cy)) rotate(var(--cr)) scale(0.4); }
}

.confetti-particle {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 1px;
  top: 50%;
  left: 50%;
  pointer-events: none;
  z-index: var(--z-dropdown);
  animation: confetti-fly 0.9s ease-out forwards;
  animation-delay: var(--cd, 0ms);
}

/* 8 partículas con direcciones distintas — JS las crea con style inline */
/* Colores definidos inline por JS según el tipo de acierto */


/* ==========================================================================
   5. LLAMA DE RACHA (Streak Flame) 🔥
   ========================================================================== */

@keyframes flame-pulse {
  0%   { transform: scale(1)    rotate(-3deg); filter: drop-shadow(0 0 6px rgba(255, 100, 0, 0.4)); }
  30%  { transform: scale(1.10) rotate(2deg);  filter: drop-shadow(0 0 12px rgba(255, 100, 0, 0.7)); }
  60%  { transform: scale(1.05) rotate(-1deg); filter: drop-shadow(0 0 8px rgba(255, 100, 0, 0.5)); }
  100% { transform: scale(1)    rotate(-3deg); filter: drop-shadow(0 0 6px rgba(255, 100, 0, 0.4)); }
}

/* Cuando la racha aumenta: rebote de celebración */
@keyframes flame-celebrate {
  0%   { transform: scale(1);    }
  20%  { transform: scale(1.40) rotate(8deg);  }
  40%  { transform: scale(0.90) rotate(-5deg); }
  60%  { transform: scale(1.20) rotate(4deg);  }
  80%  { transform: scale(0.95) rotate(-2deg); }
  100% { transform: scale(1);    }
}

.streak-flame {
  animation: flame-pulse 2.4s ease-in-out infinite;
  display: inline-block;
  transform-origin: bottom center;
}

.streak-flame--celebrate {
  animation: flame-celebrate 0.7s var(--transition-bounce) forwards;
}

/* Racha en cero: llama apagada */
[data-streak="0"] .streak-flame {
  animation: none;
  opacity: 0.25;
  filter: grayscale(1);
}


/* ==========================================================================
   6. NÚMERO DE RACHA — Counter up animation
   Cuando el número sube: el dígito sale hacia arriba y el nuevo baja.
   ========================================================================== */

@keyframes streak-count-out {
  0%   { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-16px); }
}
@keyframes streak-count-in {
  0%   { opacity: 0; transform: translateY(16px); }
  100% { opacity: 1; transform: translateY(0); }
}

.streak-number {
  display: inline-block;
  overflow: hidden;
}
.streak-number--exiting {
  animation: streak-count-out 200ms ease-in forwards;
}
.streak-number--entering {
  animation: streak-count-in 200ms ease-out forwards;
}


/* ==========================================================================
   7. MODAL — Entrada y salida
   ========================================================================== */

@keyframes modal-panel-enter {
  0%   { opacity: 0; transform: translateY(28px) scale(0.96); }
  100% { opacity: 1; transform: translateY(0)    scale(1);    }
}
@keyframes modal-panel-exit {
  0%   { opacity: 1; transform: translateY(0)    scale(1);    }
  100% { opacity: 0; transform: translateY(20px) scale(0.97); }
}
@keyframes modal-backdrop-enter {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes modal-backdrop-exit {
  from { opacity: 1; }
  to   { opacity: 0; }
}


/* ==========================================================================
   8. TOAST — Entrada desde la derecha, salida hacia la derecha
   ========================================================================== */

@keyframes toast-enter {
  0%   { opacity: 0; transform: translateX(100%) scale(0.95); max-height: 0;   }
  40%  { opacity: 1; max-height: 120px; }
  100% { opacity: 1; transform: translateX(0)    scale(1);    max-height: 120px; }
}
@keyframes toast-exit {
  0%   { opacity: 1; transform: translateX(0);    max-height: 120px; margin-bottom: var(--space-3); }
  100% { opacity: 0; transform: translateX(100%); max-height: 0;     margin-bottom: 0; padding: 0; }
}

.toast {
  animation: toast-enter 380ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  overflow: hidden;
}
.toast--exiting {
  animation: toast-exit 280ms ease-in forwards;
}


/* ==========================================================================
   9. SPLASH SCREEN — Secuencia de entrada
   ========================================================================== */

@keyframes splash-logo-enter {
  0%   { opacity: 0; transform: scale(0.8) translateY(10px); filter: blur(4px); }
  100% { opacity: 1; transform: scale(1)   translateY(0);    filter: blur(0);   }
}
@keyframes splash-spinner-enter {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes splash-exit {
  0%   { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden;  }
}

.splash__logo {
  animation: splash-logo-enter 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.splash__spinner {
  animation: splash-spinner-enter 0.4s ease 0.5s both;
}
.splash.splash--hidden {
  animation: splash-exit 0.5s ease forwards;
  pointer-events: none;
}


/* ==========================================================================
   10. SKELETON LOADING — Shimmer wave
   ========================================================================== */

@keyframes skeleton-wave {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}

.loading-skeleton {
  background: linear-gradient(
    90deg,
    var(--color-bg-surface)  0%,
    var(--color-bg-elevated) 50%,
    var(--color-bg-surface)  100%
  );
  background-size: 200% 100%;
  animation: skeleton-wave 1.6s ease-in-out infinite;
  border-radius: var(--radius-md);
}


/* ==========================================================================
   11. BADGE PULSE — Para el badge de predicciones pendientes en el nav
   ========================================================================== */

@keyframes badge-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(249, 168, 37, 0.6); }
  70%  { box-shadow: 0 0 0 6px rgba(249, 168, 37, 0);   }
  100% { box-shadow: 0 0 0 0   rgba(249, 168, 37, 0);   }
}

.nav-badge--pending {
  animation: badge-pulse 2s ease-out infinite;
}


/* ==========================================================================
   12. SPINNER GENÉRICO
   ========================================================================== */

@keyframes spin {
  to { transform: rotate(360deg); }
}

.spinner-ring {
  animation: spin 0.75s linear infinite;
}

/* Phosphor spin utility (usado en botones de carga) */
.ph-spin {
  animation: spin 0.8s linear infinite;
}


/* ==========================================================================
   13. SLIDE UP — Para la barra de guardar predicciones
   ========================================================================== */

@keyframes slide-up {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0);    }
}

.save-predictions-bar {
  animation: slide-up 350ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}


/* ==========================================================================
   14. PAYWALL BUTTON — Shimmer animado en el botón principal de compra
   Efecto "luz que cruza" para llamar la atención sobre el CTA.
   ========================================================================== */

@keyframes btn-shimmer {
  0%   { transform: translateX(-100%) skewX(-15deg); }
  100% { transform: translateX(200%)  skewX(-15deg); }
}

.btn--premium,
.btn--ticket {
  position: relative;
  overflow: hidden;
}
.btn--premium::before,
.btn--ticket::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 40%;
  height: 100%;
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  animation: btn-shimmer 2.8s ease-in-out 1.5s infinite;
  pointer-events: none;
  border-radius: inherit;
}


/* ==========================================================================
   15. FIXTURE CARD HOVER — Glow animado sutil en el borde
   Solo en cards pendientes (editables), no en las ya evaluadas.
   ========================================================================== */

@keyframes card-border-glow {
  0%   { box-shadow: 0 0 0   0   rgba(39, 174, 96, 0);    }
  50%  { box-shadow: 0 0 16px 1px rgba(39, 174, 96, 0.12); }
  100% { box-shadow: 0 0 0   0   rgba(39, 174, 96, 0);    }
}

/* hover animation removed */

/* Card estrella: glow dorado permanente sutil */
@keyframes star-card-glow {
  0%   { box-shadow: 0 0 12px 0px rgba(249, 168, 37, 0.12); }
  50%  { box-shadow: 0 0 22px 2px rgba(249, 168, 37, 0.22); }
  100% { box-shadow: 0 0 12px 0px rgba(249, 168, 37, 0.12); }
}

/* star card glow removed — borde dorado estático en components.css */


/* ==========================================================================
   16. PODIO — Entrada animada (desktop: desde abajo, mobile: fade)
   ========================================================================== */

@keyframes pedestal-rise {
  0%   { opacity: 0; transform: scaleY(0);   transform-origin: bottom; }
  100% { opacity: 1; transform: scaleY(1);   transform-origin: bottom; }
}
@keyframes podium-avatar-drop {
  0%   { opacity: 0; transform: translateY(-20px) scale(0.85); }
  70%  { transform: translateY(4px) scale(1.04); }
  100% { opacity: 1; transform: translateY(0)  scale(1); }
}

.podium-slot__pedestal {
  animation: pedestal-rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.podium-slot--1 .podium-slot__pedestal { animation-delay: 0.1s; }
.podium-slot--2 .podium-slot__pedestal { animation-delay: 0.2s; }
.podium-slot--3 .podium-slot__pedestal { animation-delay: 0.3s; }

.podium-slot__avatar {
  animation: podium-avatar-drop 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.podium-slot--1 .podium-slot__avatar { animation-delay: 0.4s; }
.podium-slot--2 .podium-slot__avatar { animation-delay: 0.5s; }
.podium-slot--3 .podium-slot__avatar { animation-delay: 0.6s; }


/* ==========================================================================
   17. LIVE BADGE PULSE
   ========================================================================== */

@keyframes live-pulse {
  0%, 100% { opacity: 1;   transform: scale(1);    }
  50%       { opacity: 0.3; transform: scale(0.75); }
}


/* ==========================================================================
   18. FADE UP — Utilidad genérica para listas que se cargan progresivamente
   JS puede aplicar esta clase a elementos con animation-delay inline.
   ========================================================================== */

@keyframes fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0);    }
}

.animate-fade-up {
  animation: fade-up 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Versión con delay para listas: se asigna animation-delay desde JS */
.animate-stagger {
  animation: fade-up 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: var(--stagger-delay, 0ms);
}


/* ==========================================================================
   19. TOURNAMENT TAB — Indicador deslizante
   Las tabs del torneo usan este efecto de subrayado que se mueve.
   JS mueve la clase .tournament-tab--active en el click.
   ========================================================================== */

.tournament-tab {
  transition:
    color        var(--transition-fast),
    background   var(--transition-fast),
    box-shadow   var(--transition-fast);
}
.tournament-tab--active {
  transition:
    color        var(--transition-fast),
    background   var(--transition-base),
    box-shadow   var(--transition-base);
}


/* ==========================================================================
   20. INPUT DE SCORE — Feedback al escribir
   Cuando el usuario termina de escribir un número se hace un micro-bounce.
   JS agrega y quita la clase .score-input--typed.
   ========================================================================== */

@keyframes input-bounce {
  0%   { transform: scale(1);    }
  30%  { transform: scale(1.08); }
  60%  { transform: scale(0.97); }
  100% { transform: scale(1);    }
}

.score-input--typed {
  animation: input-bounce 250ms var(--transition-bounce) forwards;
}


/* ==========================================================================
   21. SIDEBAR NAV LINK — Indicador de ruta activa
   El pseudo-elemento ::before con la barra verde hace un slide-in.
   ========================================================================== */

.sidebar__nav-link::before {
  transition:
    height    var(--transition-base),
    opacity   var(--transition-fast);
  opacity: 0;
}
.sidebar__nav-link--active::before,
.sidebar__nav-link[data-active="true"]::before {
  opacity: 1;
}


/* ==========================================================================
   22. LEADERBOARD ROW — Entrada escalonada al cargar el ranking
   leaderboard.js asigna --row-index a cada fila para el delay.
   ========================================================================== */

@keyframes row-enter {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0);    }
}

.leaderboard-row {
  animation: row-enter 300ms ease both;
  animation-delay: calc(var(--row-index, 0) * 40ms);
}


/* ==========================================================================
   23. CROWN DEL PODIO — Bounce eterno en el 1er lugar
   ========================================================================== */

@keyframes crown-bounce {
  0%   { transform: translateY(0)   rotate(-5deg) scale(1);    }
  25%  { transform: translateY(-4px) rotate(0deg)  scale(1.1);  }
  50%  { transform: translateY(0)   rotate(5deg)  scale(1);    }
  75%  { transform: translateY(-2px) rotate(0deg)  scale(1.05); }
  100% { transform: translateY(0)   rotate(-5deg) scale(1);    }
}

.podium-slot__crown {
  animation: crown-bounce 2.5s ease-in-out infinite;
  transform-origin: center bottom;
}


/* ==========================================================================
   24. RETO TOP 3 — Check mark de acierto en el banner
   ========================================================================== */

@keyframes check-pop {
  0%   { opacity: 0; transform: scale(0) rotate(-45deg); }
  60%  { opacity: 1; transform: scale(1.25) rotate(8deg); }
  100% { opacity: 1; transform: scale(1)    rotate(0deg); }
}

.top3-indicator--exact {
  animation: check-pop 0.4s var(--transition-bounce) forwards;
}


/* ==========================================================================
   25. SIDEBAR MOBILE — Slide in/out
   ========================================================================== */

.sidebar {
  transition: transform var(--transition-base);
}
.sidebar.sidebar--open {
  /* transform: translateX(0) ya declarado en layout.css */
  /* La transición de salida también usa var(--transition-base) */
}


/* ==========================================================================
   26. OVERLAY — Fade in/out
   ========================================================================== */

.overlay {
  transition: opacity var(--transition-base), visibility var(--transition-base);
}


/* ==========================================================================
   27. BARRA DE GUARDAR — Shake cuando falla la validación
   Se activa si el usuario intenta guardar sin completar inputs requeridos.
   ========================================================================== */

@keyframes shake {
  0%   { transform: translateX(0);   }
  15%  { transform: translateX(-6px); }
  30%  { transform: translateX(6px);  }
  45%  { transform: translateX(-4px); }
  60%  { transform: translateX(4px);  }
  75%  { transform: translateX(-2px); }
  90%  { transform: translateX(2px);  }
  100% { transform: translateX(0);   }
}

.save-predictions-bar--error {
  animation: shake 0.45s ease both;
  border-color: rgba(211, 47, 47, 0.5) !important;
}


/* ==========================================================================
   28. HERO DEL TORNEO — Banderas flotantes en el fondo
   worldcup.js inyecta elementos .flag-bg-item con --flag-x y --flag-delay.
   ========================================================================== */

@keyframes flag-float {
  0%   { transform: translateY(0)    rotate(var(--flag-rot, 0deg)); opacity: 0.05; }
  50%  { transform: translateY(-12px) rotate(var(--flag-rot, 0deg)); opacity: 0.08; }
  100% { transform: translateY(0)    rotate(var(--flag-rot, 0deg)); opacity: 0.05; }
}

.flag-bg-item {
  animation: flag-float 5s ease-in-out infinite;
  animation-delay: var(--flag-delay, 0s);
}


/* ==========================================================================
   29. PREMIUM BADGE — Brillo giratorio
   ========================================================================== */

@keyframes premium-shine {
  0%   { background-position: -200% center; }
  100% { background-position:  200% center; }
}

.badge--premium {
  background-size: 200% auto;
  animation: premium-shine 3s linear infinite;
  background-image: linear-gradient(
    135deg,
    var(--color-premium-d) 0%,
    var(--color-premium-l) 40%,
    #fff6d0              50%,
    var(--color-premium-l) 60%,
    var(--color-premium-d) 100%
  );
}