/* movimiento.css — El movimiento del sitio, en un solo sitio.
 *
 * Regla de la casa, de las guías de Apple: amortiguación crítica (sin rebote)
 * salvo cuando el gesto trae impulso. Rebotar por rebotar marea, sobre todo
 * mientras alguien escribe.
 *
 * Y todo se apaga con prefers-reduced-motion. Reducir movimiento no es quitar
 * la respuesta: se cambia el desplazamiento por un fundido corto.
 */

/* ── 5 · Respuesta al pulsar, en TODO el sitio ─────────────────────────────
   Feedback en el pointer-down, no al soltar. Es la base de que algo se sienta
   directo; sin esto, un botón parece muerto los 200 ms que tarda el clic. */
.btn, button, .tipos button, .vistas button, [role="radio"] {
  transition: transform 100ms ease-out, background-color 140ms ease-out,
              border-color 140ms ease-out, color 140ms ease-out;
}
.btn:active, .tipos button:active, .vistas button:active { transform: scale(.97); }

/* ── 1 · El interruptor de vistas ──────────────────────────────────────────
   La píldora se desliza en vez de saltar, con el muelle de "mover" de Apple
   (damping 1.0, response 0.4) aproximado con una curva sin rebote. */
.vistas-pildora {
  transition: transform 400ms cubic-bezier(.32, .72, 0, 1),
              width 400ms cubic-bezier(.32, .72, 0, 1);
}
/* El contenido entra desde donde viene, no aparece de la nada. */
.vista.entrando { animation: vista-entra 340ms cubic-bezier(.32, .72, 0, 1) both; }
@keyframes vista-entra {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ── 2 · La tarjeta mientras se arma ───────────────────────────────────────
   Sin rebote a propósito: el color y la foto cambian con cada tecla y un muelle
   elástico aquí sería mareante. */
.tel-pantalla .tarjeta, .tel-pantalla .guardar, .tel-pantalla .portada {
  transition: background-color 160ms ease-out, background-image 160ms ease-out;
}
.tel-pantalla .foto img, .tel-pantalla .portada { transition: opacity 200ms ease-out; }
.tel-pantalla .filas li, .tel-pantalla .redes li {
  animation: fila-entra 220ms cubic-bezier(.32, .72, 0, 1) both;
}
@keyframes fila-entra {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* ── 3 · El QR cuando se verifica ──────────────────────────────────────────
   Materializar, no aparecer: es el momento en que el producto demuestra que
   funciona, y merece leerse como algo que llega. */
#lienzo canvas, .vcard-qr canvas {
  animation: qr-materializa 280ms cubic-bezier(.32, .72, 0, 1) both;
}
@keyframes qr-materializa {
  from { opacity: 0; filter: blur(6px); transform: scale(.96); }
  to   { opacity: 1; filter: none; transform: none; }
}
.estado { transition: color 200ms ease-out, background-color 200ms ease-out; }

/* ── 4 · La galería del artístico ──────────────────────────────────────────
   Escalonada: ocho piezas entrando a la vez es un parpadeo; escalonadas se leen
   como una serie, que es lo que son. */
/* OJO: el estado inicial lo pone JavaScript con .por-entrar, NO el CSS a secas.
   Si lo escondiera aquí y el observador fallara —o no hubiera JS— la galería se
   quedaría invisible, que es exactamente lo que ya pasó dos veces. El contenido
   se ve por defecto; la animación sólo lo adorna. */
.galeria figure.por-entrar { opacity: 0; transform: translateY(14px) scale(.98); }
.galeria figure.a-la-vista {
  animation: pieza-entra 420ms cubic-bezier(.32, .72, 0, 1) both;
  animation-delay: calc(var(--turno, 0) * 60ms);
}
@keyframes pieza-entra {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.galeria figure img { transition: transform 300ms cubic-bezier(.32, .72, 0, 1); }
.galeria figure:hover img { transform: scale(1.03); }

/* ── 6 · Lo que se abre encima ─────────────────────────────────────────────
   Materializa con desenfoque y escala a la vez, para que el cristal se lea como
   un material que llega y no como una opacidad que sube. */
.modal:not([hidden]), .oferta:not([hidden]) {
  animation: velo-entra 200ms ease-out both;
}
.modal:not([hidden]) .modal-caja, .oferta:not([hidden]) .oferta-caja {
  animation: caja-entra 320ms cubic-bezier(.32, .72, 0, 1) both;
}
@keyframes velo-entra { from { opacity: 0; } to { opacity: 1; } }
@keyframes caja-entra {
  from { opacity: 0; transform: scale(.94) translateY(12px); filter: blur(8px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* ── Reducir movimiento ────────────────────────────────────────────────────
   Se quedan los cambios de opacidad y color, que ayudan a entender; se van los
   desplazamientos, las escalas y los desenfoques, que son los que marean. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    transition-duration: 120ms !important;
  }
  .btn:active, .tipos button:active, .vistas button:active { transform: none; }
  .galeria figure { opacity: 1; transform: none; }
  .galeria figure:hover img { transform: none; }
  .modal:not([hidden]) .modal-caja { animation: velo-entra 120ms ease-out both; }
}
