/**
 * ZIHOUSE · SISTEMA DE REVEAL
 *
 * DE DÓNDE SALE
 * -------------
 * La técnica está tomada de una referencia de ejecución muy alta, pero NO su
 * lenguaje. Allí el reveal es tecnológico: glitch, escaneo, neón. Aquí es
 * editorial: una línea de texto que sube desde debajo de su propia máscara,
 * como el papel al pasar de página. Misma mecánica, intención opuesta.
 *
 * Lo que se ha conservado de la referencia es lo que la hace funcionar:
 *
 *   - envoltorio con `overflow: hidden` y `contain: paint`
 *   - el contenido entra desplazado un 105%, no un 100%: el 5% extra garantiza
 *     que ni un píxel del trazo asome antes de tiempo, sobre todo en itálicas y
 *     en fuentes con descendentes largos
 *   - una inclinación mínima en X, que da volumen sin que se lea como 3D
 *   - escalonado corto entre líneas
 *   - curva ease-out muy pronunciada
 *
 * TODO EN CSS
 * -----------
 * El movimiento vive en CSS y lo dispara una clase que pone el JavaScript al
 * entrar en pantalla. Ventajas sobre animarlo desde JavaScript: lo mueve el
 * compositor y no el hilo principal, sigue funcionando si el script falla, y no
 * compite con los efectos de scroll del hero, que es justo lo que saturaba el
 * hilo en esta web.
 *
 * SIN JAVASCRIPT NO SE ROMPE NADA
 * -------------------------------
 * El contenido es visible por defecto. Solo se esconde cuando el script ha
 * confirmado que puede animarlo, marcando el documento. Así, si el JavaScript
 * no llega, el visitante lee la página entera igualmente.
 *
 * @package ZIHOUSE
 */

/* ══════════════════════════════════════════════════════════════════════════
   1 · ESTADO INICIAL
   Solo se aplica cuando el script ha marcado el documento como capaz.
   ══════════════════════════════════════════════════════════════════════════ */

.zi-motion [data-zi-reveal]:not(.is-revealed) {
	--zi-d: var(--zi-reveal-duration);
	--zi-e: var(--zi-reveal-ease);
}

/* --- Máscara: el envoltorio recorta, el contenido se desliza --- */
.zi-mask {
	display: block;
	overflow: hidden;
	/* Aísla el repintado del recorte: el navegador no revisa el resto. */
	contain: paint;
}

.zi-mask__inner {
	display: block;
	transform-origin: 50% 100%;
	will-change: transform;
}

.zi-motion .zi-mask:not(.is-revealed) .zi-mask__inner {
	transform: translate3d(0, var(--zi-reveal-shift), 0) rotateX(var(--zi-reveal-tilt));
	opacity: 0;
}

.zi-mask.is-revealed .zi-mask__inner {
	transform: translate3d(0, 0, 0) rotateX(0deg);
	opacity: 1;
	transition:
		transform var(--zi-reveal-duration) var(--zi-reveal-ease) var(--zi-delay, 0ms),
		opacity calc(var(--zi-reveal-duration) * 0.55) linear var(--zi-delay, 0ms);
}

/* La perspectiva va en el padre para que la inclinación tenga profundidad real.
   Sin ella, rotateX aplana el texto en vez de inclinarlo. */
.zi-motion [data-zi-reveal="heading"],
.zi-motion [data-zi-reveal="lines"] {
	perspective: 1000px;
}

/* ══════════════════════════════════════════════════════════════════════════
   2 · TEXTOS SIN MÁSCARA
   Para párrafos y metadatos. Un desplazamiento corto y opacidad: no hace falta
   recortar nada porque el gesto es mucho más discreto.
   ══════════════════════════════════════════════════════════════════════════ */

.zi-motion [data-zi-reveal="fade"]:not(.is-revealed),
.zi-motion [data-zi-reveal="words"]:not(.is-revealed) .zi-word {
	opacity: 0;
	transform: translate3d(0, var(--zi-reveal-lift), 0);
}

.zi-motion [data-zi-reveal="fade"].is-revealed,
.zi-motion [data-zi-reveal="words"].is-revealed .zi-word {
	opacity: 1;
	transform: translate3d(0, 0, 0);
	transition:
		transform var(--zi-reveal-duration-short) var(--zi-reveal-ease) var(--zi-delay, 0ms),
		opacity var(--zi-reveal-duration-short) var(--zi-reveal-ease) var(--zi-delay, 0ms);
}

.zi-word {
	display: inline-block;
	/* El espacio entre palabras lo pone el JavaScript como nodo aparte, así el
	   texto se sigue pudiendo seleccionar y copiar con normalidad. */
	will-change: transform;
}

/* ══════════════════════════════════════════════════════════════════════════
   3 · IMÁGENES EDITORIALES
   Cortina que abre de izquierda a derecha mientras la foto se posa desde un
   escalado ligeramente mayor. Solo para piezas grandes: en una miniatura este
   gesto no se aprecia y solo cuesta rendimiento.
   ══════════════════════════════════════════════════════════════════════════ */

.zi-motion [data-zi-reveal="image"] {
	overflow: hidden;
}

.zi-motion [data-zi-reveal="image"]:not(.is-revealed) {
	clip-path: inset(0 100% 0 0);
}

.zi-motion [data-zi-reveal="image"]:not(.is-revealed) img {
	transform: scale(1.035);
}

.zi-motion [data-zi-reveal="image"].is-revealed {
	clip-path: inset(0 0 0 0);
	transition: clip-path var(--zi-reveal-duration) var(--zi-reveal-ease) var(--zi-delay, 0ms);
}

.zi-motion [data-zi-reveal="image"].is-revealed img {
	transform: scale(1);
	transition: transform calc(var(--zi-reveal-duration) * 1.15) var(--zi-reveal-ease) var(--zi-delay, 0ms);
}

/* ══════════════════════════════════════════════════════════════════════════
   4 · REJILLAS
   Escalonado mínimo. Por debajo de 80ms el ojo lo lee como un solo gesto con
   cuerpo; por encima, como una lista que va cargando. Queremos lo primero.
   ══════════════════════════════════════════════════════════════════════════ */

.zi-motion [data-zi-reveal="stagger"] > * {
	opacity: 0;
	transform: translate3d(0, 18px, 0);
}

.zi-motion [data-zi-reveal="stagger"].is-revealed > * {
	opacity: 1;
	transform: translate3d(0, 0, 0);
	transition:
		transform var(--zi-reveal-duration-short) var(--zi-reveal-ease),
		opacity var(--zi-reveal-duration-short) var(--zi-reveal-ease);
}

/* El retardo por posición lo escribe el JavaScript en `--zi-delay` de cada hijo;
   estas reglas son la red de seguridad para las primeras doce tarjetas. */
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(1)  { transition-delay: 0ms; }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(2)  { transition-delay: calc(var(--zi-reveal-stagger) * 1); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(3)  { transition-delay: calc(var(--zi-reveal-stagger) * 2); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(4)  { transition-delay: calc(var(--zi-reveal-stagger) * 3); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(5)  { transition-delay: calc(var(--zi-reveal-stagger) * 4); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(6)  { transition-delay: calc(var(--zi-reveal-stagger) * 5); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(7)  { transition-delay: calc(var(--zi-reveal-stagger) * 6); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(8)  { transition-delay: calc(var(--zi-reveal-stagger) * 7); }
.zi-motion [data-zi-reveal="stagger"].is-revealed > *:nth-child(n+9) { transition-delay: calc(var(--zi-reveal-stagger) * 8); }

/* ══════════════════════════════════════════════════════════════════════════
   5 · PANEL LATERAL DEL CARRITO
   El panel ya entra desde la derecha por su propia hoja. Aquí solo el contenido
   interno, que aparece escalonado una vez el panel está en su sitio.
   ══════════════════════════════════════════════════════════════════════════ */

.zi-motion .zihouse-drawer[data-open="true"] .cart_list li,
.zi-motion .zihouse-drawer[data-open="true"] .woocommerce-mini-cart__total,
.zi-motion .zihouse-drawer[data-open="true"] .zihouse-suggest,
.zi-motion .zihouse-drawer[data-open="true"] .woocommerce-mini-cart__buttons {
	animation: zi-drawer-in var(--zi-reveal-duration-short) var(--zi-reveal-ease) both;
}

.zi-motion .zihouse-drawer[data-open="true"] .cart_list li:nth-child(2) { animation-delay: 40ms; }
.zi-motion .zihouse-drawer[data-open="true"] .cart_list li:nth-child(3) { animation-delay: 80ms; }
.zi-motion .zihouse-drawer[data-open="true"] .cart_list li:nth-child(n+4) { animation-delay: 110ms; }
.zi-motion .zihouse-drawer[data-open="true"] .woocommerce-mini-cart__total { animation-delay: 130ms; }
.zi-motion .zihouse-drawer[data-open="true"] .zihouse-suggest { animation-delay: 170ms; }
.zi-motion .zihouse-drawer[data-open="true"] .woocommerce-mini-cart__buttons { animation-delay: 200ms; }

@keyframes zi-drawer-in {
	from { opacity: 0; transform: translate3d(0, 12px, 0); }
	to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* ══════════════════════════════════════════════════════════════════════════
   6 · LÍMITES
   ══════════════════════════════════════════════════════════════════════════ */

/* En el checkout el movimiento estorba: el visitante está rellenando datos. Se
   permite la aparición de las cabeceras de sección y nada más. */
.woocommerce-checkout .zi-motion [data-zi-reveal="stagger"] > *,
.woocommerce-checkout [data-zi-reveal="image"],
.woocommerce-checkout [data-zi-reveal="words"] .zi-word {
	opacity: 1 !important;
	transform: none !important;
	clip-path: none !important;
}

@media (prefers-reduced-motion: reduce) {
	.zi-motion [data-zi-reveal],
	.zi-motion [data-zi-reveal] *,
	.zi-mask__inner,
	.zi-word {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
		transition: none !important;
		animation: none !important;
	}
}

/* ══════════════════════════════════════════════════════════════════════════
   7 · SALIDA DE PÁGINA
   Solo el contenido se atenúa. La cabecera se queda quieta a propósito: es lo
   único que sobrevive de una página a la siguiente, y verla parpadear en cada
   clic da sensación de recarga completa, que es justo lo que se quiere disimular.
   ══════════════════════════════════════════════════════════════════════════ */

.zihouse-main,
main {
	transition: opacity var(--zi-leave-duration, 140ms) linear;
}

.zi-leaving .zihouse-main,
.zi-leaving main {
	opacity: 0.35;
}

/* El cursor pasa a "esperando" mientras tanto: el visitante sabe que su clic se
   ha registrado y no vuelve a pulsar. */
.zi-leaving {
	cursor: progress;
}

@media (prefers-reduced-motion: reduce) {
	.zihouse-main,
	main { transition: none; }
	.zi-leaving .zihouse-main,
	.zi-leaving main { opacity: 1; }
}
