/* ══════════════════════════════════════════════════════════════════════════
 * motion-ax.css — EL VOCABULARIO DE MOVIMIENTO `archive-x`, UNA SOLA VEZ
 * ══════════════════════════════════════════════════════════════════════════
 *
 * Qué es: el paso lateral de las galerías nativas —WhatsApp, Fotos de iOS—. La
 * que SALE se escala al 60 % desvaneciéndose; la que ENTRA desliza **desde la
 * izquierda**. Al retroceder, el espejo. Da profundidad en vez de un fundido
 * plano, y es lo que un visor de imágenes quiere por defecto.
 *
 * ── POR QUÉ EXISTE ESTA HOJA (y por qué es la SEGUNDA vez que nace) ────────
 *
 * 🗣️ Lo dictó Adán el 2026-10-12: *«una cosa es el dialog de apertura del grid y
 * otra el efecto carousel; el carousel también mueve los testimonials»*. Y el
 * mismo día, la raíz: *«el dialog debería aplicar el efecto que importamos, como
 * el carousel aplica el suyo por parámetro»*.
 *
 * El efecto vivía **dentro de `carousel.css`**, así que el visor del álbum tenía
 * dos salidas y las dos malas: declarar esa hoja entera —traerse el vestido de
 * otra pieza, incluidos sus velos y su navegación de miniaturas— o quedarse sin
 * efecto. 📐 **Y se quedó sin efecto, medido en producción el 2026-10-12:** el
 * paso de foto del álbum daba `animationName: none` en las dos imágenes, con la
 * que sale escalando un **6 %** (0.999 → 0.94, imperceptible) y la que entra
 * llegando **desde la derecha**. O sea el deslizamiento propio del `_goTo` del
 * motor, no `archive-x`. Adán lo dijo tres sesiones seguidas: *«el efecto del
 * slider sigue sin ser el de archive-x»*.
 *
 * 🔴 **Nació el 2026-10-11, con esta misma razón, y el revert `1912488e` se la
 * llevó** junto con seis keyframes inventados que sí había que retirar. El
 * revert tenía razón en el conjunto y se equivocó en esta pieza: su propio
 * mensaje declara que al slider *«le falta `archive-x`»*. Se repone **con los
 * cuatro keyframes originales y ni uno más**.
 *
 * ── CÓMO SE CONSUME: dos piezas, un vocabulario ───────────────────────────
 *
 * Aquí viven **sólo los `@keyframes`**. Las reglas que los invocan están en la
 * hoja de cada pieza, con su `z-index` y su duración, porque eso es su diseño
 * (`docs/context/principios.md` §8 — lo compartido sale a su capa; el vestido
 * no se comparte):
 *
 *   · `.cz-ax.nav*`   en `carousel.css` — el motor del carrusel (secciones,
 *                     testimonios), con sus velos y su apilado.
 *   · `.ax-move.nav*` en `grid-fx.css` — el visor del motor de rejilla, que
 *                     quiere el MISMO paso sin heredar nada de la otra pieza.
 *
 * ── LA DURACIÓN, EN UN SOLO SITIO ─────────────────────────────────────────
 *
 * `--cz-ax-dur` la leen las cuatro animaciones **y el JS** (`motion.js` la saca
 * del CSS en vez de llevar su propio número, y `grid-fx-boot.js` hace lo mismo).
 * Cambiarla aquí lo cambia todo a la vez. Antes de eso, un motor esperaba
 * `animationend` y soltaba su candado a los 30 ms: el paso era un salto.
 *
 * 🚨 **Quien encole `carousel.css` tiene que encolar también esta hoja.** Un
 * consumidor que se la deje pierde el efecto **en silencio** —una `animation:`
 * que apunta a un keyframe ausente no hace nada y no da un solo error, que es
 * literalmente lo que pasó aquí— y por eso lo vigila
 * `tests/App/View/MotionVocabularyIsEnqueuedTest`.
 * ══════════════════════════════════════════════════════════════════════════ */

/* 🔴 **AQUÍ VIVEN LOS KEYFRAMES Y NADA MÁS, y es una CORRECCIÓN del primer
   intento de esta misma hoja, hecha el mismo día.** La primera versión se trajo
   también las cuatro reglas que los invocan (`.cz-ax.navOutNext { animation: … }`
   y sus gemelas para el visor), y eso parecía más DRY pero rompía dos cosas:

     · **cada pieza perdía su vestido.** El `z-index` con el que el carrusel apila
       la que sale sobre la que entra es decisión de SU diseño, no del movimiento
       — mezclarlos es lo que Adán paró cuando una sesión declaró `carousel.css`
       entera en el visor: *«el carousel también mueve los testimonials»*.
     · **y dejaba al guard sin nada que vigilar.** Si la invocación y la
       definición acaban en la MISMA hoja, `MotionVocabularyIsEnqueuedTest` no
       tiene ningún cruce que comprobar: se verificó MUTANDO —quitando esta hoja
       de un consumidor— y el guard **seguía en verde**. Un detector que no se
       pone rojo con el defecto puesto no vale.

   ✅ Así que el reparto es: **los keyframes aquí** (vocabulario puro, una sola
   definición) y **las reglas que los invocan en la hoja de cada pieza**, con su
   `z-index` y su duración. Entonces cada hoja INVOCA lo que no DEFINE, y el
   guard exige que las dos viajen juntas a la página. */

/* 🔴 EL `from` ES OBLIGATORIO, y su ausencia es la causa de que el zoom-out
   «no se vea». Sin `from`, una animacion parte del valor COMPUTADO — y el
   `_goTo` del motor ya ha escrito `opacity: 0` en linea sobre la copia que sale,
   asi que la animacion iba **de 0 a 0**: la foto se escalaba invisible y el paso
   se percibia como un cambio seco de imagen.
   📐 Medido en produccion el 2026-10-12: `czScaleHalfDownX` corriendo con
   `opacity: 0.00` durante toda la ventana. Lo reporto Adan —*«pulsas next/prev y
   solo cambia de imagen, no hay efecto»*— y mi sonda daba VERDE, porque medir
   que la animacion CORRE no es medir que el efecto SE VE.
   🔁 **Y ya se habia descubierto el 2026-10-11** (commit `af18e653`, *«el
   zoom-out necesita un `from` explicito — la foto que salia nacia invisible»*):
   aquel dia se resolvio creando un keyframe gemelo, `czAxGhostOutX`, y el revert
   `1912488e` lo retiro con los demas «keyframes inventados». Ese no lo era.
   ⚖️ Se arregla AQUI y no con un gemelo: el `from` es el estado del que el
   carrusel parte de todas formas (`.cz-ax.is-on` ya esta en `opacity: 1`), asi
   que una definicion sirve a los dos y no hay dos nombres para un movimiento. */
@keyframes czScaleHalfDownX   { from { opacity: 1; transform: scale(1); } to { transform: scale(.6); opacity: 0; } }
@keyframes czSlideInFromLeftX { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes czSlideOutToLeftX  { to   { transform: translateX(-100%); } }
@keyframes czScaleHalfUpX     { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }

/* Quien pide no moverse no se mueve, y ve la foto que toca. Va aquí porque
   acompaña al vocabulario: desactiva las animaciones que esta hoja define, sea
   quien sea la pieza que las invoque. */
@media (prefers-reduced-motion: reduce) {
    .cz-ax,
    .ax-move { animation: none !important; opacity: 1; }
}
