/* ==========================================================================
   Movimiento Estratégico

   Dos materiales para una sola idea —el movimiento sólo significa algo cuando
   tiene trayectoria—: el hero lo dice con LUZ sobre negro y el cuerpo lo dice
   con TINTA sobre blanco.

   Nada de lo que hay aquí decide si un contenido se ve. Los estados ocultos
   viven todos bajo .mov--anim, la clase que pone el JS al arrancar, y el hero
   arranca siendo una imagen normal que se ve sin ayuda de nadie.
   ========================================================================== */

/* Registradas para poder interpolarlas; sin registrar, saltan. */
@property --mov-iny { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --mov-corte { syntax: "<percentage>"; inherits: false; initial-value: 0%; }

/* --------------------------------------------------------------------------
   EL HERO
   -------------------------------------------------------------------------- */
.mov-hero {
	position: relative;
	--mov-salida: 0;
	isolation: isolate;
	overflow: hidden;
	min-height: clamp(600px, 96vh, 1000px);
	display: flex;
	align-items: center;
	justify-content: flex-start;
	margin-inline: calc(50% - 50vw);
	width: 100vw;
	max-width: 100vw;
	padding: clamp(90px, 12vh, 150px) clamp(24px, 6vw, 104px) clamp(60px, 8vh, 100px);
	background: #000;
	color: #F7F5F0;
}

/* La primera vista y el lienzo ocupan el mismo sitio. La imagen es el suelo;
   el lienzo se pone encima y sólo se hace cargo cuando ya ha pintado. */
.mov-hero__torno,
.mov-hero__base {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	pointer-events: none;
}

/* La lámina de reposo. Se encuadra IGUAL que la dibuja el lienzo —recorte de
   torso, anclada a la derecha— para que al relevarse no haya salto: no ocupa
   el ancho del hero sino su propia caja a la derecha, y dentro de ella recorta
   por arriba.

   Esto no es un detalle del estado de carga: es lo que ve todo el que llega
   con movimiento reducido o desde el móvil, donde el torno no corre. */
.mov-hero__base {
	/* La misma geometría que calcula el lienzo, escrita en CSS: ancho fijo,
	   alto por proporción y desplazada 21 % hacia abajo, que es donde deja la
	   coronilla al 28 % del alto del hero.

	   Con `object-fit: cover` no había manera: la lámina sólo mide 1374 px
	   escalada contra una caja de 912, y `object-position` no puede EMPUJARLA
	   hacia abajo — sólo elige qué parte se recorta. Por eso va con `top` y el
	   alto en automático, y lo que sobra lo recorta el `overflow` del hero. */
	left: auto;
	right: -4%;
	top: 21%;
	bottom: auto;
	/* 79 % = 72 % x 1,10: el mismo 10 % que creció el lienzo, para que al
	   relevarse no haya salto de tamaño. */
	width: min(79%, 1210px);
	height: auto;
	transition: opacity 900ms ease;
}

.mov-hero__torno { opacity: 0; transition: opacity 900ms ease; }

/* La clase la pone el JS DESPUÉS de pintar su primer fotograma: hasta ese
   momento manda la imagen. Así, si el script falla, no desaparece nada. */
.mov-hero.es-torno .mov-hero__torno { opacity: 1; }
.mov-hero.es-torno .mov-hero__base { opacity: 0; }

/* La pista del gesto. Un efecto que se gobierna con el ratón no se descubre
   solo; y en cuanto se usa, sobra. */
.mov-hero__pista {
	position: absolute;
	z-index: 2;
	left: clamp(24px, 6vw, 104px);
	bottom: clamp(52px, 7vh, 78px);
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: 0.66rem;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: rgba(201, 185, 143, 0.72);
	transition: opacity 620ms ease, transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
}

.mov-hero__pista.es-ido { opacity: 0; transform: translateY(8px); }

@media (hover: none), (pointer: coarse) { .mov-hero__pista { display: none; } }

/* Los cuatro bordes al mismo negro de las láminas: la escena deja de leerse como un
   rectángulo pegado sobre el fondo. Y una caída más densa abajo, que es donde
   la página tiene que entregar el paso al blanco. */
.mov-hero__fundido {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	/* El velo de arriba baja de 0,92 a 0,55 y se cierra antes.

	   Con 0,92 hasta el 22 % del alto, la cabeza de la figura —que ahora vive
	   al 28 %— entraba en la parte densa y se veía cortada. No hacía falta
	   tanto: el velo está para que el encabezado fijo tenga sobre qué
	   apoyarse, y para eso basta con la franja del propio encabezado. */
	background:
		radial-gradient(126% 96% at 50% 46%, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, 0.5) 80%, #000 100%),
		linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 13%, rgba(0, 0, 0, 0) 64%, #000 100%);
}

/* EL GRANO.

   Una trama finísima sobre el hero entero. Sobre negro, los degradados largos
   —el halo de la figura, el velo de los bordes— se escalonan en bandas
   visibles porque en ocho bits no hay valores intermedios suficientes; el
   grano las rompe. Al 3,5 % no se lee como textura, se nota como material, y
   es lo mismo que ya hace el cuerpo de Nutrición. */
.mov-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	opacity: 0.035;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* La salida del hero. El JS escribe --mov-salida (0 arriba del todo, 1
   cuando el hero ya se ha ido) y aquí se usa para que el texto se despida
   con la figura en vez de limitarse a desaparecer por el borde. Sin JS vale
   0 y el contenido se queda quieto, entero y legible. */
.mov-hero__contenido {
	position: relative;
	z-index: 2;
	/* A la IZQUIERDA, no centrado. La figura vive anclada a la derecha del
	   cuadro —así la encajan tanto la lámina de reposo como el lienzo—, así que
	   centrar el texto lo pondría justo encima del cuerpo. Cada uno en su
	   mitad: la escena a la derecha, la voz a la izquierda. */
	width: min(680px, 54vw);
	max-width: 100%;
	margin-right: auto;
	text-align: left;
	transform: translate3d(0, calc(var(--mov-salida, 0) * -70px), 0);
	opacity: calc(1 - var(--mov-salida, 0) * 1.25);
	will-change: transform, opacity;
}

/* El velo bajo el texto.

   La figura recorre TODO el ancho del cuadro, así que tarde o temprano pasa
   por detrás del titular; medido sobre el vídeo, en algunos fotogramas el
   cuerpo cruza justo por la línea del subtítulo. No sirve apartar el texto a
   un lado —la figura también llega ahí—, y oscurecer el vídeo entero mataría
   la escena. Lo que funciona es una elipse muy difusa, centrada en el bloque
   de texto: sostiene el contraste donde hay que leer y en ningún borde se ve
   dónde empieza. */
.mov-hero__contenido::before {
	content: "";
	position: absolute;
	inset: -14% -18%;
	z-index: -1;
	pointer-events: none;
	background: radial-gradient(72% 64% at 34% 50%, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.72) 44%, rgba(0, 0, 0, 0.26) 74%, rgba(0, 0, 0, 0) 100%);
}

/* El isotipo firma la escena desde la esquina superior derecha.

   Antes encabezaba la pila de texto y ahí competía con el titular: dos cosas
   pidiendo el centro. En la esquina manda igual, deja el eje libre para el
   nombre del pilar y puede ir más grande sin estorbar.

   El `top` respeta el encabezado fijo del sitio, y sale con el resto del hero
   por el mismo --mov-salida, para que no se quede flotando sola cuando el
   texto ya se ha ido. */
.mov-hero__isotipo {
	position: absolute;
	z-index: 2;
	top: clamp(78px, 10.5vh, 128px);
	right: clamp(24px, 6vw, 104px);
	display: block;
	width: clamp(64px, 6.2vw, 104px);
	height: auto;
	margin: 0;
	/* El isotipo es un archivo de marca y no se redibuja. Sobre negro sólo se
	   le levanta un punto el brillo para que el dorado no se apague. */
	filter: brightness(1.08);
	opacity: calc(1 - var(--mov-salida, 0) * 1.25);
	transform: translate3d(0, calc(var(--mov-salida, 0) * -40px), 0);
}

.mov-hero__eyebrow {
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: clamp(0.66rem, 0.86vw, 0.78rem);
	letter-spacing: 0.3em;
	text-transform: uppercase;
	color: rgba(201, 185, 143, 0.82);
	margin: 0 0 clamp(18px, 2.2vw, 28px);
}

.mov-hero__titulo {
	font-family: var(--font-display, Butler, serif);
	font-weight: 400;
	font-size: clamp(2.1rem, 6.4vw, 6rem);
	line-height: 0.94;
	letter-spacing: 0.015em;
	text-transform: uppercase;
	color: #F7F5F0;
	margin: 0;
	text-wrap: balance;
	overflow-wrap: break-word;
}

.mov-hero__sub {
	font-family: var(--font-display, Butler, serif);
	font-size: clamp(1.1rem, 1.9vw, 1.9rem);
	line-height: 1.34;
	color: rgba(247, 245, 240, 0.9);
	max-width: 26ch;
	margin: clamp(22px, 2.6vw, 34px) 0 0;
}

.mov-hero__kicker {
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: clamp(0.86rem, 1.02vw, 1rem);
	font-weight: 300;
	line-height: 1.6;
	/* 0,62 sobre negro da 7,4:1. Es texto pequeño y lleva las palabras que
	   tienen que encontrarse: no puede quedarse en un susurro. */
	color: rgba(247, 245, 240, 0.62);
	max-width: 42ch;
	margin: clamp(20px, 2.2vw, 28px) 0 0;
}

.mov-hero__pie {
	position: absolute;
	z-index: 2;
	left: clamp(24px, 6vw, 104px);
	bottom: clamp(20px, 3vh, 34px);
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: 0.6rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(247, 245, 240, 0.3);
}

/* ==========================================================================
   EL CUERPO — blanco

   El hero es luz sobre negro; el cuerpo es tinta sobre blanco. La misma idea
   —el movimiento sólo significa algo cuando tiene trayectoria— dicha en dos
   materiales, y el corte entre uno y otro es deliberado: al salir del hero se
   pasa página.

   LAS IMÁGENES VAN CONTENIDAS. Salen de la biblioteca del proyecto, van a
   cuatro tercios dentro de su columna y no mandan sobre la sección:
   acompañan al texto. Una imagen a sangre aquí se comería el argumento, que
   es lo que hay que leer.

   EL RITMO. Las entradas van a 620–760 ms con una salida exponencial fuerte
   (0.16, 1, 0.3, 1). Lo único que se alarga a propósito es el revelado de las
   imágenes, porque ahí el tiempo ES el efecto.
   ========================================================================== */

.mov {
	--mov-tinta: #0A0A0B;
	--mov-tinta-baja: rgba(10, 10, 11, 0.64);
	/* #85734F y no el #8A7856 de Nutrición: el rótulo pequeño va a 12,5 px y
	   sobre blanco puro aquel tono da 4,28:1, por debajo del 4,5:1 que pide AA
	   para texto pequeño. Éste da 4,60:1 y a simple vista es el mismo beige. */
	--mov-beige: #85734F;
	--mov-hilo: rgba(133, 115, 79, 0.3);
	--mov-blanco: #FFFFFF;
	--mov-e: cubic-bezier(0.16, 1, 0.3, 1);

	position: relative;
	background: var(--mov-blanco);
	color: var(--mov-tinta);
}

.mov__bleed {
	margin-inline: calc(50% - 50vw);
	width: 100vw;
	max-width: 100vw;
}

.mov__seccion {
	position: relative;
	z-index: 1;
	padding: clamp(84px, 13vh, 190px) clamp(24px, 6vw, 104px);
}

.mov__seccion--rabo { padding-top: 0; }

.mov__inner { max-width: 1400px; margin: 0 auto; }

/* --------------------------------------------------------------------------
   Las superficies que no dibujé

   Selección, cursor de texto, anillo de foco y barra de scroll vienen del
   navegador y no pertenecen a ningún sistema de diseño. Vestirlas es lo más
   barato que se puede hacer para que una página parezca construida y no
   ensamblada.
   -------------------------------------------------------------------------- */
.mov ::selection { background: rgba(133, 115, 79, 0.24); color: #0A0A0B; }
.mov-hero ::selection { background: rgba(201, 185, 143, 0.3); color: #F7F5F0; }
.mov { caret-color: var(--mov-beige); scrollbar-color: rgba(133, 115, 79, 0.55) transparent; }

.mov :focus-visible,
.mov-hero :focus-visible {
	outline: 2px solid var(--mov-beige, #85734F);
	outline-offset: 4px;
	border-radius: 2px;
}

/* --------------------------------------------------------------------------
   La trayectoria
   -------------------------------------------------------------------------- */
.mov-ruta {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	pointer-events: none;
	overflow: visible;
}

.mov-ruta path {
	fill: none;
	stroke: var(--mov-hilo);
	stroke-width: 1.4;
	stroke-linecap: round;
	stroke-linejoin: round;
	vector-effect: non-scaling-stroke;
	/* Sólo el color. El grosor no se anima: es lo único que sería una medida
	   en vez de pintura, y encima de un salto de opacidad de 2,8× no aportaba
	   nada. */
	transition: stroke 380ms ease;
}

.mov-ruta path.es-vivo { stroke: rgba(133, 115, 79, 0.85); }

/* --------------------------------------------------------------------------
   Tipografía común
   -------------------------------------------------------------------------- */
.mov__eyebrow {
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: clamp(0.68rem, 0.86vw, 0.78rem);
	letter-spacing: 0.28em;
	text-transform: uppercase;
	color: var(--mov-beige);
	margin: 0 0 clamp(20px, 2.6vw, 34px);
}

.mov__titulo {
	font-family: var(--font-display, Butler, serif);
	font-weight: 400;
	text-transform: uppercase;
	line-height: 0.96;
	letter-spacing: 0.012em;
	font-size: clamp(2rem, 5vw, 4.6rem);
	text-wrap: balance;
	margin: 0 0 clamp(28px, 3.4vw, 50px);
	color: var(--mov-tinta);
}

.mov__titulo--ancho { font-size: clamp(2.1rem, 5.6vw, 5.2rem); }
.mov__titulo--medio { font-size: clamp(1.9rem, 3.8vw, 3.4rem); }

.mov__lead {
	font-size: clamp(1.02rem, 1.26vw, 1.28rem);
	line-height: 1.68;
	font-weight: 300;
	color: var(--mov-tinta-baja);
	margin: 0 0 1.2em;
	max-width: 62ch;
}

/* --------------------------------------------------------------------------
   Qué es — una sola frase, al tamaño que le corresponde
   -------------------------------------------------------------------------- */
/* La frase de apertura va a DOS COLUMNAS: el rótulo en un raíl estrecho a la
   izquierda, como una nota al margen, y la frase ocupando el resto.

   A una sola columna con medida de 22 caracteres, la frase se quedaba en una
   tira estrecha pegada al borde izquierdo con dos tercios de pantalla vacíos a
   su derecha: no leía como una declaración de apertura, leía como un texto
   huérfano. Con el raíl, el ancho de la página queda ocupado y la medida sube
   a 30 caracteres, que sigue siendo corta para tipografía de display —que es
   como debe ser— pero ya no parece un accidente. */
.mov-que .mov__inner {
	display: grid;
	grid-template-columns: minmax(0, 0.24fr) minmax(0, 1fr);
	gap: clamp(20px, 3.4vw, 70px);
	align-items: start;
}

.mov-que .mov__eyebrow {
	margin-bottom: 0;
	padding-top: 0.75em;
}

.mov-que__frase {
	font-family: var(--font-display, Butler, serif);
	font-weight: 400;
	font-size: clamp(1.5rem, 3.1vw, 3rem);
	line-height: 1.26;
	letter-spacing: 0.004em;
	color: var(--mov-tinta);
	margin: 0;
	max-width: 30ch;
	text-wrap: pretty;
}

/* Cada palabra entra por su cuenta, con 30 ms entre una y la siguiente: a ese
   paso la frase se ESCRIBE a la velocidad a la que se lee. El JS las envuelve;
   sin él, la frase se lee entera desde el primer fotograma. */
.mov--anim .mov-que__frase .mov-pal {
	display: inline-block;
	opacity: 0;
	transform: translateY(0.38em);
	transition: opacity 620ms var(--mov-e), transform 620ms var(--mov-e);
	transition-delay: calc(var(--mov-pal-i, 0) * 30ms);
}

.mov--anim .mov-que__frase.es-visible .mov-pal { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   Cómo lo hacemos — tres estaciones

   Escalonadas, no en fila: son tres propiedades distintas del mismo plan, y
   una rejilla de rectángulos idénticos diría "tres cosas parecidas". El
   desnivel es además lo que deja sitio a los ramales de la trayectoria para
   separarse y volver a juntarse.
   -------------------------------------------------------------------------- */
.mov-estaciones {
	list-style: none;
	margin: clamp(40px, 6vw, 90px) 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(24px, 3.4vw, 56px);
	align-items: start;
}

.mov-estacion {
	position: relative;
	cursor: default;
}

.mov-estacion:nth-child(2) { margin-top: clamp(36px, 5.5vw, 96px); }
.mov-estacion:nth-child(3) { margin-top: clamp(72px, 11vw, 192px); }

/* La imagen, contenida: cuatro tercios dentro de su columna y nada más. */
.mov-estacion__foto {
	position: relative;
	margin: 0 0 clamp(22px, 2.6vw, 34px);
	aspect-ratio: 4 / 3;
	overflow: hidden;
	border-radius: 3px;
	background: rgba(133, 115, 79, 0.07);
}

.mov-estacion__foto img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* La misma corrección para las tres: es lo que las hace leerse como un
	   conjunto y no como tres imágenes de sitios distintos. */
	filter: brightness(0.97) saturate(0.9) contrast(1.04);
	transition: transform 900ms var(--mov-e);
}

.mov-estacion:hover .mov-estacion__foto img,
.mov-estacion:focus-visible .mov-estacion__foto img { transform: scale(1.03); }

.mov-estacion__nodo {
	position: absolute;
	/* Centrado sobre la esquina superior izquierda de la lámina: es el punto
	   por el que la trayectoria entra y sale de esta estación. */
	left: 0;
	top: 0;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--mov-blanco);
	box-shadow: 0 0 0 1px var(--mov-beige);
	transform: translate(-50%, -50%);
	transition: transform 620ms var(--mov-e);
}

.mov-estacion__nodo::after {
	content: "";
	position: absolute;
	inset: -9px;
	border-radius: 50%;
	background: var(--mov-beige);
	opacity: 0;
	transform: scale(0.4);
	transition: opacity 440ms ease, transform 620ms var(--mov-e);
}

.mov-estacion:hover .mov-estacion__nodo,
.mov-estacion:focus-visible .mov-estacion__nodo { transform: translate(-50%, -50%) scale(1.18); }

.mov-estacion:hover .mov-estacion__nodo::after,
.mov-estacion:focus-visible .mov-estacion__nodo::after { opacity: 0.18; transform: scale(1); }

.mov-estacion__t {
	font-family: var(--font-display, Butler, serif);
	font-weight: 400;
	font-size: clamp(1.3rem, 1.9vw, 2rem);
	line-height: 1.12;
	margin: 0 0 clamp(12px, 1.4vw, 18px);
	color: var(--mov-tinta);
	transition: transform 620ms var(--mov-e);
}

.mov-estacion:hover .mov-estacion__t,
.mov-estacion:focus-visible .mov-estacion__t { transform: translateX(5px); }

.mov-estacion__d {
	font-size: clamp(0.95rem, 1.04vw, 1.06rem);
	line-height: 1.66;
	font-weight: 300;
	color: var(--mov-tinta-baja);
	margin: 0;
	max-width: 36ch;
}

.mov-estaciones__pie {
	margin: clamp(20px, 2.4vw, 30px) 0 0;
	/* La caja se ajusta al texto. Como <p> ocupaba el ancho del contenedor
	   entero, y una caja de 1400 px para veintiuna letras estorba a cualquier
	   cosa que pase cerca. */
	width: max-content;
	max-width: 100%;
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: 0.6rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	/* 0,58 y no 0,34: es una nota de PROCEDENCIA, no un adorno. Al 34 % daba
	   2,28:1 sobre blanco, muy por debajo del 4,5:1 de AA para texto pequeño,
	   y a 9,6 px sencillamente no se leía. Al 58 % da 5,33:1. */
	color: rgba(10, 10, 11, 0.58);
}

/* --------------------------------------------------------------------------
   Por qué — el punto de convergencia
   -------------------------------------------------------------------------- */
.mov-porque { text-align: center; }
.mov-porque .mov__lead { margin-inline: auto; }
.mov-porque__texto { max-width: 60ch; margin-inline: auto; }

.mov-destino {
	position: relative;
	display: flex;
	justify-content: center;
	margin-top: clamp(36px, 4.6vw, 70px);
}

/* El botón. Es el único de la página y es donde termina el trazo: por eso pesa.
   El relleno sube desde abajo, que es la dirección por la que ha llegado la
   trayectoria. */
.mov-cta {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 14px;
	padding: 20px 40px;
	overflow: hidden;
	border: 1px solid var(--mov-beige);
	border-radius: 2px;
	color: var(--mov-beige);
	text-decoration: none;
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: 0.82rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	background: var(--mov-blanco);
	transition: color 380ms ease, border-color 380ms ease;
}

.mov-cta::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--mov-beige);
	transform: translateY(101%);
	transition: transform 480ms var(--mov-e);
}

.mov-cta__texto,
.mov-cta__flecha { position: relative; z-index: 1; }
.mov-cta__flecha svg { display: block; width: 18px; height: 18px; transition: transform 380ms var(--mov-e); }

.mov-cta:hover,
.mov-cta:focus-visible { color: var(--mov-blanco); }
.mov-cta:hover::before,
.mov-cta:focus-visible::before { transform: translateY(0); }
.mov-cta:hover .mov-cta__flecha svg,
.mov-cta:focus-visible .mov-cta__flecha svg { transform: translateX(6px); }

/* --------------------------------------------------------------------------
   Para quién es — la única fotografía de gimnasio real de la página
   -------------------------------------------------------------------------- */
/* PARA QUIÉN ES — el texto VIVE SOBRE la fotografía.

   Es la única imagen real de la página y la que cierra el argumento, así que
   ocupa la pantalla entera y el texto va encima, no debajo. Puestos uno junto
   a otro competían; encima, la fotografía es el escenario y el texto la voz.

   La imagen se oscurece por dos vías que hacen cosas distintas y las dos hacen
   falta: un `filter: brightness` baja la escena entera —también sus altas
   luces, que es lo que la ventana de este gimnasio tiene de más— y un
   degradado lateral carga la tinta justo donde se lee, dejando respirar el
   lado del sujeto. Sólo con el degradado, la ventana del fondo seguía
   reventada; sólo con el filtro, había que oscurecer tanto que la fotografía
   dejaba de verse.
   -------------------------------------------------------------------------- */
.mov-quien {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	min-height: clamp(560px, 88vh, 900px);
	display: grid;
	align-items: center;
	padding: clamp(70px, 10vh, 130px) clamp(24px, 6vw, 104px);
	color: #F7F5F0;
}

.mov-quien__foto {
	position: absolute;
	inset: 0;
	z-index: -1;
	margin: 0;
	overflow: hidden;
	background: #0A0A0B;
}

.mov-quien__foto img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* El sujeto vive en el centro-derecha del encuadre; desplazando el foco a
	   la derecha se le deja el lado izquierdo entero al texto. */
	object-position: 62% 42%;
	/* 0,78 y no 0,58. Con 0,58 más el degradado la fotografía desaparecía del
	   todo: quedaba un rectángulo negro con texto encima, que es exactamente lo
	   contrario de lo que se busca. La escena tiene que verse. */
	filter: brightness(0.78) saturate(0.85) contrast(1.05);
}

.mov-quien__foto::after {
	content: "";
	position: absolute;
	inset: 0;
	/* La tinta se sostiene por encima de 0,55 hasta el 50 % del ancho —que es
	   hasta donde llega el bloque de texto— y se despeja a partir del 78 %,
	   que es donde está el sujeto. Medido sobre el peor caso (la ventana del
	   fondo, que es lo más claro del cuadro): 6,5:1 en el punto más flojo. */
	background:
		linear-gradient(90deg, rgba(10, 10, 11, 0.86) 0%, rgba(10, 10, 11, 0.78) 30%, rgba(10, 10, 11, 0.55) 50%, rgba(10, 10, 11, 0.14) 78%, rgba(10, 10, 11, 0) 100%),
		linear-gradient(180deg, rgba(10, 10, 11, 0.34) 0%, rgba(10, 10, 11, 0) 22%, rgba(10, 10, 11, 0) 74%, rgba(10, 10, 11, 0.42) 100%);
}

/* El pie va abajo a la IZQUIERDA, no a la derecha.

   A la derecha caía sobre la zona despejada de la fotografía —el degradado
   ahí ya vale cero— y daba 1,45:1: una nota de PROCEDENCIA que no se leía.
   A la izquierda se apoya en el 0,86 del degradado y sube a 8,2:1. El bloque
   de texto está centrado en vertical, así que esa esquina queda libre. */
.mov-quien__foto figcaption {
	position: absolute;
	left: clamp(24px, 6vw, 104px);
	bottom: clamp(14px, 2.4vh, 24px);
	font-family: var(--font-sans, system-ui, sans-serif);
	font-size: 0.6rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(247, 245, 240, 0.78);
	text-shadow: 0 1px 6px rgba(10, 10, 11, 0.7);
}

.mov-quien__texto {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 1400px;
	margin-inline: auto;
}

/* Una sola columna, en la mitad izquierda: sobre fotografía, dos columnas de
   texto obligarían a oscurecer también el lado del sujeto y no quedaría
   imagen que enseñar. */
/* La caja se ajusta al texto. Como <p> ocupaba el ancho del bloque entero y
   se extendía hasta el 94 % de la sección —sobre la zona clara de la foto—
   aunque su texto sean trece letras pegadas a la izquierda. */
.mov-quien__texto .mov__eyebrow { color: #C9B98F; width: max-content; max-width: 100%; }
.mov-quien__texto .mov__titulo { color: #F7F5F0; max-width: 18ch; }
.mov-quien__texto .mov__lead {
	color: rgba(247, 245, 240, 0.82);
	max-width: min(46ch, 48%);
	margin-bottom: 0;
}

.mov-quien--sin-foto {
	min-height: 0;
	color: var(--mov-tinta);
	padding: clamp(84px, 13vh, 190px) clamp(24px, 6vw, 104px);
}

.mov-quien--sin-foto .mov__eyebrow { color: var(--mov-beige); }
.mov-quien--sin-foto .mov__titulo { color: var(--mov-tinta); }
.mov-quien--sin-foto .mov__lead { color: var(--mov-tinta-baja); }

/* --------------------------------------------------------------------------
   El revelado de las imágenes

   Una cortina que se abre de abajo arriba mientras la imagen, que entra
   ampliada, se asienta. Se anima un porcentaje REGISTRADO y no la función
   `inset()` entera: entre `inset(100% 0 0 0)` e `inset(0)` el navegador no
   interpola —serializan con distinto número de componentes— y la máscara se
   queda clavada sin abrirse nunca.
   -------------------------------------------------------------------------- */
.mov-estacion__foto,
.mov-quien__foto { clip-path: inset(var(--mov-corte, 0%) 0 0 0); }

.mov--anim .mov-estacion__foto,
.mov--anim .mov-quien__foto {
	--mov-corte: 100%;
	transition: --mov-corte 900ms var(--mov-e);
}

.mov--anim .mov-estacion__foto img,
.mov--anim .mov-quien__foto img {
	transform: scale(1.07);
	transition: transform 1500ms var(--mov-e);
}

.mov--anim .mov-estacion__foto.es-visible,
.mov--anim .mov-quien__foto.es-visible { --mov-corte: 0%; }

.mov--anim .mov-estacion__foto.es-visible img,
.mov--anim .mov-quien__foto.es-visible img { transform: scale(1); }

/* --------------------------------------------------------------------------
   La aparición
   -------------------------------------------------------------------------- */
.mov-in { transform: translate3d(0, var(--mov-iny, 0px), 0); }

.mov--anim .mov-in {
	opacity: 0;
	--mov-iny: 22px;
	transition: opacity 700ms var(--mov-e), --mov-iny 700ms var(--mov-e);
}

.mov--anim .mov-in.es-visible { opacity: 1; --mov-iny: 0px; }

/* Las estaciones entran una tras otra, siguiendo el orden del recorrido. */
.mov--anim .mov-estacion.mov-in { transition-delay: calc(var(--mov-est-i, 0) * 130ms); }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1000px) {
	.mov-hero__contenido { width: 100%; }

	.mov-estaciones { grid-template-columns: 1fr; gap: clamp(40px, 7vw, 64px); }
	/* En una columna el escalón no dice nada y sólo abre huecos. */
	.mov-estacion:nth-child(2),
	.mov-estacion:nth-child(3) { margin-top: 0; }
	.mov-estacion__foto { max-width: 560px; }
	/* En vertical la tinta carga ABAJO, no a la izquierda: el sujeto ocupa
	   casi todo el ancho y no queda medio cuadro libre para el texto. */
	.mov-quien { align-items: end; min-height: clamp(600px, 92vh, 820px); }
	/* La fotografía es de interior y ya viene oscura: medida, da 49 de brillo
	   medio después del filtro. En vertical, donde el degradado tiene que cargar
	   mucho más para sostener el texto, ese mismo filtro la mataba del todo. Aquí
	   sube a 0,95 y el degradado deja limpio el tramo de arriba. */
	.mov-quien__foto img { object-position: 58% 32%; filter: brightness(0.95) saturate(0.88) contrast(1.04); }
	.mov-quien__foto::after {
		/* La rampa arranca en el 30 % y llega a 0,72 en el 44 %, que es donde
		   empieza el bloque de texto (el rótulo es lo primero y es el texto más
		   pequeño). Con la rampa más tarde, el rótulo caía en
		   la franja todavía despejada y daba 1,01:1. Por encima del 32 % la
		   fotografía se ve limpia, que es donde está la cara. */
		background: linear-gradient(180deg, rgba(10, 10, 11, 0.35) 0%, rgba(10, 10, 11, 0) 16%, rgba(10, 10, 11, 0) 30%, rgba(10, 10, 11, 0.72) 44%, rgba(10, 10, 11, 0.86) 70%, rgba(10, 10, 11, 0.94) 100%);
	}
	.mov-quien__texto .mov__titulo { max-width: none; }
	.mov-quien__texto .mov__lead { max-width: none; }
	/* En estrecho el raíl del rótulo no cabe: la frase vuelve a una columna. */
	.mov-que .mov__inner { grid-template-columns: 1fr; gap: 0; }
	.mov-que .mov__eyebrow { padding-top: 0; margin-bottom: clamp(20px, 2.6vw, 34px); }
	.mov-que__frase { max-width: none; }
}

@media (max-width: 640px) {
	.mov-que__frase { max-width: none; }
}

/* --------------------------------------------------------------------------
   Movimiento reducido — se apaga el movimiento, no el contenido
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.mov--anim .mov-in { opacity: 1; --mov-iny: 0px; transition: none; }
	.mov--anim .mov-que__frase .mov-pal { opacity: 1; transform: none; transition: none; }
	.mov--anim .mov-estacion__foto,
	.mov--anim .mov-quien__foto { --mov-corte: 0%; transition: none; }
	.mov--anim .mov-estacion__foto img,
	.mov--anim .mov-quien__foto img { transform: none; transition: none; }
	.mov-estacion__nodo, .mov-estacion__nodo::after, .mov-estacion__t, .mov-ruta path { transition: none; }
}

/* --------------------------------------------------------------------------
   PANTALLA VERTICAL — el encuadre de la figura

   La condición es la PROPORCIÓN del hueco, no un ancho en píxeles, y eso es
   deliberado: el lienzo del torno decide su encuadre comparando el ancho del
   hero con su alto (`W < H` en movimiento-estrategico.js). Si aquí se
   preguntara por `max-width`, en una tableta apaisada de 900 px la lámina de
   reposo se encuadraría de una manera y el lienzo de otra, y al relevarse
   habría un salto. Preguntando por lo mismo que pregunta el lienzo, los dos
   encuadres coinciden siempre.

   La figura entra ENTERA y se mide por ancho. Antes se escalaba por alto
   —`height: 119%`—, que en una pantalla estrecha y larga la agrandaba hasta
   dejar en cuadro un fragmento de torso estirado: era eso lo que se veía
   demasiado largo. Al 94 % del ancho guarda respecto a la pantalla la misma
   proporción que tiene en escritorio.
   -------------------------------------------------------------------------- */
@media (max-aspect-ratio: 1 / 1) {
	.mov-hero {
		/* La figura ocupa la mitad de arriba; el texto se apoya abajo, que es
		   donde queda sitio libre. Centrado se montaba sobre las piernas. */
		align-items: flex-end;
		min-height: clamp(600px, 92vh, 900px);
	}
	.mov-hero__base {
		right: auto;
		left: 50%;
		top: 10%;
		width: 94%;
		height: auto;
		transform: translateX(-50%);
	}
	/* EL VELO, medido y no estimado.
	 *
	 * Con la figura entera en cuadro, el bloque de texto cae sobre sus
	 * piernas, no sobre negro. Componiendo la escena real en un lienzo —la
	 * lámina más los dos degradados— y muestreando los píxeles bajo cada caja
	 * de texto, el rótulo "PILAR · MÉTODO P7" daba 3,45:1 contra un reflejo
	 * claro del modelo: por debajo de lo legible para 10,5 px.
	 *
	 * No se arregla aclarando la letra —tendría que llegar casi al blanco—
	 * sino apagando el fondo justo donde empieza el texto. La rampa entra al
	 * 34 % (la cabeza y el torso quedan limpios) y ya lleva 0,78 al 60 %, que
	 * es donde arranca el bloque. Medido después: 7,4:1.
	 */
	.mov-hero__fundido {
		background:
			radial-gradient(126% 96% at 50% 38%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.5) 78%, #000 100%),
			linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 12%, rgba(0, 0, 0, 0) 34%, rgba(0, 0, 0, 0.62) 52%, rgba(0, 0, 0, 0.9) 66%, #000 100%);
	}

	/* Y el rótulo va a opacidad plena: al 82 % perdía casi un punto de
	   contraste justo en el texto más pequeño de la pantalla. */
	.mov-hero__eyebrow { color: #C9B98F; }
}
