@charset "UTF-8";

/*!
 * NGT Campus — hoja de estilo pública
 *
 * DIRECCIÓN DE ARTE
 * -----------------
 * El campus de verano es cálido y vivo. Este es su contrario: invierno, noche,
 * hielo, acero. La página no grita, mide. Tres decisiones la sostienen:
 *
 * 1. LA ALTURA. La sala del CAR tiene catorce metros. La portada se construye
 *    en vertical: una regla graduada dibujada en el margen, un degradado que
 *    entra por arriba como la luz cenital de un pabellón, y unas líneas
 *    verticales muy tenues que recuerdan las espalderas. Ninguna imagen, ningún
 *    recurso externo: todo es CSS.
 *
 * 2. LOS NÚMEROS SON EL CONTENIDO. 3 jornadas, 12 horas, 20 gimnastas, 480 €,
 *    40 €/hora. En vez de adornar las cifras con iconos, las cifras SON el
 *    adorno: serif de gran tamaño, cifras tabulares, rótulo pequeño en
 *    versalitas debajo. De ahí que no haya ni un solo emoji ni una fuente de
 *    iconos en todo el fichero.
 *
 * 3. JERARQUÍA POR INVERSIÓN, NO POR INSIGNIA. El campus completo —la opción
 *    que la clienta quiere destacar— no lleva estrella ni cinta de «el más
 *    popular»: se invierte a fondo noche. Lo mismo hace una jornada elegida.
 *    Elegir es entrar en la sala; visualmente, se apaga la luz del día.
 *
 * TIPOGRAFÍA
 * Serif del sistema para los títulos y las cifras, sans del sistema para el
 * texto corriente. Ninguna fuente descargada: el contrato prohíbe los CDN, y
 * una familia externa costaría tiempo de carga y una petición a un tercero que
 * Complianz tendría que declarar.
 *
 * COLOR
 * Paleta calculada y validada antes de escribir una línea. Cada ficha lleva su
 * ratio de contraste WCAG. Ninguna combinación de este fichero baja de 4,5:1.
 *
 * @package NGT_Campus
 */

/*
 * Orden canónico de capas.
 *
 * IMPRESCINDIBLE y tiene que ir ANTES de cualquier regla. El orden de las
 * capas lo fija la PRIMERA vez que aparece cada nombre, en todo el documento.
 * Si esta hoja se carga antes que la del tema —que es lo que pasa— y abre
 * `components` sin más, esa capa queda registrada la primera y por tanto como
 * la MENOS prioritaria: el preflight de Tailwind (`@layer base`, con
 * `* { margin: 0; padding: 0 }`) pasa a ganarle al tema y los bloques pierden
 * su centrado y sus márgenes laterales.
 *
 * Declarando aquí el orden, da igual en qué orden se carguen las hojas.
 */
@layer base, components, utilities;

@layer components {

	/* =================================================================
	 * 1. Fichas de color y de tipografía
	 *
	 * Se declaran en .campus y no en :root: el plugin se instala en sitios
	 * ajenos y no tiene por qué contaminar el espacio de nombres del tema.
	 * ================================================================= */

	.campus {
		/* --- Paleta invierno, fijada y validada (no recalcular) --------- */
		--campus-noche: #0E1A2B;    /* fondo noche        · blanco encima 17,48:1 */
		--campus-hielo: #EAF2FA;    /* fondo glaciar      · tinta encima 13,85:1 */
		--campus-acero: #17497F;    /* acento sobre claro · 8,09:1 */
		--campus-escarcha: #A9CCEB; /* acento sobre noche · 10,43:1 */
		--campus-plata: #CBD8E6;    /* texto secundario sobre noche · 12,07:1 */
		--campus-cta: #0F6FC4;      /* botón              · blanco encima 5,13:1 */

		/* --- Añadidos, con su contraste medido -------------------------
		 * --campus-tinta: es la «tinta» del contrato. 13,85:1 sobre
		 *   --campus-hielo, exactamente el ratio anunciado; 15,66:1 sobre
		 *   blanco. Se obtiene resolviendo el ratio, no eligiendo a ojo.
		 * --campus-alerta: bronce profundo para «últimas plazas».
		 *   6,36:1 sobre --campus-hielo · 5,69:1 sobre --campus-superficie
		 *   · 7,19:1 sobre blanco. Bronce y no rojo a propósito: aquí se
		 *   vende un campus de élite, no un vuelo de bajo coste. La escasez
		 *   es un hecho, no hace falta gritarla.
		 * --campus-alerta-clara: el mismo aviso sobre fondo noche (una
		 *   jornada elegida se invierte). 9,33:1 sobre --campus-noche ·
		 *   7,96:1 sobre --campus-superficie-noche.
		 * --campus-completo: granate apagado. 8,88:1 sobre --campus-hielo
		 *   · 7,95:1 sobre --campus-superficie.
		 * --campus-superficie: mezcla tinta 6% sobre hielo (#DDE6EE).
		 * --campus-superficie-noche: escarcha 8% sobre noche (#1A283A).
		 * ---------------------------------------------------------------- */
		--campus-tinta: #152438;
		--campus-alerta: #7A4E0C;
		--campus-alerta-clara: #E0B778;
		--campus-completo: #7E1C2E;
		--campus-superficie: color-mix(in srgb, var(--campus-tinta) 6%, var(--campus-hielo));
		--campus-superficie-noche: color-mix(in srgb, var(--campus-escarcha) 8%, var(--campus-noche));

		/* Filetes: decorativos, nunca portan información. */
		--campus-filete: color-mix(in srgb, var(--campus-tinta) 16%, transparent);
		--campus-filete-noche: color-mix(in srgb, var(--campus-escarcha) 22%, transparent);

		/* Color del anillo de foco, redefinido en los bloques nocturnos. */
		--campus-foco: var(--campus-acero);

		/* --- Tipografía ------------------------------------------------- */
		--campus-display: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
		--campus-texto: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

		/* --- Ritmo ------------------------------------------------------ */
		--campus-aire: clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);
		--campus-canal: clamp(1rem, 0.6rem + 1.8vw, 2rem);

		/* clip y no hidden: hidden convierte a todos los ancestros en
		 * contenedor de desplazamiento y mata el position:sticky del
		 * resumen. Es el mismo error que ya costó un sticky en este sitio. */
		overflow-x: clip;

		box-sizing: border-box;
		margin-block: var(--campus-aire);
		color: var(--campus-tinta);
		font-family: var(--campus-texto);
		font-size: 1rem;
		line-height: 1.6;
		-webkit-text-size-adjust: 100%;
		text-size-adjust: 100%;
	}

	.campus *,
	.campus *::before,
	.campus *::after {
		box-sizing: inherit;
	}

	/* Un fieldset sin min-inline-size:0 se niega a encogerse dentro de una
	 * rejilla y provoca desbordamiento horizontal en móvil. */
	.campus fieldset {
		min-inline-size: 0;
		margin: 0;
		padding: 0;
		border: 0;
	}

	.campus legend {
		padding: 0;
	}

	.campus p,
	.campus dl,
	.campus dd,
	.campus ul,
	.campus ol,
	.campus h2,
	.campus h3 {
		margin: 0;
	}

	.campus ul,
	.campus ol {
		padding: 0;
		list-style: none;
	}

	.campus img,
	.campus svg {
		max-inline-size: 100%;
	}

	.campus [hidden] {
		display: none;
	}

	.campus :focus-visible {
		outline: 2px solid var(--campus-foco);
		outline-offset: 2px;
	}

	.campus-vh {
		position: absolute;
		inline-size: 1px;
		block-size: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	/* =================================================================
	 * 2. Retículas y títulos comunes
	 * ================================================================= */

	.campus-titulo {
		font-family: var(--campus-display);
		font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.4rem);
		font-weight: 600;
		line-height: 1.12;
		letter-spacing: -0.01em;
		color: var(--campus-tinta);
		margin-block-end: var(--campus-canal);
	}

	.campus-antetitulo {
		font-size: 0.72rem;
		font-weight: 600;
		letter-spacing: 0.2em;
		text-transform: uppercase;
		color: var(--campus-escarcha);
	}

	.campus-nota {
		margin-block-start: var(--campus-canal);
		font-size: 0.85rem;
		line-height: 1.55;
		color: color-mix(in srgb, var(--campus-tinta) 78%, var(--campus-hielo));
	}

	.campus-desbordable {
		overflow-x: auto;
		overscroll-behavior-x: contain;
	}

	/* =================================================================
	 * 3. Portada — la sala de catorce metros
	 * ================================================================= */

	.campus-portada {
		position: relative;
		overflow: clip;
		padding: clamp(2.5rem, 1.5rem + 5vw, 5.5rem) var(--campus-canal);
		color: var(--campus-hielo);
		background-color: var(--campus-noche);

		/* Dos capas, ninguna imagen:
		 *  · la luz cenital de un pabellón, que entra por arriba;
		 *  · unas verticales muy tenues, las espalderas de la sala.
		 * El punto más claro del degradado es #13365D; el texto blanco
		 * encima sigue en 12,26:1, y la escarcha en 7,31:1. */
		background-image:
			radial-gradient(90% 62% at 50% -12%, color-mix(in srgb, var(--campus-acero) 60%, transparent) 0%, transparent 70%),
			repeating-linear-gradient(90deg, color-mix(in srgb, var(--campus-escarcha) 6%, transparent) 0 1px, transparent 1px 7rem);

		--campus-foco: var(--campus-escarcha);
	}

	/* La regla graduada: trazos cortos cada 1,5 rem y uno largo cada 6 rem,
	 * como la cinta métrica de una sala. Decorativa y sin texto, de modo que
	 * ninguna medida queda cableada en el código. */
	.campus-portada__medida {
		position: absolute;
		inset-block: clamp(1.5rem, 4vw, 3rem);
		inset-inline-start: clamp(1rem, 2.4vw, 2.25rem);
		inline-size: 14px;
		border-inline-start: 1px solid var(--campus-filete-noche);
		background-image:
			repeating-linear-gradient(to bottom, var(--campus-filete-noche) 0 1px, transparent 1px 1.5rem),
			repeating-linear-gradient(to bottom, var(--campus-filete-noche) 0 1px, transparent 1px 6rem);
		background-size: 6px 100%, 14px 100%;
		background-repeat: no-repeat, no-repeat;
	}

	.campus-portada__texto {
		position: relative;
		max-inline-size: 62rem;
		margin-inline: auto;
	}

	.campus-portada__titulo {
		margin-block-start: 0.75rem;
		font-family: var(--campus-display);
		font-size: clamp(2rem, 1.15rem + 3.6vw, 4rem);
		font-weight: 600;
		/* 1,1 y no 1,05: en español las mayúsculas acentuadas (É de «élite»)
		 * suben por encima de la altura de mayúscula, y a este cuerpo el
		 * acento llegaba a rozar la línea anterior. */
		line-height: 1.1;
		letter-spacing: -0.018em;
		text-wrap: balance;
		color: #FFFFFF; /* 17,48:1 sobre --campus-noche */
		max-inline-size: 18ch;
	}

	.campus-portada__entrada {
		/* El interlineado del titular ya se come parte del hueco por dentro
		 * de la caja de línea: hace falta más aire del que parece. */
		margin-block-start: clamp(1.5rem, 1rem + 1.2vw, 2.5rem);
		max-inline-size: 46ch;
		font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
		color: var(--campus-plata);
	}

	.campus-portada__reserva {
		margin-block-start: 1.5rem;
		padding-block-start: 1rem;
		border-block-start: 1px solid var(--campus-filete-noche);
		font-size: 0.85rem;
		letter-spacing: 0.02em;
		color: var(--campus-escarcha);
	}

	/* --- Ficha técnica: las cifras del campus ------------------------- */

	.campus-ficha {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
		gap: 1.25rem var(--campus-canal);
		margin-block-start: clamp(1.75rem, 1rem + 2vw, 3rem);
		padding-block-start: 1.5rem;
		border-block-start: 1px solid var(--campus-filete-noche);
	}

	/* column-reverse: el orden del código es rótulo → cifra, que es el que
	 * lee un lector de pantalla («Jornadas, 3»); el orden visual es el
	 * inverso, porque la cifra manda. Ni un solo elemento recibe el foco
	 * aquí, así que invertir no altera el recorrido del teclado. */
	.campus-ficha__dato {
		display: flex;
		flex-direction: column-reverse;
		gap: 0.35rem;
	}

	.campus-ficha__dato dt {
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--campus-escarcha);
	}

	.campus-ficha__dato dd {
		font-family: var(--campus-display);
		font-size: clamp(2rem, 1.5rem + 1.8vw, 3rem);
		font-weight: 600;
		line-height: 1;
		font-variant-numeric: tabular-nums lining-nums;
		color: #FFFFFF;
	}

	@media (min-width: 64rem) {
		.campus-portada {
			padding-inline-start: clamp(3.5rem, 6vw, 6rem);
		}
	}

	@media (max-width: 63.999rem) {
		.campus-portada__medida {
			display: none;
		}
	}

	/* =================================================================
	 * 4. Escalera de tarifas
	 *
	 * Filas, no tarjetas. Tres tarjetas iguales dicen «tres opciones
	 * equivalentes»; una escalera dice «cada peldaño baja el precio por
	 * hora», que es el argumento real.
	 * ================================================================= */

	.campus-tarifas {
		padding-inline: var(--campus-canal);
	}

	.campus-escalera {
		display: grid;
		gap: 0.75rem;
	}

	.campus-escalon {
		display: grid;
		grid-template-columns: minmax(0, auto) minmax(0, 1fr);
		gap: 1rem var(--campus-canal);
		align-items: center;
		padding: clamp(1.1rem, 0.8rem + 1vw, 1.75rem) clamp(1.1rem, 0.8rem + 1vw, 2rem);
		background-color: var(--campus-superficie);
		border: 1px solid var(--campus-filete);
	}

	/* El peldaño destacado se invierte: sin insignia, sin estrella. */
	.campus-escalon--completo {
		color: var(--campus-hielo);
		background-color: var(--campus-noche);
		background-image: radial-gradient(70% 140% at 88% 0%, color-mix(in srgb, var(--campus-acero) 45%, transparent) 0%, transparent 72%);
		border-color: var(--campus-noche);
		--campus-foco: var(--campus-escarcha);
	}

	.campus-escalon__jornadas {
		display: flex;
		flex-direction: column;
		gap: 0.1rem;
		min-inline-size: 3.5rem;
	}

	.campus-escalon__cifra {
		font-family: var(--campus-display);
		font-size: clamp(2.5rem, 1.9rem + 2.4vw, 3.75rem);
		font-weight: 600;
		line-height: 0.95;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-escalon__unidad {
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: color-mix(in srgb, currentColor 72%, transparent);
	}

	.campus-escalon__volumen {
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
	}

	.campus-escalon__horas {
		font-size: 0.85rem;
		color: color-mix(in srgb, currentColor 80%, transparent);
	}

	.campus-escalon__precio {
		display: flex;
		flex-direction: column;
		gap: 0.15rem;
	}

	.campus-escalon__importe {
		font-family: var(--campus-display);
		font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.25rem);
		font-weight: 600;
		line-height: 1.05;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-escalon__hora {
		font-size: 0.8rem;
		letter-spacing: 0.02em;
		color: color-mix(in srgb, currentColor 78%, transparent);
	}

	.campus-escalon__ahorro {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 0.5rem 0.9rem;
	}

	.campus-ahorro {
		display: inline-flex;
		flex-direction: column;
		padding-inline-start: 0.7rem;
		border-inline-start: 2px solid currentColor;
	}

	.campus-ahorro__rotulo {
		font-size: 0.65rem;
		font-weight: 600;
		letter-spacing: 0.16em;
		text-transform: uppercase;
		color: color-mix(in srgb, currentColor 72%, transparent);
	}

	.campus-ahorro__cifra {
		font-size: 1rem;
		font-weight: 600;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-escalon__sello {
		font-size: 0.68rem;
		font-weight: 600;
		letter-spacing: 0.18em;
		text-transform: uppercase;
		color: var(--campus-escarcha);
	}

	/* --- Barra de volumen: un tramo = una jornada de 4 h -------------- */

	.campus-barra {
		display: flex;
		gap: 4px;
		max-inline-size: 13rem;
	}

	.campus-barra__tramo {
		flex: 1 1 0;
		block-size: 6px;
		background-color: color-mix(in srgb, currentColor 22%, transparent);
	}

	.campus-barra__tramo.is-lleno {
		background-color: currentColor;
	}

	@media (min-width: 48rem) {
		.campus-escalon {
			grid-template-columns: 5.5rem minmax(8rem, 1fr) minmax(7.5rem, auto) minmax(7rem, auto);
		}
	}

	.campus-tarifas__accion {
		margin-block-start: var(--campus-canal);
	}

	/* =================================================================
	 * 5. Parrilla de plazas
	 * ================================================================= */

	.campus-plazas {
		padding-inline: var(--campus-canal);
	}

	.campus-parrilla {
		inline-size: 100%;
		min-inline-size: 22rem;
		border-collapse: collapse;
		text-align: start;
	}

	.campus-parrilla th,
	.campus-parrilla td {
		padding: 0.85rem 0.9rem;
		border: 1px solid var(--campus-filete);
		vertical-align: top;
		text-align: start;
	}

	.campus-parrilla__esquina {
		background-color: transparent;
		border-color: transparent;
	}

	.campus-parrilla__dia {
		background-color: var(--campus-noche);
		border-color: var(--campus-noche);
		color: #FFFFFF;
	}

	.campus-parrilla__numero {
		display: block;
		font-family: var(--campus-display);
		font-size: 1.6rem;
		font-weight: 600;
		line-height: 1;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-parrilla__rotulo {
		display: block;
		margin-block-start: 0.2rem;
		font-size: 0.68rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--campus-escarcha);
	}

	.campus-parrilla__turno {
		background-color: var(--campus-superficie);
	}

	.campus-parrilla__nombre {
		display: block;
		font-weight: 600;
	}

	.campus-parrilla__horario {
		display: block;
		margin-block-start: 0.15rem;
		font-size: 0.8rem;
		font-variant-numeric: tabular-nums;
		color: color-mix(in srgb, var(--campus-tinta) 76%, var(--campus-hielo));
	}

	.campus-parrilla__celda--vacia {
		color: color-mix(in srgb, var(--campus-tinta) 45%, var(--campus-hielo));
	}

	.campus-leyenda {
		display: flex;
		flex-wrap: wrap;
		gap: 0.5rem 1.5rem;
		margin-block-start: 1rem;
	}

	/* =================================================================
	 * 6. Avisos de disponibilidad
	 *
	 * Tres estados, tres FORMAS distintas (anillo, rombo, barra) además de
	 * tres colores: quien no distingue el color lee la forma, el texto y la
	 * grasa. Ninguno de los tres depende del color para entenderse.
	 * ================================================================= */

	.campus-aviso {
		display: flex;
		align-items: center;
		gap: 0.45rem;
		font-size: 0.8rem;
		line-height: 1.35;
	}

	.campus-marca {
		flex: none;
	}

	.campus-aviso--disponible {
		color: var(--campus-acero); /* 8,09:1 sobre hielo */
	}

	/* «Quedan 3 plazas»: bronce, versalitas y negrita. Tensión, no alarma. */
	.campus-aviso--ultimas {
		color: var(--campus-alerta); /* 6,36:1 sobre hielo · 5,69:1 sobre superficie */
		font-weight: 700;
		letter-spacing: 0.04em;
	}

	.campus-aviso--completo {
		color: var(--campus-completo); /* 8,88:1 sobre hielo */
		font-weight: 600;
		letter-spacing: 0.1em;
		text-transform: uppercase;
	}

	/* =================================================================
	 * 7. Formulario
	 * ================================================================= */

	.campus-inscripcion .campus-form {
		padding-inline: var(--campus-canal);
	}

	.campus-form__cuerpo {
		display: grid;
		gap: clamp(1.75rem, 1rem + 2.5vw, 3rem);
		max-inline-size: 78rem;
		margin-inline: auto;
		margin-block-start: clamp(1.75rem, 1rem + 2.5vw, 3rem);
	}

	.campus-form__campos {
		display: grid;
		gap: clamp(2rem, 1.2rem + 2.5vw, 3.5rem);
		min-inline-size: 0;
	}

	/* --- Bloque numerado --------------------------------------------- */

	.campus-bloque {
		display: block;
		padding-block-start: 1.25rem;
		border-block-start: 1px solid var(--campus-filete);
	}

	.campus-bloque__titulo {
		display: block;
		inline-size: 100%;
		margin-block-end: 1rem;
	}

	.campus-bloque__numero {
		display: block;
		font-family: var(--campus-display);
		font-size: 0.9rem;
		font-variant-numeric: tabular-nums lining-nums;
		letter-spacing: 0.16em;
		color: var(--campus-acero);
	}

	.campus-bloque__nombre {
		display: block;
		font-family: var(--campus-display);
		font-size: clamp(1.35rem, 1.15rem + 0.9vw, 1.9rem);
		font-weight: 600;
		line-height: 1.15;
		letter-spacing: -0.01em;
	}

	.campus-bloque__entrada {
		max-inline-size: 58ch;
		margin-block-end: 1.25rem;
		font-size: 0.9rem;
		color: color-mix(in srgb, var(--campus-tinta) 80%, var(--campus-hielo));
	}

	.campus-rejilla {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
		gap: 1.1rem var(--campus-canal);
	}

	/* Los campos largos ocupan la fila entera. El nivel es un --radio como
	 * cualquier otro desde que lo pinta campo(). */
	.campus-campo--textarea,
	.campus-campo--radio {
		grid-column: 1 / -1;
	}

	/* --- Campo --------------------------------------------------------- */

	.campus-campo {
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
		min-inline-size: 0;
	}

	.campus-campo__etiqueta {
		font-size: 0.72rem;
		font-weight: 700;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		color: color-mix(in srgb, var(--campus-tinta) 88%, var(--campus-hielo));
	}

	.campus-campo__marca {
		color: var(--campus-completo);
	}

	.campus-campo__opcional {
		font-weight: 500;
		letter-spacing: 0.04em;
		text-transform: none;
		color: color-mix(in srgb, var(--campus-tinta) 62%, var(--campus-hielo));
	}

	.campus-campo__control {
		inline-size: 100%;
		min-inline-size: 0;
		padding: 0.7rem 0.8rem;
		font: inherit;
		font-size: 1rem; /* 16px: por debajo, iOS hace zoom al enfocar. */
		color: var(--campus-tinta);
		background-color: #FFFFFF;
		border: 1px solid color-mix(in srgb, var(--campus-tinta) 32%, transparent);
		border-radius: 0; /* Ángulo vivo: la píldora redondeada es el gesto genérico. */
		transition: border-color 160ms ease, box-shadow 160ms ease;
	}

	.campus-campo__control:hover {
		border-color: color-mix(in srgb, var(--campus-tinta) 52%, transparent);
	}

	.campus-campo__control:focus {
		border-color: var(--campus-acero);
		/* Segundo filete interior en vez de sombra difusa: más nítido y no
		 * desplaza nada, porque no toca el modelo de caja. */
		box-shadow: inset 0 -2px 0 0 var(--campus-acero);
		outline: none;
	}

	.campus-campo__control:focus-visible {
		outline: 2px solid var(--campus-foco);
		outline-offset: 2px;
	}

	.campus-campo textarea.campus-campo__control {
		resize: vertical;
		min-block-size: 4.5rem;
	}

	.campus-campo__ayuda {
		font-size: 0.8rem;
		line-height: 1.45;
		color: color-mix(in srgb, var(--campus-tinta) 74%, var(--campus-hielo));
	}

	.campus-campo__error {
		display: flex;
		align-items: baseline;
		gap: 0.4rem;
		font-size: 0.82rem;
		font-weight: 600;
		color: var(--campus-completo); /* 8,88:1 sobre hielo */
	}

	.campus-campo__error::before {
		content: "";
		flex: none;
		inline-size: 0.5rem;
		block-size: 0.5rem;
		background-color: currentColor;
		transform: rotate(45deg); /* Rombo: el error se ve sin distinguir el color. */
	}

	.campus-campo--error .campus-campo__control {
		border-color: var(--campus-completo);
		box-shadow: inset 0 -2px 0 0 var(--campus-completo);
	}

	/* --- Opciones (radio) --------------------------------------------- */

	.campus-opciones {
		display: flex;
		flex-wrap: wrap;
		gap: 0.5rem;
	}

	.campus-opcion {
		position: relative;
		display: inline-flex;
	}

	/* El control nativo sigue en el flujo y recibe el foco y el teclado;
	 * solo es invisible. Nunca display:none, que lo sacaría del recorrido. */
	.campus-opcion__input {
		position: absolute;
		inset-block-start: 0;
		inset-inline-start: 0;
		inline-size: 100%;
		block-size: 100%;
		margin: 0;
		opacity: 0;
		cursor: pointer;
	}

	.campus-opcion__cara {
		display: inline-flex;
		align-items: center;
		padding: 0.55rem 1rem;
		font-size: 0.9rem;
		font-weight: 600;
		letter-spacing: 0.02em;
		background-color: #FFFFFF;
		border: 1px solid color-mix(in srgb, var(--campus-tinta) 28%, transparent);
		cursor: pointer;
		transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
	}

	.campus-opcion__input:hover + .campus-opcion__cara {
		border-color: var(--campus-acero);
	}

	.campus-opcion__input:checked + .campus-opcion__cara {
		color: #FFFFFF; /* 17,48:1 sobre noche */
		background-color: var(--campus-noche);
		border-color: var(--campus-noche);
	}

	.campus-opcion__input:focus-visible + .campus-opcion__cara {
		outline: 2px solid var(--campus-foco);
		outline-offset: 2px;
	}

	/* --- Aviso de turno asignado -------------------------------------- */

	.campus-turno:not(:empty) {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		margin-block-start: 1rem;
		padding: 0.6rem 0.9rem;
		font-size: 0.85rem;
		font-weight: 600;
		color: var(--campus-acero);
		background-color: var(--campus-superficie);
		border-inline-start: 3px solid var(--campus-acero);
	}

	.campus-empujon {
		margin-block-start: 1rem;
		padding: 0.75rem 1rem;
		font-size: 0.88rem;
		font-weight: 600;
		color: var(--campus-hielo);
		background-color: var(--campus-noche);
	}

	/* --- Grupos de turno ----------------------------------------------- */

	.campus-grupo {
		display: block;
		margin-block-start: 1.75rem;
	}

	.campus-grupo__titulo {
		display: block;
		inline-size: 100%;
		margin-block-end: 0.75rem;
		padding-block-end: 0.5rem;
		border-block-end: 1px solid var(--campus-filete);
	}

	.campus-grupo__nombre {
		font-family: var(--campus-display);
		font-size: 1.15rem;
		font-weight: 600;
	}

	.campus-grupo__horario {
		margin-inline-start: 0.6rem;
		font-size: 0.9rem;
		font-variant-numeric: tabular-nums;
		color: var(--campus-acero);
	}

	.campus-grupo__niveles {
		display: block;
		margin-block-start: 0.15rem;
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: color-mix(in srgb, var(--campus-tinta) 68%, var(--campus-hielo));
	}

	/* --- Jornadas ------------------------------------------------------ */

	.campus-jornadas {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
		gap: 0.75rem;
	}

	.campus-jornada {
		position: relative;
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
		padding: 1rem;
		background-color: #FFFFFF;
		border: 1px solid color-mix(in srgb, var(--campus-tinta) 22%, transparent);
		transition: border-color 160ms ease, background-color 160ms ease, transform 160ms ease;
	}

	.campus-jornada__input {
		position: absolute;
		inset-block-start: 0.7rem;
		inset-inline-end: 0.7rem;
		inline-size: 1px;
		block-size: 1px;
		margin: 0;
		opacity: 0;
	}

	.campus-jornada__cara {
		display: flex;
		flex-direction: column;
		gap: 0.1rem;
		cursor: pointer;
	}

	/* La etiqueta cubre la tarjeta entera: se pulsa en cualquier punto. */
	.campus-jornada__cara::after {
		content: "";
		position: absolute;
		inset: 0;
	}

	.campus-jornada__numero {
		font-family: var(--campus-display);
		font-size: clamp(2.25rem, 1.8rem + 1.6vw, 3rem);
		font-weight: 600;
		line-height: 0.95;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-jornada__rotulo {
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: color-mix(in srgb, var(--campus-tinta) 68%, var(--campus-hielo));
	}

	.campus-jornada__horario {
		font-size: 0.8rem;
		font-variant-numeric: tabular-nums;
		color: color-mix(in srgb, var(--campus-tinta) 76%, var(--campus-hielo));
	}

	/* El trazo de «elegida» solo aparece cuando lo está. */
	.campus-marca--elegida {
		position: absolute;
		inset-block-start: 0.85rem;
		inset-inline-end: 0.85rem;
		opacity: 0;
		transition: opacity 160ms ease;
	}

	/* El hover va en la tarjeta, no en la casilla: la casilla mide 1px y
	 * nadie la va a rozar con el ratón. */
	.campus-jornada:not(.campus-jornada--completo):hover {
		border-color: var(--campus-acero);
	}

	.campus-jornada__input:focus-visible + .campus-jornada__cara {
		outline: 2px solid var(--campus-foco);
		outline-offset: 4px;
	}

	/* Elegir una jornada invierte la tarjeta: se entra en la sala. */
	.campus-jornada:has(.campus-jornada__input:checked) {
		color: var(--campus-hielo);
		background-color: var(--campus-noche);
		border-color: var(--campus-noche);
		--campus-foco: var(--campus-escarcha);
	}

	.campus-jornada:has(.campus-jornada__input:checked) .campus-jornada__rotulo,
	.campus-jornada:has(.campus-jornada__input:checked) .campus-jornada__horario {
		color: var(--campus-plata); /* 12,07:1 sobre noche */
	}

	.campus-jornada:has(.campus-jornada__input:checked) .campus-aviso--disponible {
		color: var(--campus-escarcha); /* 10,43:1 sobre noche */
	}

	.campus-jornada:has(.campus-jornada__input:checked) .campus-aviso--ultimas {
		color: var(--campus-alerta-clara); /* 9,33:1 sobre noche */
	}

	.campus-jornada__input:checked + .campus-jornada__cara .campus-marca--elegida {
		opacity: 1;
	}

	/* Repliegue si el navegador no entiende :has().
	 * Sin él la inversión no se aplicaría y el texto blanco quedaría sobre
	 * fondo blanco: invisible. Aquí no se invierte nada, se dibuja un cerco
	 * de acero desde la propia etiqueta, que sí alcanza toda la tarjeta. */
	@supports not selector(:has(*)) {
		.campus-jornada__input:checked + .campus-jornada__cara::before {
			content: "";
			position: absolute;
			inset: 0;
			border: 3px solid var(--campus-acero);
		}

		.campus-jornada__input:checked + .campus-jornada__cara {
			color: var(--campus-acero); /* 8,09:1 sobre blanco y sobre hielo */
		}
	}

	/* Completo: ni pulsable ni enfocable, y tachado para que se entienda
	 * sin leer el aviso. */
	.campus-jornada--completo {
		background-color: var(--campus-superficie);
		border-style: dashed;
		border-color: color-mix(in srgb, var(--campus-tinta) 26%, transparent);
	}

	.campus-jornada--completo .campus-jornada__cara {
		cursor: not-allowed;
	}

	.campus-jornada--completo .campus-jornada__numero {
		color: color-mix(in srgb, var(--campus-tinta) 55%, var(--campus-hielo));
		text-decoration: line-through;
		text-decoration-thickness: 2px;
	}

	.campus-jornada--ultimas {
		border-color: color-mix(in srgb, var(--campus-alerta) 55%, transparent);
	}

	/* =================================================================
	 * 8. Resumen — el precio en directo
	 * ================================================================= */

	.campus-resumen {
		align-self: start;
		padding: clamp(1.25rem, 1rem + 1vw, 1.75rem);
		color: var(--campus-hielo);
		background-color: var(--campus-noche);
		background-image: radial-gradient(85% 45% at 50% 0%, color-mix(in srgb, var(--campus-acero) 42%, transparent) 0%, transparent 70%);
		--campus-foco: var(--campus-escarcha);
	}

	.campus-resumen__titulo {
		font-family: var(--campus-display);
		font-size: 1.25rem;
		font-weight: 600;
		color: #FFFFFF;
	}

	.campus-resumen__estado {
		margin-block-start: 0.35rem;
		font-size: 0.82rem;
		line-height: 1.45;
		color: var(--campus-escarcha);
	}

	.campus-cifras {
		margin-block-start: 1.25rem;
		border-block-start: 1px solid var(--campus-filete-noche);
	}

	.campus-cifras__linea {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
		justify-content: space-between;
		gap: 0.5rem;
		padding-block: 0.55rem;
		border-block-end: 1px solid var(--campus-filete-noche);
	}

	.campus-cifras__linea dt {
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--campus-plata);
	}

	.campus-cifras__linea dd {
		font-size: 1rem;
		font-weight: 600;
		font-variant-numeric: tabular-nums lining-nums;
		color: #FFFFFF;
	}

	.campus-cifras__linea--total dd {
		font-family: var(--campus-display);
		font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
		line-height: 1.05;
	}

	/* --- Tabla mínima: la escalera sin JavaScript --------------------- */

	.campus-mini {
		inline-size: 100%;
		margin-block-start: 1rem;
		border-collapse: collapse;
		font-size: 0.8rem;
		font-variant-numeric: tabular-nums lining-nums;
	}

	.campus-mini th,
	.campus-mini td {
		padding: 0.4rem 0.3rem;
		text-align: end;
		color: var(--campus-plata);
		border-block-end: 1px solid var(--campus-filete-noche);
	}

	.campus-mini thead th {
		font-size: 0.62rem;
		font-weight: 600;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		color: var(--campus-escarcha);
	}

	.campus-mini tbody th {
		text-align: start;
	}

	.campus-mini__fila--destacada th,
	.campus-mini__fila--destacada td {
		color: #FFFFFF;
	}

	/* Fila activa: filete lateral + blanco. La marca el JavaScript. */
	.campus-mini tr.is-activa th {
		position: relative;
		padding-inline-start: 0.6rem;
		box-shadow: inset 3px 0 0 0 var(--campus-escarcha);
	}

	.campus-mini tr.is-activa th,
	.campus-mini tr.is-activa td {
		color: #FFFFFF;
	}

	/* --- Botón --------------------------------------------------------- */

	.campus-boton {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		/* Ancho natural: un botón de 1200 px de ancho bajo las tarifas deja de
		 * parecer un botón y pasa a parecer una franja. Solo el del resumen,
		 * que vive en una columna estrecha, se estira. */
		inline-size: auto;
		min-inline-size: min(100%, 15rem);
		min-block-size: 3rem;
		margin-block-start: 1.25rem;
		padding: 0.8rem 1.5rem;
		font: inherit;
		font-size: 0.85rem;
		font-weight: 700;
		letter-spacing: 0.1em;
		text-transform: uppercase;
		text-decoration: none;
		color: #FFFFFF; /* 5,13:1 sobre --campus-cta */
		background-color: var(--campus-cta);
		border: 0;
		border-radius: 0;
		cursor: pointer;
		transition: background-color 160ms ease;
	}

	.campus-boton:hover,
	.campus-boton:focus {
		/* Mezclar hacia la noche solo sube el contraste del blanco. */
		background-color: color-mix(in srgb, var(--campus-cta) 82%, var(--campus-noche));
		color: #FFFFFF;
	}

	.campus-resumen__boton {
		inline-size: 100%;
	}

	.campus-boton--compacto {
		inline-size: auto;
		min-inline-size: 0;
		min-block-size: 2.75rem;
		margin-block-start: 0;
		padding-inline: 1.1rem;
	}

	.campus-resumen__nota {
		margin-block-start: 0.9rem;
		font-size: 0.75rem;
		line-height: 1.5;
		color: var(--campus-plata);
	}

	.campus-resumen__nota a {
		color: var(--campus-escarcha); /* 10,43:1 sobre noche */
		text-underline-offset: 0.2em;
	}

	/* --- Barra fija de móvil ------------------------------------------- */

	.campus-barra-movil {
		position: sticky;
		inset-block-end: 0;
		z-index: 2;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 1rem;
		margin-block-start: 1.5rem;
		padding: 0.6rem 1rem;
		padding-block-end: calc(0.6rem + env(safe-area-inset-bottom, 0px));
		color: var(--campus-hielo);
		background-color: var(--campus-noche);
		border-block-start: 1px solid var(--campus-filete-noche);
		--campus-foco: var(--campus-escarcha);
	}

	.campus-barra-movil__cifra {
		font-family: var(--campus-display);
		font-size: 1.5rem;
		font-weight: 600;
		font-variant-numeric: tabular-nums lining-nums;
		color: #FFFFFF;
	}

	/* =================================================================
	 * 9. Errores y avisos de administración
	 * ================================================================= */

	.campus-errores {
		max-inline-size: 78rem;
		margin-inline: auto;
		margin-block-start: var(--campus-canal);
		padding: 1rem 1.25rem;
		background-color: var(--campus-superficie);
		border-inline-start: 4px solid var(--campus-completo);
	}

	.campus-errores__titulo {
		font-family: var(--campus-display);
		font-size: 1.1rem;
		font-weight: 600;
		color: var(--campus-completo); /* 7,95:1 sobre la superficie clara */
	}

	.campus-errores__lista {
		margin-block-start: 0.5rem;
		display: grid;
		gap: 0.3rem;
		font-size: 0.88rem;
	}

	.campus-errores__lista a {
		color: var(--campus-completo);
		text-underline-offset: 0.2em;
	}

	.campus-aviso-admin {
		padding: 0.75rem 1rem;
		font-family: var(--campus-texto);
		font-size: 0.85rem;
		color: var(--campus-completo);
		background-color: var(--campus-superficie);
		border: 1px dashed var(--campus-completo);
	}

	/* =================================================================
	 * 10. Dos columnas
	 * ================================================================= */

	@media (min-width: 62rem) {
		.campus-form__cuerpo {
			grid-template-columns: minmax(0, 1fr) minmax(17rem, 21rem);
			align-items: start;
		}

		/* El resumen ocupa la única fila de la rejilla, así que su bloque
		 * contenedor es toda la altura del formulario: sticky funciona. */
		.campus-resumen {
			position: sticky;
			inset-block-start: 1.5rem;
		}

		.campus-barra-movil {
			display: none;
		}
	}

	@media (max-width: 61.999rem) {
		/* En móvil el envío vive en la barra fija: un solo botón visible,
		 * un solo punto de tabulación. */
		.campus-resumen__boton {
			display: none;
		}
	}

	/* =================================================================
	 * 11. Movimiento reducido
	 *
	 * Acotado a .campus: desactivar las animaciones del tema entero no es
	 * asunto de este plugin.
	 * ================================================================= */

	@media (prefers-reduced-motion: reduce) {
		.campus,
		.campus *,
		.campus *::before,
		.campus *::after {
			animation-duration: 0.001ms;
			animation-iteration-count: 1;
			transition-duration: 0.001ms;
			scroll-behavior: auto;
		}
	}

	/* =================================================================
	 * 12. Impresión — la ficha que una familia deja en la nevera
	 * ================================================================= */

	@media print {
		.campus-barra-movil,
		.campus-boton,
		.campus-portada__medida {
			display: none;
		}

		.campus-portada,
		.campus-resumen,
		.campus-escalon--completo {
			color: #000000;
			background: none;
		}

		.campus-form__cuerpo {
			display: block;
		}
	}
}
