/* movimiento.css — el sistema de movimiento del panel SEIS.
 *
 * Existe por una razón medible: al 22-08 el panel del agente tenía 32
 * transiciones y las esferas 12, mientras agentes, catalogo, modelo, espejo y
 * workshop no tenían NINGUNA. Navegar entre ellas se sentía como cambiar de
 * producto.
 *
 * Se comparte entre las 7 páginas, y eso contradice el "cada archivo se basta
 * a sí mismo" de agentes.html — pero ese mismo comentario dejó escrito cuándo
 * dejaba de valer: "Si un día son cuatro, se saca". Son siete, y auth.js ya
 * cruzó esa línea antes que este archivo.
 *
 * Manda ESTILO.md, sin excepciones:
 *   · 160–220ms, `ease`. Nada más lento.
 *   · Se anima opacidad y transformación. Nunca colores de fondo ni anchos.
 *   · Nada rebota.
 * El movimiento acá no decora: dice qué cambió y de dónde vino. Si un efecto
 * no responde a eso, no entra.
 */

:root{
  --mov: 200ms;          /* el medio del rango de ESTILO.md */
  --mov-corto: 160ms;
  --mov-curva: ease;
  --mov-alza: 12px;      /* de la escala de espacio: 4·8·12·16 */
}

/* ── 1 · Navegación entre páginas ──────────────────────────────────────────
 * Cross-document View Transitions: el navegador cruza de una página a otra sin
 * el flash en blanco de la recarga. Nativo — no hay librería, no hay build, no
 * hay router. Las 7 páginas estáticas pasan a leerse como una sola superficie.
 * Donde no está soportado, la navegación es exactamente la de hoy: no hay
 * degradación que manejar, la regla simplemente no aplica. */
@view-transition{ navigation: auto }

/* La marca y el "← volver" son idénticos en las 5 páginas de contenido. Con
 * nombre propio el navegador los reconoce como el MISMO objeto entre páginas y
 * los deja quietos, en vez de desvanecerlos y volverlos a dibujar. Es lo que
 * hace que se lea como un cambio de contenido y no como un cambio de sitio. */
.marca { view-transition-name: marca }
.volver{ view-transition-name: volver }
.tema  { view-transition-name: tema }

/* El título sí cambia entre páginas: sube un poco al entrar y baja al salir,
 * en la dirección en que avanza la lectura.
 *
 * ⚠️ Va acotado al <h1> de la hoja, NO a `h1` a secas. Un nombre de transición
 * tiene que ser único en el documento: si dos elementos lo comparten, el
 * navegador aborta la transición ENTERA, en silencio. Pasó el 22-08 — el
 * overlay de acceso de auth.js también traía un <h1> y con eso ninguna
 * transición podía correr. Ese título ya no es un h1, y esta regla además
 * no lo alcanzaría. */
.hoja > h1,
.hoja header h1{ view-transition-name: titulo }

::view-transition-old(root),
::view-transition-new(root){
  animation-duration: var(--mov);
  animation-timing-function: var(--mov-curva);
}
::view-transition-old(titulo){
  animation: sale-titulo var(--mov-corto) var(--mov-curva) both;
}
::view-transition-new(titulo){
  animation: entra-titulo var(--mov) var(--mov-curva) both;
}
@keyframes sale-titulo{  to  { opacity:0; transform:translateY(calc(var(--mov-alza) * -.5)) } }
@keyframes entra-titulo{ from{ opacity:0; transform:translateY(var(--mov-alza)) } }

/* Los objetos con nombre propio no se animan: se quedan. Sin esto el navegador
 * les aplica el cruce por defecto y el efecto se pierde. */
::view-transition-group(marca),
::view-transition-group(volver),
::view-transition-group(tema){ animation-duration: var(--mov) }

/* ── 2 · Revelado al entrar en pantalla ────────────────────────────────────
 * `animation-timeline: view()` ata la animación a la posición del elemento en
 * el viewport. Lo resuelve el compositor: no hay listener de scroll, no hay
 * IntersectionObserver, no hay reflow. Es el reemplazo nativo de lo que antes
 * pedía GSAP + ScrollTrigger.
 *
 * `both` importa: sin él, lo que ya está en pantalla al cargar arranca en
 * opacidad 0 y se queda invisible hasta que el usuario mueva algo. */
@supports (animation-timeline: view()){
  .aparece,
  /* Las secciones de las páginas-documento (modelo, espejo, catálogo).
   * Se ataca por estructura y no por una clase nueva para no tocar el HTML:
   * index.html no usa <section> en ninguna parte, así que esta regla no
   * puede alcanzarlo por accidente. */
  .hoja section,
  /* Las fichas del catálogo, que las pinta JavaScript al leer el repositorio.
   * ⚠️ La planilla de `agentes.html` NO entra acá, por dos razones: un <tr> es
   * `display:table-row` y no es un sujeto confiable para `view()`, y 27 filas
   * revelándose uno tras otro se leen como una ola que marea. Esa página se
   * anima como bloque, no fila por fila. */
  .hoja .skill{
    animation: aparece linear both;
    animation-timeline: view();
    /* El rango va de "asoma por abajo" a "terminó de asomar", las dos marcas
     * de la MISMA fase. Mezclar fases (`entry` con `cover`) parece más fino
     * pero se rompe: en una pantalla baja —o con un bloque más alto que la
     * pantalla— el final resuelve antes que el principio, el rango colapsa y
     * el elemento se queda pegado en su estado final. Medido acá con una
     * ventana de 357px: las seis secciones quedaban reveladas de entrada. */
    animation-range: entry 0% entry 100%;
  }
}
@keyframes aparece{
  from{ opacity:0; transform:translateY(var(--mov-alza)) }
  to  { opacity:1; transform:none }
}

/* ── 3 · Estados de interfaz ───────────────────────────────────────────────
 * Lo que se toca responde. Transformación y opacidad, nada más. */
.volver{ transition: opacity var(--mov-corto) var(--mov-curva),
                     transform var(--mov-corto) var(--mov-curva) }
.volver:hover{ transform: translateX(-3px) }

/* ── 4 · Quien pidió no moverse, no se mueve ───────────────────────────────
 * ESTILO.md ya lo exigía para la traza. Acá vale para todo, y de verdad: se
 * apaga el movimiento, no se acorta. Incluye la transición entre páginas. */
@media (prefers-reduced-motion: reduce){
  @view-transition{ navigation: none }
  .aparece{ animation: none; opacity:1; transform:none }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
