/* Efecto «persist» (Mati, 10/11): el estanque sigue entre páginas. Lo guarda y restaura fx/persist.js; acá, la
   coreografía de la transición entre documentos. Todo bajo html.fx-persist: apagado (?off=persist), queda el fundido
   de site.css. Con movimiento reducido site.css apaga la transición y persist.js no marca la llegada. */

/* La raíz cruza con curvas complementarias (lo que baja la vieja lo sube la nueva) y suma con plus-lighter: lo que es
   igual en las dos páginas (koi, barra, fondo, halo) queda quieto y sólo se funde lo que cambió. El navegador aplica
   plus-lighter como animación y se pierde al pisar la animación de la raíz: hay que reponerlo. El contenido viejo se va
   con este fundido corto; el nuevo entra aparte (koi-arrive). */
html.fx-persist::view-transition-old(root),
html.fx-persist::view-transition-new(root) { animation-duration: .16s; animation-delay: 0s; animation-timing-function: cubic-bezier(.4, 0, .2, 1); animation-fill-mode: both; mix-blend-mode: plus-lighter; }
html.fx-persist::view-transition-old(root) { animation-name: koi-persist-out; }
html.fx-persist::view-transition-new(root) { animation-name: koi-persist-in; }
@keyframes koi-persist-out { to { opacity: 0; } }
@keyframes koi-persist-in { from { opacity: 0; } }

/* Llegada: el texto del héroe entra con opacidad y una subida corta, después de que el viejo se fue. La opacidad nunca
   va en un ancestro de algo con vidrio (el halo, los botones): lo volvería "backdrop root" y dejaría de desenfocar los
   koi; por eso se animan los botones y no .ctas, y el halo no se toca. La miga tampoco: es donde aterriza el nombre.
   Las secciones siguientes (los logos del portfolio, el texto de privacidad) entran igual, enteras: el vidrio que tienen
   adentro queda más abajo, fuera de la primera pantalla, y vuelve a desenfocar al quitarse la clase (persist.js). */
html.fx-persist.koi-arrive .hero .inner > :not(.crumb):not(.ctas),
html.fx-persist.koi-arrive .hero .inner > .ctas > *,
html.fx-persist.koi-arrive main.page > :not(.hero) { animation: koi-persist-arrive .46s cubic-bezier(.16, 1, .3, 1) .08s both; }
@keyframes koi-persist-arrive { from { opacity: 0; transform: translateY(10px); } }

/* El nombre que viaja (título de la fila o tarjeta, ítem del menú, link de la barra o del pie → último tramo de la miga).
   Los dos textos tienen tamaño y peso muy distintos: cada imagen llena el alto del grupo y conserva su proporción
   (ancho automático, centrada), así el texto se achica sin estirarse; la vieja se va antes de que la nueva aparezca. */
html.fx-persist .koi-vt-text { display: inline-block; text-shadow: none; } /* sin el velo del texto: viaja sobre otro fondo */
html.fx-persist::view-transition-group(koi-name) { animation-duration: .38s; animation-timing-function: cubic-bezier(.16, 1, .3, 1); }
html.fx-persist::view-transition-old(koi-name),
html.fx-persist::view-transition-new(koi-name) { block-size: 100%; inline-size: auto; inset-inline-start: 50%; translate: -50% 0; mix-blend-mode: normal; }
html.fx-persist::view-transition-old(koi-name) { animation: koi-persist-out .16s cubic-bezier(.4, 0, 1, 1) both; }
html.fx-persist::view-transition-new(koi-name) { animation: koi-persist-in .26s cubic-bezier(.16, 1, .3, 1) .1s both; }

/* barra que no se vuelve a abrir al llegar desde el sitio (persist.js la deja abierta sin transición) */
html.fx-persist .pill.koi-still, html.fx-persist .pill.koi-still * { transition: none !important; }

@media (prefers-reduced-motion: reduce) {
  html.fx-persist.koi-arrive .hero .inner > *, html.fx-persist.koi-arrive .hero .inner > .ctas > *, html.fx-persist.koi-arrive main.page > * { animation: none; }
}
