/* ZenFit — coreografía (references/motion.md). Solo transform/opacity. */

/* Anti doble-tap: bloquea toda la pantalla apenas se registra la primera elección/CTA, hasta que la transición se lleva la pantalla. */
.screen.locked { pointer-events: none; }

/* 1. Transición entre pantallas */
/* Navegación más ágil (auditoría GPT 17/09: "repetida 35 veces empieza a pesar"): entrada 220ms, salida 150ms,
   y la entrada arranca mientras la salida todavía corre (las dos pantallas conviven ~150ms), así el paso
   selección → salida → entrada se siente continuo y no como tres tiempos. */
.screen.enter { animation: screen-in 220ms var(--ease) both; }
.screen.leave { animation: screen-out 150ms var(--ease-out) both; pointer-events: none; }
.screen.enter.back { animation-name: screen-in-back; }
.screen.leave.back { animation-name: screen-out-back; }
@keyframes screen-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes screen-out { to { opacity: 0; transform: translateX(-24px); } }
@keyframes screen-in-back { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
@keyframes screen-out-back { to { opacity: 0; transform: translateX(24px); } }

.progress > span { transition: width var(--dur-slow) var(--ease); position: relative; overflow: hidden; }
.progress > span::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255, 254, 250, .45), transparent); transform: translateX(-100%); animation: shine 900ms var(--ease) 120ms 1; }
@keyframes shine { to { transform: translateX(100%); } }

/* 2. Stagger de entrada. Selector [data-rv] (no .reveal): rv() en render.js/paywall.js escribe un atributo
   propio para no duplicar el class="..." que cada tag ya trae (dos `class` en un tag es HTML inválido y el
   parser se queda con el primero). Delay con tope de 8 elementos (motion.md §2: "máximo 8, después sin stagger"). */
[data-rv] { opacity: 0; transform: translateY(12px); animation: reveal 320ms var(--ease) both; animation-delay: calc(min(var(--i, 0), 8) * 45ms + 60ms); }
@keyframes reveal { to { opacity: 1; transform: none; } }

/* 3. Opciones */
.opt, .card { transition: transform 90ms var(--ease), background-color var(--dur-fast), border-color var(--dur-fast), box-shadow 160ms var(--ease), opacity 180ms var(--ease); }
.opt:active, .card:active { transform: scale(.985); }
.card:active img { transform: scale(1.03); }
.card img { transition: transform 200ms var(--ease); }
@media (hover: hover) { .card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); } }
.opt .arrow, .card .arrow { transition: transform 220ms var(--ease); }
.opts.picked .opt:not([aria-checked="true"]), .cards.picked .card:not([aria-checked="true"]) { opacity: .55; }
.opt[aria-checked="true"] .arrow, .card[aria-checked="true"] .arrow { animation: pop 220ms var(--ease); }
@keyframes pop { 50% { transform: scale(1.15); } }
.opt .check svg path { stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset 180ms var(--ease); }
.opt[aria-checked="true"] .check svg path { stroke-dashoffset: 0; }
.btn { transition: transform 90ms var(--ease), opacity var(--dur-fast), box-shadow 200ms var(--ease); }
.btn:active:not([disabled]) { transform: scale(.985); }
.btn.enabled-in { animation: reveal 220ms var(--ease) both; }

/* 5. Sliders */
.measure .val.tick { animation: val-tick 80ms var(--ease); }
@keyframes val-tick { from { transform: scale(1.06); opacity: .6; } }
.slider .thumb { transition: transform 120ms var(--ease); }
.slider.dragging .thumb { transform: scale(1.2); }

/* 6. Loader */
.ring circle.fg { transition: stroke-dashoffset 300ms linear; }
.bullet.done .dot svg path { stroke-dasharray: 24; stroke-dashoffset: 0; transition: stroke-dashoffset 220ms var(--ease); }
.bullet.pending .dot svg path { stroke-dasharray: 24; stroke-dashoffset: 24; }

/* 7. Gráficos */
.draw-line { stroke-dasharray: 700; stroke-dashoffset: 700; animation: draw 900ms var(--ease) 200ms forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.draw-pop { opacity: 0; transform-box: fill-box; transform-origin: center; animation: pop-in 260ms var(--ease) 1000ms forwards; }
@keyframes pop-in { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }
.gauge .marker { transition: transform 700ms var(--ease); }

/* 8. Venta */
.sticky-cta { position: fixed; left: 50%; bottom: 0; width: 100%; max-width: var(--app-max); transform: translate(-50%, 100%); transition: transform var(--dur) var(--ease); z-index: 5; padding: 10px var(--pad-x) calc(12px + env(safe-area-inset-bottom)); background: linear-gradient(180deg, rgba(247, 244, 236, 0), var(--bg) 40%); }
.sticky-cta.show { transform: translate(-50%, 0); }
.digit { display: inline-block; min-width: 1ch; font-variant-numeric: tabular-nums; }
/* Solo desplazamiento, sin opacidad: si un motor congela o descarta la animación (auditoría GPT vio "12:" sin
   segundos), el dígito sigue legible. El estado final es explícito. */
.digit.flip { animation: flip 200ms var(--ease); }
@keyframes flip { from { transform: translateY(-35%); } to { transform: none; } }
/* Cupos: un solo pulso suave al aparecer y el número cambia con flip (no shake): color + movimiento marcan la
   urgencia sin agresividad (GPT 17/09). */
.scarcity[data-rv] .pill-note { animation: urgency-pulse 700ms var(--ease) 500ms 1; }
.scarcity .pill-note b { display: inline-block; }
.scarcity.bump .pill-note b { animation: flip 260ms var(--ease); }
@keyframes urgency-pulse { 40% { transform: scale(1.03); box-shadow: 0 6px 18px rgba(185, 71, 60, .22); } }
.revealable { opacity: 0; transform: translateY(14px); }
.revealable.on { animation: reveal 380ms var(--ease) both; animation-delay: calc(var(--i, 0) * 80ms); }
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 240ms var(--ease); }
.faq-a > div { overflow: hidden; }
.faq-item.open .faq-a { grid-template-rows: 1fr; }
.faq-q .chev { transition: transform 240ms var(--ease); }
.faq-item.open .faq-q .chev { transform: rotate(180deg); }
/* Tres pulsos y quieto: el pulso infinito se siente "landing agresiva" (GPT 17/09). */
.btn.pulse { animation: pulse 2400ms var(--ease) 3; }
@keyframes pulse { 0%, 100% { box-shadow: var(--shadow-primary); } 45% { box-shadow: 0 10px 28px rgba(63, 84, 56, 0.32); } }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .screen.enter, .screen.leave { animation-duration: 120ms; animation-name: fade-in; }
  .screen.leave { animation-name: fade-out; }
  /* fade-in necesita un "to" explícito: sin él, el "to" implícito toma el opacity:0 estático de [data-rv]
     (translateY(12px) incluido) y con animation-fill-mode:both el contenido queda invisible para siempre
     en cualquier dispositivo con "reducir movimiento" activado — no es solo cosmético, es un bloqueo real. */
  @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes fade-out { to { opacity: 0; } }
  [data-rv], .revealable.on { animation: fade-in 120ms both; animation-delay: 0ms !important; transform: none !important; }
  .progress > span::after, .btn.pulse, .opt[aria-checked="true"] .arrow, .digit.flip, .scarcity[data-rv] .pill-note, .scarcity.bump .pill-note b { animation: none; }
  .draw-line { animation: none; stroke-dashoffset: 0; }
  .draw-pop { animation: none; opacity: 1; }
  .opt, .card, .btn, .gauge .marker, .sticky-cta, .faq-a { transition-duration: 1ms; }
}
