/* ═══════════════════════════════════════════════════════════════
   ANIMATIONS.CSS — Todas las animaciones y keyframes del sitio
   Nota: los efectos controlados por JS (cursor, partículas, parallax,
   hover magnético, slot-machine, confeti) deben consultar
   window.matchMedia('(prefers-reduced-motion: reduce)') antes de
   animar por rAF — eso vive en animations.js / counters.js, no aquí.
   El reset global en reset.css ya reduce animation/transition-duration
   a ~0 para *todo*; los bloques @prefers-reduced-motion de este
   archivo afinan casos puntuales (loops infinitos, blur, opacidad).
   ═══════════════════════════════════════════════════════════════ */

/* ── Reveal on scroll (IntersectionObserver añade [data-visible]) ── */
[data-reveal] {
  opacity: 0;
  transition: opacity var(--dur-slower) var(--ease-spring),
              transform var(--dur-slower) var(--ease-spring);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal="fade-up"]    { transform: translateY(28px); }
[data-reveal="fade-left"]  { transform: translateX(-28px); }
[data-reveal="fade-right"] { transform: translateX(28px); }
[data-reveal="scale-in"]   { transform: scale(0.92); }

[data-reveal][data-visible="true"] {
  opacity: 1;
  transform: translate(0, 0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ── Badge — punto parpadeante ────────────────────────────────── */
@keyframes badgeBlink {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.5); }
  50% { opacity: 0.55; box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); }
}

/* ── Botón con pulso de glow (CTA final, wa-float) ────────────── */
@keyframes btnPulseGlow {
  0%, 100% { box-shadow: 0 0 0 0 var(--color-accent-glow); }
  50% { box-shadow: 0 0 40px 6px var(--color-accent-glow); }
}

@keyframes waPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.45); }
  50% { box-shadow: 0 0 0 12px rgba(37, 211, 102, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .btn--pulse, .wa-float { animation: none; }
}

/* ── Cursor: ripple al hacer click ────────────────────────────── */
@keyframes cursorRipple {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.8); opacity: 0; }
}

/* ── Preloader ────────────────────────────────────────────────── */
@keyframes preloaderLetter {
  to { opacity: 1; transform: translateY(0); }
}

@keyframes preloaderFill {
  0%   { width: 0%; }
  70%  { width: 78%; }
  100% { width: 100%; }
}

/* ── Typewriter cursor ────────────────────────────────────────── */
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* ── Marquee doble dirección ──────────────────────────────────── */
@keyframes marqueeLTR {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes marqueeRTL {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; }
}

/* ── Carrusel — barra de progreso del dot activo ──────────────── */
@keyframes carouselDotFill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ── Mapa de cobertura — pulso del punto principal ────────────── */
@keyframes mapPulse {
  0%   { r: 6; opacity: 0.9; }
  70%  { r: 16; opacity: 0; }
  100% { r: 6; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .coverage__point--main circle { animation: none; }
}

/* ── Glitch sutil del logo del hero (cada 8s, disparado por JS) ── */
@keyframes glitchRGB {
  0%   { clip-path: inset(0 0 0 0); transform: translate(0, 0); }
  10%  { clip-path: inset(10% 0 60% 0); transform: translate(-2px, 1px); }
  20%  { clip-path: inset(60% 0 5% 0); transform: translate(2px, -1px); }
  30%  { clip-path: inset(20% 0 40% 0); transform: translate(-1px, 0); }
  40%  { clip-path: inset(0 0 0 0); transform: translate(0, 0); }
  100% { clip-path: inset(0 0 0 0); transform: translate(0, 0); }
}

.glitching {
  position: relative;
}

.glitching::before,
.glitching::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  background: inherit;
}

.glitching.is-glitch::before {
  color: #ff2b4d;
  mix-blend-mode: screen;
  animation: glitchRGB 120ms linear;
}
.glitching.is-glitch::after {
  color: #00e5ff;
  mix-blend-mode: screen;
  animation: glitchRGB 120ms linear reverse;
}

@media (prefers-reduced-motion: reduce) {
  .glitching.is-glitch::before,
  .glitching.is-glitch::after { animation: none; content: none; }
}

/* ── Slot machine — dígitos del contador del hero ─────────────── */
.slot-digit {
  display: inline-block;
  overflow: hidden;
  height: 1em;
  vertical-align: bottom;
}

.slot-digit__reel {
  display: flex;
  flex-direction: column;
  transition: transform var(--dur-slower) var(--ease-spring);
}

@media (prefers-reduced-motion: reduce) {
  .slot-digit__reel { transition: none; }
}

/* ── Contador — partícula de celebración al terminar ──────────── */
@keyframes counterBurst {
  0%   { transform: scale(0.4); opacity: 1; }
  100% { transform: scale(2.2); opacity: 0; }
}

.counter-burst {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--color-accent-glow);
  pointer-events: none;
  animation: counterBurst 600ms var(--ease-out) forwards;
}

@media (prefers-reduced-motion: reduce) {
  .counter-burst { display: none; }
}

/* ── Parallax del hero (transform aplicado por JS vía --parallax-y) */
.hero__grid,
.hero__glow,
[data-parallax] {
  transform: translateY(calc(var(--parallax-y, 0px)));
}

@media (prefers-reduced-motion: reduce) {
  .hero__grid, .hero__glow, [data-parallax] {
    transform: none !important;
  }
}

/* ── Confeti (canvas dibujado por JS; solo contenedor aquí) ───── */
@media (prefers-reduced-motion: reduce) {
  .form__confetti-canvas { display: none; }
}
