/*
 * TRANSICIONES DE NAVEGACIÓN
 * ==========================
 *
 * El gesto único del sitio —el barrido de izquierda a derecha, la lanzadera del
 * telar— deja de terminarse en el borde de la página y pasa a cruzar de una
 * página a la siguiente. Ir de la portada a una ficha deja de ser un corte y
 * pasa a ser una pasada más del telar.
 *
 * NATIVAS, ENTRE DOCUMENTOS. No es el `<ClientRouter />` de Astro.
 *
 * Esa es una decisión, no un descuido. El ClientRouter monta un enrutador en el
 * cliente: intercepta los clics, trae el HTML por fetch y sustituye el <body>.
 * Funciona, y cuesta JavaScript, un ciclo de vida propio y un punto donde se
 * rompen los scripts que asumen una carga de documento —que aquí son todos:
 * motion.js, regulador.js, vapor.js y splash.js montan al cargar—.
 *
 * `@view-transition { navigation: auto }` lo hace el navegador, en una
 * navegación de documento normal, con CERO bytes de JavaScript. Y cuando no hay
 * soporte —hoy, Firefox y Safari— la regla entera se ignora y la navegación es
 * la de siempre. No hay degradación que programar: no hay nada que degradar.
 *
 * Coste real de este fichero: lo que pese comprimido. Nada en tiempo de
 * ejecución, nada en el hilo principal, ningún `requestAnimationFrame`. El
 * único latido del sitio sigue siendo el de motion.js.
 */

@view-transition {
	navigation: auto;
	types: tejer;
}

/*
 * EL BARRIDO.
 *
 * Por defecto el navegador hace un fundido cruzado entre las dos páginas. Un
 * fundido es exactamente el gesto que CLAUDE.md prohíbe: «si aparece la
 * tentación de un segundo gesto —un desvanecido, una diagonal, un
 * deslizamiento—, no entra».
 *
 * Así que se sustituye. La página que se va se deshila por la derecha; la que
 * llega se teje desde la izquierda. Es el mismo `clip-path: inset()` que usan
 * los peldaños de la entrada y el revelado de sección: una sola familia de
 * movimiento en todo el sitio.
 */

@keyframes tejer-entrada {
	from {
		clip-path: inset(0 100% 0 0);
	}
	to {
		clip-path: inset(0 0 0 0);
	}
}

@keyframes deshilar-salida {
	from {
		clip-path: inset(0 0 0 0);
	}
	to {
		clip-path: inset(0 0 0 100%);
	}
}

/*
 * 126 · P1 «NIEBLA QUE PASA». La página que se va se disuelve en vapor azul
 * (desenfoque + velo añil, sube un poco); la que llega amanece un paso más
 * clara (sale de un brillo bajo hacia el suyo). Un hilo de luz dorado cruza
 * la pantalla en 600 ms (grupo «hilo», ver más abajo). Sin JS.
 */
@keyframes niebla-salida {
	0% { opacity: 1; filter: blur(0) brightness(1) saturate(1); transform: translateY(0); }
	100% { opacity: 0; filter: blur(14px) brightness(.72) saturate(.6); transform: translateY(-2.5vh); }
}
@keyframes alba-entrada {
	0% { opacity: 0; filter: blur(10px) brightness(.62) saturate(.7); transform: translateY(1.5vh); }
	55% { opacity: 1; }
	100% { opacity: 1; filter: blur(0) brightness(1) saturate(1); transform: translateY(0); }
}
::view-transition { background: #1f2538; }
::view-transition-old(root) {
	mix-blend-mode: normal;
	animation: niebla-salida 0.52s cubic-bezier(0.4, 0, 0.6, 1) both;
}
::view-transition-new(root) {
	mix-blend-mode: normal;
	animation: alba-entrada 0.82s cubic-bezier(0.22, 1, 0.36, 1) 0.14s both;
}

/* El hilo: un elemento fijo que sólo existe durante la transición. */
.vt-hilo { display: none; }
html:active-view-transition .vt-hilo {
	display: block; position: fixed; left: calc(50% - 1px); top: 0; width: 1.5px; height: 100vh; pointer-events: none; /* 137 · el hilo de la carretera: sale por abajo de una página y entra por arriba en la siguiente */
	background: linear-gradient(180deg, transparent, rgba(225,173,102,.0) 10%, #f3d29a 60%, #fff3d6 92%, transparent);
	filter: drop-shadow(0 0 6px rgba(243,210,154,.8));
	view-transition-name: hilo;
}
@keyframes hilo-cruza {
	0% { transform: translateY(-100%) scaleX(.6); opacity: 0; }
	15% { opacity: 1; }
	85% { opacity: 1; }
	100% { transform: translateY(100%) scaleX(1); opacity: 0; }
}
::view-transition-old(hilo) { display: none; }
::view-transition-new(hilo) { animation: hilo-cruza 0.9s cubic-bezier(0.45, 0, 0.2, 1) 0.08s both; }
::view-transition-group(hilo) { animation: none; z-index: 10; }

/*
 * LA MARCA NO PARPADEA.
 *
 * «Fifí de Pueblo · Cacahoatán · Chiapas» está en el mismo sitio en todas las
 * páginas. Sin nombre propio se iría con la página vieja y volvería con la
 * nueva: un parpadeo de la firma en cada clic, que es justo lo contrario de una
 * firma. Con nombre propio el navegador la reconoce como el MISMO elemento y la
 * deja quieta mientras todo lo demás cruza.
 *
 * Es el ancla de la navegación: lo único que no se mueve.
 */
.marca {
	view-transition-name: marca;
}

body[data-editorial]:not([data-ruta^="/chat"]):not([data-ruta^="/admin"]) nav.claro,
body[data-editorial]:not([data-ruta^="/chat"]):not([data-ruta^="/admin"]) nav.oscuro {
	view-transition-name: masthead;
}

html:active-view-transition-type(tejer)::view-transition-group(masthead) {
	animation: none;
}

body[data-editorial]:not([data-ruta^="/chat"]):not([data-ruta^="/admin"]) .cabecera h1 {
	view-transition-name: cabecera;
}

html:active-view-transition-type(tejer)::view-transition-group(cabecera) {
	animation: none;
}

html:active-view-transition-type(tejer)::view-transition-old(cabecera) {
	mix-blend-mode: normal;
	height: 100%;
	object-fit: none;
	object-position: left top;
	animation: niebla-salida 0.52s cubic-bezier(0.4, 0, 0.6, 1) both;
}

html:active-view-transition-type(tejer)::view-transition-new(cabecera) {
	mix-blend-mode: normal;
	height: 100%;
	object-fit: none;
	object-position: left top;
	animation: alba-entrada 0.82s cubic-bezier(0.22, 1, 0.36, 1) 0.14s both;
}

/*
 * LA FOTOGRAFÍA VIAJA.
 *
 * Éste es el motivo real de montar todo esto. La tarjeta de un lugar en
 * /lugares y la portada de su ficha son la misma fotografía en dos tamaños. Con
 * el mismo `view-transition-name` en las dos, el navegador no hace dos
 * animaciones: interpola UNA, de la tarjeta al hero. La fotografía no aparece
 * en la ficha — llega a ella.
 *
 * El nombre lo pone cada página con `style` porque tiene que ser único por
 * lugar y ESTAR UNA SOLA VEZ POR DOCUMENTO. Dos elementos con el mismo nombre
 * anulan la transición entera, sin error en consola. Por eso el bloque de
 * cercanos al pie de una ficha —que reusa la misma tarjeta— no lo lleva: la
 * ficha ya gastó ese nombre en su hero.
 *
 * Duración algo mayor que el barrido: la fotografía es el sujeto, y el sujeto
 * llega el último.
 */
::view-transition-group(foto-*) {
	animation-duration: 0.9s;
	animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/*
 * Sin recorte durante el cruce. El `contain` que llevan algunas bandas del
 * sitio recortaría el grupo mientras vuela entre las dos maquetas.
 */
::view-transition-image-pair(*) {
	isolation: auto;
}

/*
 * REDUCED MOTION.
 *
 * No se desactivan las transiciones: se dejan instantáneas. Desactivarlas del
 * todo devolvería el fundido cruzado por defecto del navegador, que es
 * movimiento igualmente. Un cruce de 1 ms es, en la práctica, un corte limpio.
 */
@media (prefers-reduced-motion: reduce) {
	::view-transition-group(*),
	::view-transition-old(*),
	::view-transition-new(*) {
		animation-duration: 1ms !important;
		animation-delay: 0s !important;
	}
	html:active-view-transition .vt-hilo { display: none; }
	::view-transition { background: none; }
}
