/*
Theme Name: Darori Studio
Theme URI: https://daroristudio.com
Author: Darori Studio
Description: Tema de bloques neobrutalista construido sobre el logotipo de Darori Studio: negro de trazo grueso, formas bubble, destellos de cuatro puntas y anillos orbitales, en rosa y amarillo pastel.
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 8.0
Version: 2.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: darori
Tags: full-site-editing, block-patterns, portfolio, one-column, custom-colors, custom-menu
*/

/* =========================================================================
   0 · FALLBACKS TIPOGRÁFICOS (métricas ajustadas → sin salto al cargar)
   ====================================================================== */
@font-face {
	font-family: "Archivo Fallback";
	src: local("Helvetica Neue"), local("Arial");
	size-adjust: 97%;
	ascent-override: 92%;
	descent-override: 24%;
	line-gap-override: 0%;
}
@font-face {
	font-family: "Bricolage Fallback";
	src: local("Helvetica Neue Bold"), local("Arial Bold"), local("Arial");
	size-adjust: 101%;
	ascent-override: 90%;
	descent-override: 22%;
	line-gap-override: 0%;
}

/* =========================================================================
   1 · TOKENS
   El sistema sale del logotipo: dos pasteles, negro puro de trazo muy
   grueso y esquinas de burbuja. Nada más entra en la paleta.
   ====================================================================== */
:root {
	--paper: var(--wp--preset--color--paper, #FDF7E4);
	--paper-2: var(--wp--preset--color--paper-2, #F6EDD3);
	--ink: var(--wp--preset--color--ink, #0D0D0D);
	--pink: var(--wp--preset--color--pink, #F294C4);
	--pink-soft: var(--wp--preset--color--pink-soft, #FBDDEC);
	--yellow: var(--wp--preset--color--yellow, #FAEF8C);
	--yellow-soft: var(--wp--preset--color--yellow-soft, #FDF7C2);
	--shock: var(--wp--preset--color--shock, #FF1F7D);
	--white: var(--wp--preset--color--white, #FFFFFF);

	/* Tinta secundaria: 7.4:1 sobre crema — AA de sobra en texto pequeño */
	--ink-soft: #4C4742;
	/* Secundaria sobre negro: 8.1:1 */
	--ink-invert-soft: #C6BEB4;

	--ff-display: var(--wp--preset--font-family--display);
	--ff-body: var(--wp--preset--font-family--body);
	--ff-mono: var(--wp--preset--font-family--mono);

	/* Trazo: el logo tiene contorno muy grueso. Tres pesos, ni uno más. */
	--stroke-hair: 2px;
	--stroke: 3px;
	--stroke-bold: 4.5px;

	/* Sombra dura, sin desenfoque, siempre abajo-derecha. Cuatro pasos. */
	--shadow-xs: 3px 3px 0 var(--ink);
	--shadow-sm: 6px 6px 0 var(--ink);
	--shadow: 10px 10px 0 var(--ink);
	--shadow-lg: 14px 14px 0 var(--ink);

	/* Burbuja: el radio es grande a propósito, es la firma del logotipo. */
	--radius-sm: 10px;
	--radius: 18px;
	--radius-lg: 28px;
	--radius-pill: 999px;

	/* Con `viewport-fit=cover` la página llega al borde físico, así que en
	   horizontal el notch se comería el margen de un lado. El margen nunca
	   baja de lo que ocupa la esquina segura. */
	--gutter: max(clamp(1.1rem, 0.2rem + 3.4vw, 4rem), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
	--rail: 1180px;
	--rail-wide: 1600px;

	--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
	--ease-io: cubic-bezier(0.65, 0, 0.35, 1);
	--ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
	--t-micro: 130ms;
	--t: 180ms;
	--t-enter: 460ms;

	--header-h: 74px;

	/* Flecha dibujada. El carácter "→" (U+2192) NO está en el subconjunto de
	   Martian Mono, así que caía a la mono del sistema: otro peso, otro ancho
	   y otra altura de línea. Dibujada hereda color y se centra por flexbox. */
	--arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.5 12h15M12.5 5.5 19 12l-6.5 6.5' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

	/* Barras del menú, dibujadas: el icono por defecto de WordPress es un SVG
	   fino de 24 px que no pega con un sistema de trazo de 3 px. */
	--burger: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 18'%3E%3Cg stroke='%23000' stroke-width='3.2' stroke-linecap='round'%3E%3Cpath d='M2 3h20'/%3E%3Cpath d='M2 9h20'/%3E%3Cpath d='M2 15h20'/%3E%3C/g%3E%3C/svg%3E");
	--equis: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cg stroke='%23000' stroke-width='3.2' stroke-linecap='round'%3E%3Cpath d='M3 3l12 12'/%3E%3Cpath d='M15 3L3 15'/%3E%3C/g%3E%3C/svg%3E");

	/* Destello de cuatro puntas del logotipo, como máscara reutilizable */
	--spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 0C53.5 30.5 69.5 46.5 100 50C69.5 53.5 53.5 69.5 50 100C46.5 69.5 30.5 53.5 0 50C30.5 46.5 46.5 30.5 50 0Z' fill='%23000'/%3E%3C/svg%3E");
}

/* =========================================================================
   2 · BASE
   ====================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
	/* clip, no hidden: hidden convierte body en contenedor de scroll,
	   rompe el scroll de la página y anula position:sticky.
	   Y no se quita: sin esto, en iPhone se puede arrastrar la página de lado.
	   La pila de cintas además se recorta ella sola (§9), pero este recorte se
	   queda como red: cualquier giro o sombra que se salga por un píxel no
	   debe convertirse en scroll lateral. */
	overflow-x: clip;
	scroll-behavior: smooth;
	/* Con el notch la cabecera es más alta, y un salto de ancla que no lo tenga
	   en cuenta deja el destino medio tapado. */
	scroll-padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + 1.5rem);
	-webkit-text-size-adjust: 100%;
}

body {
	overflow-x: clip;
	position: relative;
	min-height: 100vh;
	background-color: var(--paper);
	color: var(--ink);
	font-optical-sizing: auto;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	font-synthesis-weight: none;
}

/* Grano de papel al 4%: envejece los pasteles sin tocar el contraste. */
body::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 9999;
	pointer-events: none;
	opacity: 0.5;
	mix-blend-mode: multiply;
	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.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.085'/%3E%3C/svg%3E");
}

img, svg, video, canvas { max-width: 100%; height: auto; display: block; }

::selection { background: var(--ink); color: var(--paper); }

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
	outline: 3px solid var(--ink);
	outline-offset: 3px;
	border-radius: var(--radius-sm);
}

.skip-link:focus {
	position: fixed !important;
	top: 0.6rem;
	left: 0.6rem;
	z-index: 10000;
	width: auto;
	height: auto;
	clip: auto;
	clip-path: none;
	padding: 0.9rem 1.2rem;
	background: var(--yellow);
	color: var(--ink);
	border: var(--stroke) solid var(--ink);
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-xs);
	font-family: var(--ff-mono);
	font-size: 0.7rem;
	text-transform: uppercase;
	text-decoration: none;
}

/* =========================================================================
   3 · TIPOGRAFÍA
   ====================================================================== */
h1, h2, h3, h4, h5, h6,
.wp-block-post-title,
.wp-block-query-title {
	text-wrap: balance;
	hyphens: none;
	/* Red de seguridad: si alguien escribe una palabra que no cabe, se parte
	   en vez de salirse de la caja y quedar cortada por el overflow. */
	overflow-wrap: break-word;
}

p { text-wrap: pretty; }

.is-style-display,
.t-display {
	font-family: var(--ff-display) !important;
	font-weight: 800 !important;
	letter-spacing: -0.035em !important;
	line-height: 0.9 !important;
	text-transform: uppercase;
}

/* Laminado mono: la etiqueta del sistema.
   `.is-style-eyebrow` va aquí porque esa variante SÍ estaba registrada en el
   editor pero no tenía ni una regla: quien la elegía veía que no pasaba nada. */
.eyebrow,
.is-style-eyebrow,
.section-index,
.laminate {
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	line-height: 1.45;
	color: var(--ink);
	margin: 0;
}

/* Marca de sección: destello del logo + texto */
.eyebrow.has-rule,
.section-index {
	display: flex;
	align-items: center;
	gap: 0.6rem;
}
.eyebrow.has-rule::before,
.section-index::before {
	content: "";
	width: 0.95em;
	height: 0.95em;
	flex: none;
	background: currentColor;
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
}

/* Destello suelto, usable en cualquier sitio */
.spark {
	display: inline-block;
	width: 1em;
	height: 1em;
	vertical-align: -0.1em;
	background: currentColor;
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
}
.spark--spin { animation: spin 9s linear infinite; }

.chip {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	line-height: 1;
	padding: 0.65em 1em 0.6em;
	border: var(--stroke-hair) solid currentColor;
	border-radius: var(--radius-pill);
	white-space: nowrap;
}

.lead,
.is-style-lead {
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.5;
	font-weight: 430;
	max-width: 54ch;
	/* El layout "constrained" de WP centra con margin auto: lo anulamos para
	   que la entradilla quede alineada con su titular y no flotando al medio. */
	margin-inline: 0;
	color: var(--ink);
	text-wrap: pretty;
}

.measure { max-width: 62ch; margin-inline: 0; }

/* Resaltado rotulador — envuelve varias líneas sin romperse */
mark, .hl {
	background: var(--yellow);
	color: var(--ink);
	border: var(--stroke) solid var(--ink);
	border-radius: var(--radius-sm);
	box-shadow: 0.1em 0.11em 0 var(--ink);
	padding: 0.02em 0.18em;
	margin: 0 0.05em;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
}
.hl--pink { background: var(--pink); }
.hl--yellow { background: var(--yellow); }
.hl--paper { background: var(--paper); }
.hl--white { background: var(--white); }

/* Versión sticker: bloque rotado, sólo para palabras sueltas.
   El inline-block crece la caja de línea, así que el titular que lo lleva
   necesita algo más de interlineado (ver .hero__title). */
.hl--sticker {
	display: inline-block;
	transform: rotate(-2.6deg);
	padding: 0.01em 0.2em 0.05em;
	border-radius: var(--radius);
	box-shadow: var(--shadow-xs);
}
.hl--sticker-r { transform: rotate(2.2deg); }

/* Los cuatro formatos de la barra de herramientas.
   La API de formatos de WordPress asocia cada formato a UNA sola clase, así
   que aquí se combina lo que en el marcado escrito a mano son varias
   (`hl hl--pink hl--sticker`). El aspecto es exactamente el mismo. */
mark.hl--rosa { background: var(--pink); }
mark.hl--amarillo { background: var(--yellow); }
mark.hl--pegatina-rosa,
mark.hl--pegatina-amarilla {
	display: inline-block;
	transform: rotate(-2.6deg);
	padding: 0.01em 0.2em 0.05em;
	border-radius: var(--radius);
	box-shadow: var(--shadow-xs);
}
mark.hl--pegatina-rosa { background: var(--pink); }
mark.hl--pegatina-amarilla { background: var(--yellow); }

:where(h1, h2, h3) :where(mark, .hl) { position: relative; z-index: 1; line-height: 1; }

/* Un titular con resaltado necesita más interlineado: la caja del rotulador
   (relleno + borde) sobresale de la línea y, con leading de display, se
   comería la línea de encima. Se aplica solo cuando hay resaltado. */
:where(h1, h2, h3, h4):has(mark),
:where(h1, h2, h3, h4):has(.hl) { line-height: 1.16 !important; }

/* Tipo con contorno — repeticiones decorativas del wordmark */
.t-outline {
	color: transparent;
	-webkit-text-stroke: 2.5px var(--ink);
	paint-order: stroke fill;
}

.tnum, .stat__n, .rider__n, .servicio__n { font-variant-numeric: tabular-nums; }

/* Flecha del sistema: es un elemento flex más, así que el gap la separa del
   texto y align-items la centra. Nada de glifos con métricas ajenas. */
.wp-block-button__link::after,
.proyecto-card__more::after,
.servicio__go::after,
.wp-block-post-navigation-link.post-navigation-link-next::after,
.wp-block-post-navigation-link.post-navigation-link-previous::before {
	content: "";
	flex: none;
	width: 1.05em;
	height: 1.05em;
	background: currentColor;
	-webkit-mask: var(--arrow) center / contain no-repeat;
	mask: var(--arrow) center / contain no-repeat;
}
.wp-block-post-navigation-link.post-navigation-link-previous::before { rotate: 180deg; }
/* Sin proyecto adyacente WordPress deja el contenedor vacío; sin esto se
   quedaba la flecha suelta flotando en el primer y en el último. */
.wp-block-post-navigation-link:empty { display: none; }

/* =========================================================================
   4 · ENLACES
   ====================================================================== */
a { color: inherit; }

/* Subrayado animado sólo en texto corrido. Se excluye todo lo que lleva
   clase BEM propia para que no aparezca una línea fantasma bajo los
   títulos de tarjeta, que son <a> a ancho completo. */
.content-link,
.entry-content :where(p, li, cite, dd, figcaption, blockquote) a:not(.wp-block-button__link):not(.wp-block-file__button):not([class*="__"]) {
	background-image: linear-gradient(currentColor, currentColor);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 2px;
	padding-bottom: 0.08em;
	text-decoration: none;
	transition: background-size var(--t) var(--ease-out);
}
.content-link:hover,
.entry-content :where(p, li, cite, dd, figcaption, blockquote) a:not(.wp-block-button__link):not(.wp-block-file__button):not([class*="__"]):hover {
	background-size: 100% 8px;
}

.proyecto-card__title a,
.proyecto-card__tags a,
.hero__scroll a,
.next-project a,
.eyebrow a, .chip a, .laminate a,
.wp-block-post-terms a,
.wp-block-post-navigation-link a,
.footer-links a,
/* `.site-header a` a secas también alcanzaba al <a> del botón "Hablamos", y le
   anulaba el relleno inferior: el texto quedaba pegado al borde de abajo y el
   botón medía 31 px en vez de 44. Se gana por especificidad (0,1,1) contra la
   regla global del botón (0,1,0), así que no se nota hasta que se mide. */
.site-header a:not(.wp-element-button),
.cta__mail,
.site-footer .footer-wordmark a {
	background-image: none !important;
	padding-bottom: 0;
	text-decoration: none;
}

/* =========================================================================
   5 · BOTONES — física de burbuja: levantan y luego se hunden
   ====================================================================== */
.wp-block-button__link,
.wp-element-button {
	display: inline-flex;
	align-items: center;
	/* Centrado explícito: si una etiqueta larga parte en dos líneas, el
	   flex-start por defecto la dejaría pegada a la izquierda. */
	justify-content: center;
	text-align: center;
	gap: 0.55em;
	position: relative;
	overflow: hidden;
	box-shadow: var(--shadow-xs);
	transition: transform var(--t-micro) var(--ease-pop),
		box-shadow var(--t-micro) var(--ease-out),
		background-color var(--t) var(--ease-out),
		color var(--t) var(--ease-out);
	text-decoration: none !important;
	white-space: nowrap;
}
.wp-block-button__link:hover,
.wp-element-button:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-sm); }
.wp-block-button__link:active,
.wp-element-button:active { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink); }

.wp-block-button.is-style-pink .wp-block-button__link { background: var(--pink); color: var(--ink); }
.wp-block-button.is-style-yellow .wp-block-button__link { background: var(--yellow); color: var(--ink); }
.wp-block-button.is-style-shock .wp-block-button__link { background: var(--shock); color: var(--ink); }
.wp-block-button.is-style-paper .wp-block-button__link { background: var(--paper); color: var(--ink); }
.wp-block-button.is-style-white .wp-block-button__link { background: var(--white); color: var(--ink); }
.wp-block-button.is-style-outline .wp-block-button__link {
	background: transparent;
	color: currentColor;
	border-color: currentColor;
	box-shadow: none;
}
.wp-block-button.is-style-outline .wp-block-button__link::before { display: none; }
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--shock);
	color: var(--ink);
	border-color: var(--ink);
	box-shadow: var(--shadow-xs);
}
.wp-block-button.is-style-square .wp-block-button__link { border-radius: var(--radius-sm); }

.wp-block-button.is-style-pink .wp-block-button__link:hover,
.wp-block-button.is-style-yellow .wp-block-button__link:hover,
.wp-block-button.is-style-paper .wp-block-button__link:hover,
.wp-block-button.is-style-white .wp-block-button__link:hover { background: var(--shock); color: var(--ink); }
.wp-block-button.is-style-shock .wp-block-button__link:hover { background: var(--ink); color: var(--paper); }

/* --- Variaciones de sección -------------------------------------------
   Las cuatro variaciones de /styles pintan el fondo y el color base desde
   JSON. La inversión fina sobre negro —entradillas, etiquetas, botones de
   contorno— NO se duplica ahí: se reaprovechan las reglas que ya existían
   para `.has-ink-background-color`, que llevan tiempo probadas. Un fondo, dos
   sitios donde definirlo, es la receta para que uno se quede atrás. */
.has-ink-background-color .wp-block-button.is-style-outline .wp-block-button__link,
.is-style-fondo-negro .wp-block-button.is-style-outline .wp-block-button__link { color: var(--paper); }

/* --- Los botones con el dedo -------------------------------------------
   Dos cosas distintas que se juntaban en el mismo toque:

   1. iOS dibuja SU destello al tocar —un negro translúcido por encima del
      elemento— y no había nada que se lo impidiera. Sobre un botón negro no
      se nota, pero al tocarlo pasa a rosa flúor y ahí el negro translúcido lo
      convertía en un rosa sucio, apagado. Ése era el color feo: no es
      ninguno de la paleta, es el rosa de la paleta ensuciado por encima.

   2. En una pantalla táctil no existe el hover: iOS lo emula y se queda
      PEGADO hasta que tocas otra cosa. Así que el botón se quedaba levantado
      y en rosa después de soltarlo, como si siguiera bajo el cursor.

   Se quita el destello del sistema, y en pantallas sin ratón el hover deja de
   cambiar nada: el aviso de "te he leído" lo da `:active`, que dura lo que
   dura el dedo encima, que es justo lo que se espera al pulsar algo.
   ---------------------------------------------------------------------- */
a,
button,
label,
select,
summary,
textarea,
input,
.wp-block-button__link,
.wp-element-button { -webkit-tap-highlight-color: transparent; }

/* El cromo no es texto: mantener pulsado un botón o la cápsula no debe sacar
   el menú de selección de iOS ni dejar media palabra resaltada. Va sólo en lo
   que es un control; la prosa se sigue pudiendo seleccionar y copiar. */
.wp-block-button__link,
.wp-element-button,
.dock,
.dock__menu,
.dock__cta,
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	user-select: none;
}

@media (hover: none) {
	/* Sin levantar el botón: quedaría flotando después de soltarlo. */
	.wp-block-button__link:hover,
	.wp-element-button:hover { transform: none; box-shadow: var(--shadow-xs); }

	/* Y sin cambiar de color. Cada variante se queda en el suyo de reposo;
	   hay que repetirlos porque "volver al color base" no se puede pedir en
	   una sola regla cuando el base lo pone cada variante por su cuenta. */
	:root :where(.wp-element-button:hover, .wp-block-button__link:hover) {
		background-color: var(--ink);
		color: var(--paper);
	}
	.wp-block-button.is-style-pink .wp-block-button__link:hover { background: var(--pink); color: var(--ink); }
	.wp-block-button.is-style-yellow .wp-block-button__link:hover { background: var(--yellow); color: var(--ink); }
	.wp-block-button.is-style-shock .wp-block-button__link:hover { background: var(--shock); color: var(--ink); }
	.wp-block-button.is-style-paper .wp-block-button__link:hover { background: var(--paper); color: var(--ink); }
	.wp-block-button.is-style-white .wp-block-button__link:hover { background: var(--white); color: var(--ink); }
	.wp-block-button.is-style-outline .wp-block-button__link:hover {
		background: transparent;
		color: currentColor;
		border-color: currentColor;
		box-shadow: none;
	}

	/* El pulsado: se hunde en su sombra y se enciende en flúor mientras el
	   dedo está encima. Y llega SIN transición, que es la parte importante.

	   Con los 180 ms de transición de color puestos, un toque de móvil dura
	   menos que el viaje: `:active` se iba antes de llegar al destino y sólo
	   se veía el punto medio. Y el punto medio de negro a flúor es #861645,
	   un vino sucio; el del texto, de crema a negro, un gris malva. Ésos eran
	   "los colores raros": no salen de la paleta, son el barro del camino.

	   Un aviso de pulsado tiene que ser instantáneo por definición: si tarda,
	   ya no avisa. Al soltar sí vuelve con calma, porque ahí manda otra vez la
	   transición de reposo. */
	.wp-block-button__link:active,
	.wp-element-button:active {
		background: var(--shock);
		color: var(--ink);
		transform: translate(3px, 3px);
		box-shadow: 0 0 0 var(--ink);
		transition: none;
	}
	.wp-block-button.is-style-shock .wp-block-button__link:active { background: var(--ink); color: var(--paper); }

	/* Misma historia en la cápsula: el amarillo del pulsado tardaba 180 ms en
	   llegar y sólo se veía el punto medio contra el crema y el rosa. */
	.dock__menu:active,
	.dock__cta:active { transition: none; }
}

/* =========================================================================
   6 · SUPERFICIES
   ====================================================================== */
.is-style-card, .card {
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}
.is-style-panel {
	border-top: var(--stroke-bold) solid var(--ink);
	border-bottom: var(--stroke-bold) solid var(--ink);
}
/* Un solo trazo entre bloques contiguos. La cabecera ya lleva borde inferior
   y los paneles borde superior: juntos dibujaban una línea doble de 9 px. */
.entry-content > .is-style-panel:first-child,
main > .is-style-panel:first-child,
main > .alignfull.is-style-panel:first-child,
.is-style-panel + .is-style-panel,
.proyecto-hero + .is-style-panel { border-top: 0; }

.is-style-rule-top { border-top: var(--stroke-bold) solid var(--ink); padding-top: var(--wp--preset--spacing--50); }
.is-style-frame img, .is-style-frame.wp-block-image img {
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}


/* Sobre negro, el texto secundario tiene su propio tono legible */
.has-ink-background-color,
.is-style-fondo-negro,
.has-ink-background-color :where(h1, h2, h3, h4, h5, h6, p, li, cite),
.is-style-fondo-negro :where(h1, h2, h3, h4, h5, h6, p, li, cite) { color: var(--paper); }
.has-ink-background-color .lead,
.has-ink-background-color .is-style-lead,
.is-style-fondo-negro .lead,
.is-style-fondo-negro .is-style-lead { color: var(--ink-invert-soft); }
/* Islas de color dentro de una sección oscura.
   -----------------------------------------------------------------------
   La inversión de arriba alcanza a CUALQUIER titular o párrafo descendiente,
   y eso incluye los que van dentro de una tarjeta con fondo claro propio: el
   crema sobre rosa o sobre amarillo no se lee. Cada componente con fondo
   propio recupera su tinta.

   Era un fallo latente desde antes: sólo salía a la luz al poder poner
   cualquier sección en negro, porque hasta ahora la única oscura no llevaba
   tarjetas dentro. */
:is(.has-ink-background-color, .is-style-fondo-negro) :is(
	.pass, .rider__card, .stat, .quote-card, .card, .is-style-card,
	.faq__item, .wp-block-details, .proyecto-meta, .badge-float,
	.ticker--pink, .ticker--yellow, .ticker--paper, .lineup > li
) {
	color: var(--ink);
}
:is(.has-ink-background-color, .is-style-fondo-negro) :is(
	.pass, .rider__card, .stat, .quote-card, .card, .is-style-card,
	.faq__item, .wp-block-details, .proyecto-meta, .badge-float,
	.ticker--pink, .ticker--yellow, .ticker--paper, .lineup > li
) :is(h1, h2, h3, h4, h5, h6, p, li, cite, .lead, .is-style-lead, .eyebrow, .laminate) {
	color: var(--ink);
}

.has-ink-background-color .eyebrow,
.has-ink-background-color .section-index,
.has-ink-background-color .laminate,
.is-style-fondo-negro .eyebrow,
.is-style-fondo-negro .section-index,
.is-style-fondo-negro .laminate { color: var(--paper); }

/* =========================================================================
   7 · LAYOUT / AJUSTES DEL NÚCLEO
   ====================================================================== */
:where(.wp-site-blocks) > * { margin-block: 0; }

.section { position: relative; padding-block: var(--wp--preset--spacing--80); }
.section--tight { padding-block: var(--wp--preset--spacing--70); }

.section-head { margin-bottom: var(--wp--preset--spacing--60); }
.section-head > * + * { margin-top: var(--wp--preset--spacing--40); }

/* El margen lateral vive en el contenedor de sección, no en el raíl.
   Las secciones son `alignfull` con layout "default" y WordPress sólo
   reparte el padding global dentro de contenedores "constrained": sin esto,
   por debajo de 1180 px el contenido se pegaba al borde y las sombras duras
   salían cortadas. Y NO puede ir en `.rail`, porque dentro de un contexto
   constrained WordPress ya le inyecta padding y se duplicaba. */
.section,
.section--tight,
.hero,
.proyecto-hero { padding-inline: var(--gutter); }

/* Se anula el padding que WordPress inyecta en los hijos de un `alignfull`.
   Doble clase para empatar en especificidad con la regla del núcleo. */
.wp-block-group.rail,
.wp-block-group.rail-wide {
	width: 100%;
	margin-inline: auto;
	padding-inline: 0;
}
.wp-block-group.rail { max-width: var(--rail); }
.wp-block-group.rail-wide { max-width: var(--rail-wide); }

.wp-block-group.alignfull { position: relative; }

hr.wp-block-separator {
	border: 0;
	border-top: var(--stroke) solid currentColor;
	opacity: 1;
	margin-block: var(--wp--preset--spacing--50);
}

.wp-block-list.is-style-checks { list-style: none; padding-left: 0; }
.wp-block-list.is-style-checks li { position: relative; padding-left: 1.9rem; }
.wp-block-list.is-style-checks li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.42em;
	width: 0.85em;
	height: 0.85em;
	background: currentColor;
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
}

/* =========================================================================
   8 · CABECERA
   ====================================================================== */
.site-header {
	position: sticky;
	top: 0;
	z-index: 500;
	background: var(--paper);
	border-bottom: var(--stroke-bold) solid var(--ink);
	/* El relleno de arriba absorbe la franja del notch: la cabecera la pinta
	   con su propio fondo opaco en vez de dejar que se vea pasar la página por
	   detrás. En cualquier pantalla sin notch el `env` vale 0 y esto es
	   exactamente el 0,8rem de siempre. */
	padding-top: calc(0.8rem + env(safe-area-inset-top, 0px));
	padding-bottom: 0.8rem;
	min-height: calc(var(--header-h) + env(safe-area-inset-top, 0px));
	display: flex;
	align-items: center;
	transition: box-shadow var(--t) var(--ease-out), padding var(--t) var(--ease-out);
}
/* La franja de la barra de estado en iPhone.
   -----------------------------------------------------------------------
   Safari dibuja la página por debajo de la barra de estado —de ahí el
   desenfoque translúcido del reloj y la batería— pero la ventana de
   composición empieza POR DEBAJO de esa franja. Los elementos `sticky` se
   anclan a la ventana, así que la cabecera se quedaba justo por debajo y en
   la franja se veía pasar el contenido. Medido en un iPhone 16 Pro en
   vertical: pantalla 402x874, ventana 402x714. 160 px de diferencia.

   Lo que NO lo arregla, probado en el aparato:
     · `theme-color`: Safari lo ignora para esa zona.
     · `viewport-fit=cover`: no agranda la ventana (por eso
       `env(safe-area-inset-top)` da 0 en vertical), sólo cambia dónde pinta.

   Lo que sí: que la cabecera pinte por encima de su propia caja. La franja
   pasa a ser del color de la cabecera. Va fuera de flujo, así que no ocupa
   espacio ni desplaza nada, y en cualquier pantalla sin esa franja queda por
   encima del borde de la ventana y no se ve. 240 px cubren de sobra cualquier
   barra de estado en cualquier orientación. */
.site-header::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 100%;
	height: 240px;
	background: var(--paper);
	pointer-events: none;
}

/* Ojo con el atajo `padding-block` aquí: borraría el hueco del notch que
   reserva la regla de arriba y volvería a abrirse la franja. */
.site-header.is-stuck {
	box-shadow: 0 7px 0 rgba(13, 13, 13, 0.09);
	padding-top: calc(0.5rem + env(safe-area-inset-top, 0px));
	padding-bottom: 0.5rem;
}

/* La barra de cabecera y el pie llevan su propio raíl: el elemento exterior
   lo pinta el bloque template-part, que no tiene layout propio. */
.site-header__inner,
.site-footer__inner {
	width: 100%;
	max-width: var(--rail-wide);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.brand-lockup { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; }

/* Marca: el logotipo original vectorizado, no una reconstrucción. Va en tres
   grupos —órbita, cuerpo y chispa— para poder animarlos por separado.
   No es cuadrado: 1004x726, de ahí el ancho mayor que el alto. */
.brand-mark { display: block; width: 3rem; height: auto; flex: none; line-height: 0; }
.brand-mark svg { display: block; width: 100%; height: auto; overflow: visible; }
.dl-cuerpo,
.dl-orbita,
.dl-chispa { transform-box: fill-box; }

/* --- Entrada: el sello ------------------------------------------------
   Se estampa al cargar: entra pequeño y ladeado, se pasa de frenada y se
   asienta. 260 ms, el mismo muelle corto que usan las tarjetas. Es CSS puro,
   así que si el JS falla la marca aparece igual. */
.brand-mark svg { animation: dl-sello 260ms var(--ease-pop) both; }
@keyframes dl-sello {
	from { opacity: 0; scale: 0.62; rotate: -7deg; }
	60%  { opacity: 1; scale: 1.06; rotate: 1.5deg; }
	to   { opacity: 1; scale: 1; rotate: 0deg; }
}

/* --- El chicle salta -------------------------------------------------
   El disparador es una clase, `.marca-viva`, no `:hover`, y el JS decide
   cuándo ponerla. Con `:hover` la animación no existía en el móvil: en iOS el
   hover es emulado —se queda pegado tras tocar y se va al tocar otra cosa—,
   así que tocar el logotipo navegaba sin llegar a enseñar nada. Ahora el
   ratón la enciende mientras está encima y el dedo la enciende al tocar.

   Secuencia de animación clásica: anticipación (se agacha), estiramiento,
   aplastado al aterrizar y dos rebotes decrecientes. El cuerpo entero va en
   UN solo grupo: si el contorno negro y el relleno rosa se animaran por
   separado, cualquier desfase haría que el borde resbalase fuera.
   Los picos respetan conservación de volumen (sx·sy ≈ 1) y el tope duro de
   1.18 en X, por encima del cual la contraforma de la D se cierra a 48 px. */
.dl-cuerpo { transform-origin: 50% 100%; }
.brand-lockup.marca-viva .dl-cuerpo { animation: dl-salto 440ms both; }
@keyframes dl-salto {
	0%   { scale: 1 1;       translate: 0 0;    animation-timing-function: cubic-bezier(.36,0,.66,-.2); }
	16%  { scale: 1.05 0.92; translate: 0 0;    animation-timing-function: cubic-bezier(.18,1.25,.3,1); }
	40%  { scale: 0.93 1.09; translate: 0 -2%;  animation-timing-function: cubic-bezier(.5,0,.1,1); }
	66%  { scale: 1.08 0.93; translate: 0 0;    animation-timing-function: cubic-bezier(.3,0,.2,1); }
	85%  { scale: 0.99 1.02; translate: 0 0;    animation-timing-function: ease-in-out; }
	100% { scale: 1 1;       translate: 0 0; }
}
/* Al salir no se repite la anticipación: parecería un tic nervioso. */
.brand-lockup:not(.marca-viva) .dl-cuerpo { animation: dl-posarse 260ms cubic-bezier(.4,0,.2,1) both; }
@keyframes dl-posarse {
	0%   { scale: 1.02 0.98; }
	55%  { scale: 0.995 1.01; }
	100% { scale: 1 1; }
}

/* El brillo NO es una pegatina: es luz. Una luz especular no viaja con el
   objeto, la fija la fuente y la curvatura. Como hereda el aplastado del
   cuerpo, aquí se le aplica el movimiento CONTRARIO para que se quede donde
   está mientras la superficie resbala por debajo. Ese contramovimiento es la
   señal que lo hace leerse como reflejo. */
.dl-brillo { transform-origin: 45% 28%; }
.brand-lockup.marca-viva .dl-brillo { animation: dl-luz 440ms ease-in-out 50ms both; }
@keyframes dl-luz {
	0%   { scale: 1 1;    translate: 0 0; }
	40%  { scale: 1 0.93; translate: 0 1.6%; }
	66%  { scale: 1 1.06; translate: 0 -1%; }
	100% { scale: 1 1;    translate: 0 0; }
}

/* El anillo son arcos de una elipse inclinada: girarlo en el plano lo
   despegaría del dibujo. Se le da un pulso de scaleY anclado en su centro,
   que es justo donde cruza por detrás de la burbuja: los cruces se quedan
   quietos y solo flexionan los extremos. Se lee como un cabeceo en 3D, que
   es como reacciona un aro rígido a un tirón. Nunca scaleX, nunca rotate. */
.dl-orbita { transform-origin: 50% 50%; }
.brand-lockup.marca-viva .dl-orbita { animation: dl-orbita 300ms cubic-bezier(.2,.8,.2,1) 50ms both; }
@keyframes dl-orbita {
	0%, 100% { scale: 1 1; }
	42%      { scale: 1 1.09; }
}

/* La chispa es lo último en pararse: la energía disipándose. */
.dl-chispa { transform-origin: 50% 50%; }
.brand-lockup.marca-viva .dl-chispa { animation: dl-chispa 340ms cubic-bezier(.2,1.4,.3,1) 110ms both; }
@keyframes dl-chispa {
	0%, 100% { scale: 1; rotate: 0deg; }
	50%      { scale: 1.32; rotate: 35deg; }
}

/* El color SE QUEDA mientras el puntero siga encima: el rebote es un golpe
   de un solo uso, pero el estado de "esto es pulsable" tiene que sostenerse.
   La entrada usa steps(2): un color plano de pegatina no hace degradado, da
   el salto. La salida sí es suave, para no llamar la atención al irse.
   Para volver al flúor basta cambiar --yellow por --shock aquí abajo. */
.dl-burbuja { transition: fill 240ms var(--ease-out); }
.brand-lockup.marca-viva .dl-burbuja {
	fill: var(--yellow);
	transition: fill 140ms steps(2, end);
}
/* El brillo pasa a un negro muy rebajado sobre el propio amarillo: se lee como
   sombra de la forma, no como línea entintada. Descartado el claro (sobre
   amarillo desaparece) y el negro pleno (a 48 px pesa demasiado).
   Se escribe con color-mix para que siga atado a los tokens de la paleta; el
   literal de delante es el mismo color, para navegadores sin color-mix. */
.dl-brillo { transition: fill 240ms var(--ease-out); }
.brand-lockup.marca-viva .dl-brillo {
	fill: #A7A060;
	fill: color-mix(in srgb, var(--ink) 35%, var(--yellow));
	transition: fill 140ms steps(2, end);
}

/* La capa de composición se reserva sólo mientras hay movimiento. */
.brand-lockup.marca-viva .dl-cuerpo,
.brand-lockup.marca-viva .dl-brillo,
.brand-lockup.marca-viva .dl-orbita { will-change: transform; }

.wp-block-site-title a { text-decoration: none; }


.site-header .wp-block-navigation { gap: clamp(1rem, 2vw, 2rem); }
.site-header .wp-block-navigation-item__content {
	position: relative;
	padding-block: 0.35rem;
	text-decoration: none;
}
.site-header .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 3px;
	border-radius: var(--radius-pill);
	background: var(--ink);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.32s var(--ease-out);
}
.site-header .wp-block-navigation-item__content:hover::after,
.site-header .current-menu-item .wp-block-navigation-item__content::after { transform: scaleX(1); }

.site-header .wp-block-navigation__responsive-container-open,
.site-header .wp-block-navigation__responsive-container-close { color: var(--ink); }

.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--paper) !important;
	padding: calc(var(--header-h) + 1.5rem) var(--gutter) var(--gutter) !important;
}
.is-menu-open .wp-block-navigation__responsive-container-content { width: 100%; }
.is-menu-open .wp-block-navigation__container {
	align-items: stretch !important;
	justify-content: flex-start !important;
	gap: 0 !important;
	width: 100%;
}
.is-menu-open .wp-block-navigation-item {
	width: 100%;
	border-bottom: var(--stroke) solid var(--ink);
	/* La navegación de escritorio está justificada a la derecha; dentro del
	   menú desplegado todo vuelve a alinearse a la izquierda. */
	text-align: left;
}
.is-menu-open .wp-block-navigation-item__content {
	display: block;
	width: 100%;
	padding: 1.05rem 0 !important;
	font-family: var(--ff-display) !important;
	font-size: clamp(1.9rem, 8vw, 2.9rem) !important;
	font-weight: 800 !important;
	letter-spacing: -0.03em !important;
	text-transform: uppercase;
	line-height: 1 !important;
}
.is-menu-open .wp-block-navigation-item__content::after { display: none; }

/* El CTA sólo existe dentro del menú desplegado: en escritorio ese sitio
   lo ocupa el botón "Hablamos" de la cabecera. */
.site-header .wp-block-navigation-item.nav-cta { display: none; }
.is-menu-open .wp-block-navigation-item.nav-cta {
	display: block;
	border-bottom: 0;
	margin-top: 2.2rem;
	/* La navegación de escritorio va justificada a la derecha y el botón
	   heredaba esa alineación dentro del desplegable. */
	text-align: left;
}
.is-menu-open .nav-cta .wp-block-navigation-item__content {
	display: inline-block !important;
	width: auto;
	padding: 1.1rem 1.9rem !important;
	background: var(--pink);
	border: var(--stroke) solid var(--ink);
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-xs);
	font-family: var(--ff-mono) !important;
	font-size: 0.8rem !important;
	font-weight: 600 !important;
	font-stretch: 87.5%;
	letter-spacing: 0.02em !important;
}

/* La barra de administración y la cabecera pegajosa.
   -----------------------------------------------------------------------
   ESTE era el hueco del iPhone. En escritorio la barra de WordPress es
   `position: fixed`, se queda arriba, y anclar la cabecera 32 px más abajo es
   lo correcto. Pero por debajo de 783 px WordPress la pone en
   `position: absolute`: se va con el scroll. La cabecera, en cambio, seguía
   clavada a `top: 46px` para siempre, así que en cuanto la barra se iba
   quedaba una franja de 46 px transparente arriba del todo por la que se veía
   pasar la página — justo debajo del notch, y sólo estando con la sesión
   iniciada, que es como se prueba en local.
   Medido: con scroll a 1200, barraY=-1154 y cabeceraY=46. 46 px al aire.

   Son TRES tramos, no dos, y el corte de la barra no es donde parece:
     · > 782 px  → fija, 32 px de alto.
     · 601-782   → fija todavía, pero 46 px de alto.
     · <= 600 px → `position: absolute`: se va con el scroll, y la cabecera
                   tiene que subir hasta arriba del todo.
   El corte a `absolute` está en 600, no en 782 (admin-bar.css del núcleo).
   Anclarla a 0 en todo el tramo <=782 metía la cabecera por debajo de la
   barra en tabletas, que es donde la barra sí sigue fija. */
.admin-bar .site-header { top: 32px; }
@media screen and (max-width: 782px) { .admin-bar .site-header { top: 46px; } }
@media screen and (max-width: 600px) { .admin-bar .site-header { top: 0; } }

/* =========================================================================
   9 · TICKER
   ====================================================================== */
.ticker {
	overflow: hidden;
	background: var(--ink);
	color: var(--paper);
	border-block: var(--stroke-bold) solid var(--ink);
	padding-block: 0.75rem;
	user-select: none;
}
.ticker--pink { background: var(--pink); color: var(--ink); }
.ticker--yellow { background: var(--yellow); color: var(--ink); }
.ticker--shock { background: var(--shock); color: var(--ink); }
.ticker--paper { background: var(--paper); color: var(--ink); }

.ticker__track {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	width: max-content;
	will-change: transform;
	animation: ticker-l 38s linear infinite;
}
.ticker--reverse .ticker__track { animation-name: ticker-r; }

.ticker__item {
	display: inline-flex;
	align-items: center;
	gap: 1.1rem;
	margin: 0;
	font-family: var(--ff-mono);
	font-size: clamp(0.72rem, 0.62rem + 0.35vw, 0.92rem);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1;
	padding-inline: 1.1rem;
	white-space: nowrap;
}
/* Separador: el destello del logotipo */
.ticker__item::after {
	content: "";
	width: 0.85em;
	height: 0.85em;
	flex: none;
	background: currentColor;
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
}

@keyframes ticker-l { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
@keyframes ticker-r { from { transform: translate3d(-50%, 0, 0); } to { transform: translate3d(0, 0, 0); } }
.ticker:hover .ticker__track { animation-play-state: paused; }

/* Par cruzado: el gesto de cartel. Ancho extra para que la rotación no
   deje esquinas vacías en los bordes del viewport. */
/* Las cintas tienen que sobresalir del ancho de pantalla: van giradas, y si
   midieran justo lo que la ventana, la rotación dejaría las esquinas vacías.
   Antes eso se resolvía con 108vw y márgenes negativos, y el recorte lo hacía
   el documento entero — con el coste que se explica en §2. Ahora la pila mide
   lo que la ventana y recorta ella; las que sobresalen son las cintas de
   dentro. `overflow-y: visible` porque el giro también las saca por arriba y
   por abajo, y ahí no queremos cortar nada. */
/* Las cintas sobresalen del ancho de pantalla a propósito: van giradas, y si
   midieran justo lo que la ventana, el giro dejaría las esquinas vacías. Lo
   que se sale lo recorta el documento (§2).

   Aquí NO se usa un recorte local (`overflow-x: clip` con `overflow-y:
   visible` en la pila): esa mezcla de ejes es justo la que Safari puede no
   honrar, y entonces las cintas se salían un 4% por cada lado y la página se
   arrastraba de lado en el iPhone. Recorte de documento, que es el que
   siempre ha funcionado aquí. */
.ticker-stack {
	position: relative;
	z-index: 2;
	margin-block: clamp(2.6rem, 5vw, 4.6rem);
	width: 108vw;
	margin-inline: -4vw;
}
/* Las dos cintas se cruzan por la rotación; nada de solape con margen
   negativo, que tapaba la mitad de la cinta de arriba. */
.ticker-stack .ticker:first-child { transform: rotate(-1.5deg); }
.ticker-stack .ticker:last-child { transform: rotate(1.2deg); margin-top: 2rem; }

/* =========================================================================
   10 · HÉROE
   ====================================================================== */
.hero {
	position: relative;
	padding-top: clamp(2.4rem, 1.4rem + 4vw, 4.6rem);
	padding-bottom: 0;
}

.hero__status {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	margin: 0;
}
.hero__status::before {
	content: "";
	width: 0.62rem;
	height: 0.62rem;
	border-radius: 50%;
	background: var(--shock);
	border: 2px solid var(--ink);
	flex: none;
	animation: pulse 2.4s var(--ease-io) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.8); } }

.hero__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(2.2rem, 4vw, 3.6rem);
	align-items: start;
	margin-top: clamp(1.5rem, 3vw, 2.4rem);
}
/* En escritorio el pase deja de colgar de la esquina superior. Con
   `align-items: start` la columna de texto seguía casi 200 px por debajo del
   pase y quedaba un hueco muerto abajo a la derecha; centrado, las dos
   columnas se equilibran y el pase parece colgado en la pared, no pegado
   arriba. La columna también crece: a 19 rem el pase era una nota al pie
   junto a un titular de 800 px. */
@media (min-width: 1040px) {
	.hero__grid {
		grid-template-columns: minmax(0, 1fr) clamp(20rem, 23vw, 23rem);
		align-items: center;
	}
}

.hero__title {
	font-size: var(--wp--preset--font-size--giga);
	letter-spacing: -0.048em;
	/* 0.94 y no 0.84: el sticker de "pasen" ensancha la caja de línea y con
	   interlineado más apretado se comería la línea de encima. */
	line-height: 0.94;
	margin: 0;
	text-transform: uppercase;
	text-wrap: balance;
}
.hero__lead { margin-top: clamp(1.4rem, 2.5vw, 2.1rem); max-width: 46ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: clamp(1.7rem, 3vw, 2.5rem); }

/* Pase de backstage flotante */
.pass {
	position: relative;
	background: var(--white);
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow-lg);
	/* El relleno superior lo manda la ranura del cordón, no el gusto: está
	   posicionada en absoluto y si el contenido empieza antes de que ella
	   acabe, "ACCESO" se le mete debajo. Y no vale ponerlo como margen del
	   primer hijo: el soporte de layout de bloques emite
	   `.wp-container-… > :first-child { margin-block-start: 0 }`, que gana
	   por especificidad y lo borra. */
	padding: 2.3rem 1.35rem 1.2rem;
	transform: rotate(2.2deg);
	transition: transform 0.5s var(--ease-pop);
}
@media (hover: hover) { .pass:hover { transform: rotate(-1.2deg) translateY(-5px); } }
.pass::before {
	content: "";
	position: absolute;
	top: 0.85rem;
	left: 50%;
	transform: translateX(-50%);
	width: 3.4rem;
	height: 0.66rem;
	border: var(--stroke-hair) solid var(--ink);
	border-radius: var(--radius-pill);
	background: var(--paper);
}
.pass__head { margin: 0 0 0.9rem; padding-bottom: 0.85rem; border-bottom: var(--stroke) dashed var(--ink); }
.pass__title {
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: 1.45rem;
	line-height: 0.95;
	letter-spacing: -0.032em;
	text-transform: uppercase;
	margin: 0.4rem 0 0;
}
/* El aire hasta el código de barras va como relleno de la lista, no como
   margen del código: los márgenes verticales entre hermanos los reescribe el
   soporte de layout de bloques (`> * + * { margin-block-start: … }`) y el
   relleno no lo toca nadie. */
.pass__rows { display: grid; gap: 0.55rem; margin: 0; padding-bottom: 1.1rem; }
.pass__row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 0.8rem;
	font-family: var(--ff-mono);
	font-size: 0.6875rem;
	font-weight: 500;
	font-stretch: 75%;
	text-transform: uppercase;
	line-height: 1.35;
	margin: 0;
}
.pass__row span:first-child { color: var(--ink-soft); }
.pass__row span:last-child { font-weight: 700; text-align: right; }
.pass__barcode {
	position: relative;
	margin-top: 0;
	height: 2.5rem;
	border-radius: 4px;
	background-image: repeating-linear-gradient(90deg,
		var(--ink) 0 2px, transparent 2px 4px,
		var(--ink) 4px 7px, transparent 7px 9px,
		var(--ink) 9px 10px, transparent 10px 14px);
}

/* --- El pase en escritorio ----------------------------------------------
   A tamaño de escritorio el pase tenía 314 × 280: más ancho que alto, que es
   justo lo que un pase no es. Aquí crece hasta proporción de pase de verdad
   (más alto que ancho) y el interior se reparte en tres pisos con el mismo
   aire: cabecera, datos y código. Nada de esto toca al móvil, donde la
   tarjeta ya está resuelta a ancho completo.
   ---------------------------------------------------------------------- */
@media (min-width: 1040px) {
	/* Arriba, sitio para la ranura; abajo, para el número de serie, que va
	   fuera de flujo (ver más abajo). */
	.pass { padding: 3.4rem 1.6rem 2.15rem; }
	/* La ranura del cordón: si el pase crece y ella no, deja de leerse como
	   una ranura y pasa a ser una pastilla suelta. */
	.pass::before {
		top: 1.05rem;
		width: 4.2rem;
		height: 0.72rem;
	}
	.pass__head {
		margin: 0 0 1.2rem;
		padding-bottom: 1.15rem;
	}
	/* El título ocupa dos líneas a propósito y a cualquier ancho de escritorio:
	   a una línea el pase se quedaba apaisado, y con el tamaño justo unas
	   veces cabía y otras no, así que la tarjeta cambiaba de alto entre
	   anchos. `balance` reparte las palabras en vez de dejar "ÁREAS" sola.
	   Interlineado 1: con 0,92 la tilde de "ÁREAS" tocaba la línea de arriba. */
	.pass__title {
		font-size: clamp(2rem, 2.3vw, 2.35rem);
		line-height: 1;
		/* Relleno y no margen, por lo mismo que en `.pass__rows`. */
		margin-top: 0;
		padding-top: 0.45rem;
		text-wrap: balance;
	}
	.pass__rows { gap: 0.78rem; padding-bottom: 1.6rem; }
	.pass__row {
		font-size: 0.75rem;
		/* 75% de anchura era demasiado condensada para leerse de un vistazo a
		   este tamaño; el resto del sistema usa 87,5%. */
		font-stretch: 87.5%;
		line-height: 1.3;
	}
	.pass__barcode { height: 3.2rem; }
	/* Número de serie. Va en contenido generado, no en el marcado, porque el
	   héroe está guardado en la base de datos y el patrón ya no lo alcanza.
	   Es decorativo, y hereda el aria-hidden del código de barras. */
	.pass__barcode::after {
		content: "Nº DS-0001";
		position: absolute;
		left: 0;
		top: calc(100% + 0.6rem);
		font-family: var(--ff-mono);
		font-size: 0.625rem;
		font-weight: 500;
		font-stretch: 87.5%;
		letter-spacing: 0.06em;
		text-transform: uppercase;
		color: var(--ink-soft);
		line-height: 1;
	}
	.pass__barcode::before {
		content: "2026";
		position: absolute;
		right: 0;
		top: calc(100% + 0.6rem);
		font-family: var(--ff-mono);
		font-size: 0.625rem;
		font-weight: 700;
		font-stretch: 87.5%;
		letter-spacing: 0.06em;
		color: var(--ink);
		line-height: 1;
	}
}

.hero__scroll { margin-top: clamp(2rem, 4vw, 3rem); }
.hero__scroll a {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	text-decoration: none;
}
.hero__scroll a::after {
	content: "↓";
	display: inline-grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border: var(--stroke) solid var(--ink);
	border-radius: 50%;
	animation: bob 2.2s var(--ease-io) infinite;
}
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }

/* =========================================================================
   11 · SERVICIOS — índice editorial, no rejilla de tarjetas
   ====================================================================== */
.servicios { border-top: var(--stroke-bold) solid var(--ink); }

.servicio {
	position: relative;
	display: grid;
	grid-template-columns: 4rem minmax(0, 1fr) auto auto;
	align-items: center;
	gap: clamp(0.9rem, 2.2vw, 2.2rem);
	padding-block: clamp(1.5rem, 2.6vw, 2.4rem);
	padding-inline: clamp(0.8rem, 1.6vw, 1.6rem);
	border-bottom: var(--stroke) solid var(--ink);
	isolation: isolate;
	overflow: hidden;
}
/* Lavado de color que barre desde la izquierda */
.servicio::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: var(--wash, var(--pink));
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.5s var(--ease-out);
}
.servicio:focus-within::before { transform: scaleX(1); }
@media (hover: hover) { .servicio:hover::before { transform: scaleX(1); } }
.servicio:nth-child(4n+1) { --wash: var(--pink); }
.servicio:nth-child(4n+2) { --wash: var(--yellow); }
.servicio:nth-child(4n+3) { --wash: var(--pink-soft); }
.servicio:nth-child(4n+4) { --wash: var(--yellow-soft); }

.servicio__n {
	font-family: var(--ff-mono);
	font-size: 0.78rem;
	font-weight: 700;
	font-stretch: 75%;
	line-height: 1;
	margin: 0;
	align-self: start;
	padding-top: 0.45em;
	color: var(--ink-soft);
	transition: color 0.3s var(--ease-out);
}
.servicio:focus-within .servicio__n { color: var(--ink); }
@media (hover: hover) { .servicio:hover .servicio__n { color: var(--ink); } }

.servicio__body { min-width: 0; }
.servicio__t {
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.7rem, 1.1rem + 2.6vw, 3.2rem);
	line-height: 0.95;
	letter-spacing: -0.035em;
	text-transform: uppercase;
	margin: 0;
	transition: transform 0.45s var(--ease-out);
}
.servicio:focus-within .servicio__t { transform: translateX(0.7rem); }
@media (hover: hover) { .servicio:hover .servicio__t { transform: translateX(0.7rem); } }

.servicio__d {
	margin: 0.6rem 0 0;
	max-width: 52ch;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.55;
	color: var(--ink-soft);
	transition: color 0.3s var(--ease-out);
}
.servicio:focus-within .servicio__d { color: var(--ink); }
@media (hover: hover) { .servicio:hover .servicio__d { color: var(--ink); } }

.servicio__tag {
	margin: 0;
	align-self: center;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1;
	padding: 0.65em 1em 0.6em;
	border: var(--stroke-hair) solid var(--ink);
	border-radius: var(--radius-pill);
	white-space: nowrap;
	background: transparent;
	transition: background-color 0.3s var(--ease-out);
}
.servicio:focus-within .servicio__tag { background: var(--white); }
@media (hover: hover) { .servicio:hover .servicio__tag { background: var(--white); } }

/* Flecha que gira al pasar por encima */
.servicio__go {
	margin: 0;
	align-self: center;
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	flex: none;
	border: var(--stroke) solid var(--ink);
	border-radius: 50%;
	font-size: 0.9rem;
	line-height: 1;
	background: transparent;
	rotate: -45deg;
	transition: rotate 0.45s var(--ease-pop), background-color 0.3s var(--ease-out), color 0.3s var(--ease-out);
}
.servicio:focus-within .servicio__go { rotate: 0deg; background: var(--ink); color: var(--paper); }
@media (hover: hover) { .servicio:hover .servicio__go { rotate: 0deg; background: var(--ink); color: var(--paper); } }

/* =========================================================================
   12 · PROCESO — tarjetas que se apilan con sticky
   ====================================================================== */
.rider { display: grid; gap: clamp(1.2rem, 2.4vw, 2rem); }
.rider__card {
	position: sticky;
	background: var(--card, var(--pink));
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow);
	padding: clamp(1.7rem, 3vw, 3rem);
	min-height: clamp(15rem, 26vw, 20rem);
	display: flex;
	flex-direction: column;
	justify-content: center;
}
.rider__card:nth-child(1) { --card: var(--pink); top: calc(var(--header-h) + 1.6rem); }
.rider__card:nth-child(2) { --card: var(--yellow); top: calc(var(--header-h) + 3.4rem); }
.rider__card:nth-child(3) { --card: var(--white); top: calc(var(--header-h) + 5.2rem); }
.admin-bar .rider__card:nth-child(1) { top: calc(var(--header-h) + 3.6rem); }
.admin-bar .rider__card:nth-child(2) { top: calc(var(--header-h) + 5.4rem); }
.admin-bar .rider__card:nth-child(3) { top: calc(var(--header-h) + 7.2rem); }

.rider__n {
	font-family: var(--ff-mono);
	font-size: 0.72rem;
	font-weight: 700;
	font-stretch: 75%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1;
	margin: 0 0 1.5rem;
	align-self: flex-start;
	padding: 0.65em 1em 0.6em;
	background: var(--white);
	border: var(--stroke-hair) solid var(--ink);
	border-radius: var(--radius-pill);
}
.rider__card:nth-child(3) .rider__n { background: var(--paper); }
.rider__t {
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.9rem, 1.1rem + 2.6vw, 3.2rem);
	line-height: 0.94;
	letter-spacing: -0.035em;
	text-transform: uppercase;
	margin: 0 0 0.9rem;
	max-width: 16ch;
}
.rider__d { margin: 0; font-size: var(--wp--preset--font-size--base); line-height: 1.55; max-width: 46ch; }

/* =========================================================================
   13 · LINE-UP (REJILLA DE TRABAJOS)
   ====================================================================== */
.lineup.wp-block-post-template, .lineup {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(1.4rem, 2.6vw, 2.4rem);
}
.lineup > li:first-child { grid-column: 1 / -1; }
/* La primera pieza ocupa el ancho completo, así que el resto se reparte en
   dos columnas. Cuando queda una huérfana al final, se ensancha también:
   la rejilla nunca deja un hueco vacío, publiquen los que publiquen. */
.lineup > li:last-child:nth-child(even) { grid-column: 1 / -1; }

.lineup > li {
	position: relative;
	margin: 0;
	background: var(--tile, var(--white));
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	overflow: hidden;
	transform: rotate(var(--tilt, 0deg));
	transition: transform 0.35s var(--ease-pop), box-shadow 0.35s var(--ease-out);
}
.lineup > li:nth-child(4n+2) { --tile: var(--pink); --tilt: -1.1deg; }
.lineup > li:nth-child(4n+3) { --tile: var(--yellow); --tilt: 1deg; }
.lineup > li:nth-child(4n+4) { --tile: var(--pink-soft); --tilt: 0.8deg; }
.lineup > li:nth-child(4n+5) { --tile: var(--yellow-soft); --tilt: -0.9deg; }
/* "Cogerla de la pila": se endereza y se levanta */
@media (hover: hover) { .lineup > li:hover { transform: rotate(0deg) translate(-4px, -4px); box-shadow: var(--shadow-lg); } }

/* El grupo interior sale del flujo para que la <li> mande en el layout */
.proyecto-card { display: contents; }

.proyecto-card__media { margin: 0; overflow: hidden; border-bottom: var(--stroke-bold) solid var(--ink); }
/* La imagen es el gancho, no la pieza entera: si ocupa media pantalla el
   titular deja de leerse a la primera. Se recorta con proporción fija y
   además se le pone techo en vh para pantallas anchas y bajas. */
.proyecto-card__media img {
	width: 100%;
	aspect-ratio: 2 / 1;
	max-height: 300px;
	object-fit: cover;
	transition: transform 0.7s var(--ease-out);
}
@media (hover: hover) { .lineup > li:hover .proyecto-card__media img { transform: scale(1.05); } }

/* La pieza destacada ocupa las dos columnas de la rejilla, pero por dentro
   se parte en imagen + texto. Recortarla a una franja apaisadísima era lo
   que partía la ilustración por la mitad: así la imagen manda en ancho y
   no en alto, y no hace falta recortar nada. */
@media (min-width: 860px) {
	.lineup > li:first-child,
	.lineup > li:last-child:nth-child(even) {
		display: grid;
		grid-template-columns: 1.05fr 1fr;
		grid-template-rows: auto auto 1fr;
		grid-template-areas:
			"media tags"
			"media title"
			"media more";
		min-height: 19rem;
	}
	.lineup > li:first-child .proyecto-card__media,
	.lineup > li:last-child:nth-child(even) .proyecto-card__media {
		grid-area: media;
		position: relative;
		border-bottom: 0;
		border-right: var(--stroke-bold) solid var(--ink);
	}
	/* La imagen va en posición absoluta a propósito: con height:100% entra
	   en bucle con el alto de las filas (la fila depende de la imagen y la
	   imagen de la fila) y la tarjeta se dispara a miles de píxeles. En
	   absoluto no mide: sólo rellena lo que decide la columna de texto. */
	.lineup > li:first-child .proyecto-card__media img,
	.lineup > li:last-child:nth-child(even) .proyecto-card__media img {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		aspect-ratio: auto;
		max-height: none;
	}
	.lineup > li:first-child .proyecto-card__tags,
	.lineup > li:last-child:nth-child(even) .proyecto-card__tags { grid-area: tags; }
	.lineup > li:first-child .proyecto-card__title,
	.lineup > li:last-child:nth-child(even) .proyecto-card__title { grid-area: title; }
	.lineup > li:first-child .proyecto-card__more,
	.lineup > li:last-child:nth-child(even) .proyecto-card__more {
		grid-area: more;
		align-self: end;
	}
}

.proyecto-card__tags {
	margin: clamp(1.1rem, 2vw, 1.5rem) clamp(1.2rem, 2vw, 1.7rem) 0;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1.45;
	/* Tinta plena, no la secundaria: sobre los rellenos rosa y amarillo
	   --ink-soft se queda en 4.29:1 y no llega al AA de texto pequeño. */
	color: var(--ink);
}
.proyecto-card__title {
	margin: 0.55rem clamp(1.2rem, 2vw, 1.7rem) 0;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.4rem);
	line-height: 0.96;
	letter-spacing: -0.035em;
	text-transform: uppercase;
	text-wrap: balance;
	word-break: keep-all;
	hyphens: none;
}
.lineup > li:first-child .proyecto-card__title { font-size: clamp(1.9rem, 1.2rem + 3vw, 3.6rem); }
.proyecto-card__title a { text-decoration: none; }
/* El enlace del título cubre la tarjeta entera: objetivo táctil completo */
.proyecto-card__title a::after { content: ""; position: absolute; inset: 0; z-index: 3; }

.proyecto-card__more {
	margin: 1rem clamp(1.2rem, 2vw, 1.7rem) clamp(1.3rem, 2vw, 1.7rem);
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	transition: gap 0.3s var(--ease-out);
}
@media (hover: hover) { .lineup > li:hover .proyecto-card__more { gap: 1.1rem; } }

/* =========================================================================
   13b · EL CARTEL — muro de logotipos con forma de cartel de festival
   -------------------------------------------------------------------------
   Todos los logotipos van al MISMO tamaño: en este cartel no hay cabezas de
   cartel. Lo que hace que no parezca una tabla de Excel es todo lo demás:

     · Sombra a dos tintas (rosa asomando bajo el negro). Es el único sitio de
       la web que la lleva; imita el desajuste de registro de una risografía y
       marca este bloque como "pieza impresa".
     · Celdas numeradas con un contador de CSS, como una hoja de contactos.
       Al añadir o quitar logotipos se renumeran solas.
     · Bloques de color repartidos con `nth-child`. Los tonos son claros a
       propósito: el logotipo va en `multiply`, así que se imprime SOBRE el
       color en vez de flotar encima, que es justo lo que hace una risografía.
     · Código de barras en el pie, el mismo del pase del héroe.

   Y el problema de origen de cualquier muro de logotipos: los archivos llegan
   como llegan —PNG con fondo blanco, colores que se pelean, proporciones
   distintas—. El orden lo pone el marco, no los logotipos.
   ====================================================================== */
.cartel {
	overflow: hidden;
	background: var(--paper);
	border: var(--stroke) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: 6px 6px 0 var(--pink), 13px 13px 0 var(--ink);
}

/* --- Cabecera de tinta --------------------------------------------------- */
.cartel__cinta {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: baseline;
	gap: 0.3rem 1.2rem;
	background: var(--ink);
	color: var(--paper);
	padding: 0.72rem clamp(0.9rem, 2vw, 1.5rem);
}

.cartel__sello,
.cartel__fechas {
	margin: 0;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.3;
}

.cartel__fechas { color: var(--ink-invert-soft); }

/* El mismo destello que abre cada índice de sección, aquí en crema sobre la
   tinta. Es lo que hace que la cinta se lea como parte del sistema y no como
   una barra negra cualquiera. */
.cartel__sello {
	display: flex;
	align-items: center;
	gap: 0.55rem;
}

.cartel__sello::before {
	content: "";
	width: 0.9em;
	height: 0.9em;
	flex: none;
	background: currentColor;
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
}

/* --- El muro ------------------------------------------------------------- */
/* El problema de cualquier muro de logotipos: el número de marcas casi nunca
   es múltiplo del número de columnas —13 es primo, sin ir más lejos— y la
   última fila se queda coja. Dejar que las celdas crezcan para repartirse lo
   que sobra tampoco vale: con 13 a tres columnas, la número 13 se quedaba
   sola ocupando el ancho entero, y eso parece un error, no un remate.

   Aquí las celdas miden lo mismo SIEMPRE (5 x 20% = 100% exacto) y el hueco
   que queda al final se lo come un pseudoelemento trameado, como el recuadro
   anulado de un billete. Si la última fila sale completa, ese hueco mide cero
   y no se ve. Funciona con 13 logotipos, con 17 y con 4.

   El desplazamiento de 3 px saca los bordes del último de cada fila y los de
   la fila final fuera del marco, que los recorta. Así no hay línea doble en
   el perímetro, y el borde superior del pie hace de cierre. */
.cartel__muro {
	display: flex;
	flex-wrap: wrap;
	margin: 0 calc(-1 * var(--stroke)) calc(-1 * var(--stroke)) 0;
	counter-reset: marca;
}

.cartel__muro::after {
	content: "";
	flex: 1 1 0;
	min-width: 0;
	border-bottom: var(--stroke) solid var(--ink);
	background-image: repeating-linear-gradient(45deg,
		transparent 0 8px, rgba(13, 13, 13, 0.06) 8px 9px);
}

.marca {
	position: relative;
	flex: 0 0 20%;   /* cinco por fila, exactas: 5 x 20% = 100% */
	min-width: 0;
	margin: 0;
	display: grid;
	place-items: center;
	padding: clamp(1.5rem, 2.6vw, 2.2rem) clamp(1rem, 2vw, 1.7rem) clamp(1rem, 2vw, 1.7rem);
	min-height: clamp(104px, 10.5vw, 132px);
	counter-increment: marca;
	border-right: var(--stroke) solid var(--ink);
	border-bottom: var(--stroke) solid var(--ink);
	transition: background-color var(--t) var(--ease-out);
}

/* Numeración automática. Va en contenido generado a propósito: si estuviera
   en el marcado habría que renumerar a mano cada vez que se añade un cliente,
   y acabaría descuadrada. */
.marca::before {
	content: counter(marca, decimal-leading-zero);
	position: absolute;
	top: 0.55rem;
	left: 0.7rem;
	font-family: var(--ff-mono);
	font-size: 0.5625rem;
	font-weight: 600;
	font-stretch: 87.5%;
	letter-spacing: 0.08em;
	line-height: 1;
	color: var(--ink);
	opacity: 0.32;
}

/* Ritmo de color. Dos progresiones que no encajan entre sí (5n y 6n) para que
   el reparto no se lea como un patrón, sino como una decisión de imprenta.
   Los dos tonos son los suaves: con `--yellow` a plena fuerza la celda tiraba
   de la mirada más que los propios logotipos, sobre todo cuando le tocaba ser
   una de las anchas de la última fila. Junto al crema se distinguen de sobra
   sin gritar. */
.marca:nth-child(5n+2) { background: var(--pink-soft); }
.marca:nth-child(6n+4) { background: var(--yellow-soft); }

.marca img {
	display: block;
	width: auto;
	max-width: 100%;
	max-height: clamp(34px, 3.6vw, 48px);
	object-fit: contain;
	/* `multiply` sobre el papel hace desaparecer el fondo blanco de los PNG,
	   que es la mitad de la batalla; sobre las celdas de color, además, hace
	   que el logotipo parezca impreso encima en vez de pegado. El gris de
	   reposo iguala marcas con paletas que no se hablan entre sí. */
	mix-blend-mode: multiply;
	filter: grayscale(1) contrast(1.04);
	opacity: 0.84;
	transition: filter var(--t) var(--ease-out), opacity var(--t) var(--ease-out);
}

/* Al pasar por encima la celda se enciende: fondo blanco limpio y el logotipo
   a todo color. Funciona igual sobre una celda de papel que sobre una de
   color, que es lo que hace falta con el reparto de arriba. */
@media (hover: hover) {
	.marca:hover { background: var(--white); }
	.marca:hover img { filter: none; opacity: 1; }
	.marca:hover::before { opacity: 0.6; }
}

/* Escotilla para el logotipo que se muera en gris —una marca cuyo color ES la
   marca— o que venga en PNG con fondo oscuro: clase "marca--tal-cual". */
.marca--tal-cual img,
.marca-mini--tal-cual img {
	mix-blend-mode: normal;
	filter: none;
	opacity: 1;
}

/* --- El pie: letra pequeña y código de barras ---------------------------- */
.cartel__pie {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.9rem 1.6rem;
	border-top: var(--stroke) solid var(--ink);
	padding: clamp(0.9rem, 2vw, 1.3rem) clamp(1rem, 2vw, 1.5rem);
}

.cartel__letra-pequena {
	margin: 0;
	max-width: 58ch;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 500;
	font-stretch: 87.5%;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	line-height: 1.5;
	color: var(--ink-soft);
}

/* El mismo código de barras del pase del héroe. Es lo que ata el cartel al
   resto de la página: los dos son entradas del mismo sitio. */
.cartel__codigo {
	flex: none;
	width: clamp(88px, 13vw, 148px);
	height: 1.9rem;
	border-radius: 3px;
	background-image: repeating-linear-gradient(90deg,
		var(--ink) 0 2px, transparent 2px 4px,
		var(--ink) 4px 7px, transparent 7px 9px,
		var(--ink) 9px 10px, transparent 10px 14px);
}

/* --- La banda de patrocinadores ------------------------------------------ */
/* Fondo distinto, línea de separación, logotipos pequeños y apagados: esa
   jerarquía es la que dice "estos no son clientes nuestros" antes de que
   nadie lea la nota. No igualar tamaños con el muro. */
.cartel__banda {
	background: var(--paper-2);
	border-top: var(--stroke) solid var(--ink);
	padding: clamp(1.2rem, 2.6vw, 1.9rem) clamp(1rem, 3vw, 2.2rem);
}

.cartel__nota {
	margin: 0;
	max-width: 64ch;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 500;
	font-stretch: 87.5%;
	letter-spacing: 0.02em;
	line-height: 1.6;
	color: var(--ink-soft);
}

.cartel__nota strong {
	color: var(--ink);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.cartel__tira {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: clamp(1.4rem, 3.2vw, 3rem);
	margin-top: clamp(1rem, 2.2vw, 1.6rem);
}

.marca-mini { margin: 0; }

.marca-mini img {
	display: block;
	width: auto;
	max-height: clamp(20px, 2.2vw, 28px);
	object-fit: contain;
	mix-blend-mode: multiply;
	filter: grayscale(1);
	opacity: 0.58;
	transition: filter var(--t) var(--ease-out), opacity var(--t) var(--ease-out);
}

@media (hover: hover) {
	.marca-mini:hover img { filter: none; opacity: 1; }
}

.marca a,
.marca-mini a {
	display: block;
	background-image: none !important;
	padding-bottom: 0;
	line-height: 0;
}

@media (max-width: 980px) {
	.marca { flex-basis: 33.3333%; }
}

@media (max-width: 620px) {
	.cartel { box-shadow: 4px 4px 0 var(--pink), 9px 9px 0 var(--ink); }
	.marca { flex-basis: 50%; min-height: 96px; padding: 1.35rem 0.9rem 0.9rem; }
	.marca::before { top: 0.42rem; left: 0.52rem; }
	.cartel__tira { gap: 1.3rem 1.7rem; }
}

/* =========================================================================
   14 · ESTUDIO + CIFRAS
   ====================================================================== */
.stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, 2vw, 1.8rem); }
.stat {
	position: relative;
	background: var(--tile, var(--pink));
	color: var(--ink) !important;
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	padding: clamp(1.4rem, 2.2vw, 2rem);
	transition: transform 0.35s var(--ease-pop);
}
.stat:nth-child(1) { --tile: var(--pink); }
.stat:nth-child(2) { --tile: var(--yellow); }
.stat:nth-child(3) { --tile: var(--white); }
@media (hover: hover) { .stat:hover { transform: translateY(-6px) rotate(-1.2deg); } }
.stat__n {
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(2.8rem, 1.6rem + 3.8vw, 4.8rem);
	line-height: 0.85;
	letter-spacing: -0.048em;
	margin: 0;
	color: var(--ink) !important;
}
.stat__l {
	margin: 0.9rem 0 0;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 550;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1.55;
	color: var(--ink) !important;
}

/* Sello giratorio con texto en círculo */
.seal { width: clamp(7rem, 12vw, 10.5rem); aspect-ratio: 1; animation: spin 24s linear infinite; flex: none; }
.seal text {
	font-family: var(--ff-mono);
	font-size: 9.2px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* La marca en el centro del sello. Va CONTRARROTADA a la misma velocidad que
   el sello: el aro y el texto giran, el logotipo se queda quieto. Con la
   estrella daba igual porque es simétrica; un logotipo dando vueltas sobre sí
   mismo se lee como que algo va mal.

   `transform-box: view-box` es obligatorio: sin él el origen de la rotación
   se calcula sobre la caja del propio grupo y el logotipo describe una órbita
   en vez de girar sobre su centro. */
.seal__marca {
	transform-box: view-box;
	transform-origin: 100px 100px;
	animation: spin 24s linear infinite reverse;
}

/* El sello es de una sola tinta y el logotipo trae tres. Aquí se dibuja sólo
   su línea, en el color del sello: sobre el negro del estudio queda como un
   grabado, que es justo lo que es un sello. El relleno rosa y el brillo se
   quitan porque a este tamaño se comen el dibujo. */
.seal .dl-anillo,
.seal .dl-contorno,
.seal .dl-ojo,
.seal .dl-destello { fill: currentColor; }

.seal .dl-burbuja,
.seal .dl-brillo { fill: none; }

/* =========================================================================
   15 · TESTIMONIOS
   ====================================================================== */
.quotes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.4rem, 2.6vw, 2.4rem); align-items: start; }
.quote-card {
	position: relative;
	background: var(--white);
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	padding: clamp(1.7rem, 2.4vw, 2.3rem);
	transition: transform 0.4s var(--ease-pop), box-shadow 0.4s var(--ease-out);
}
.quote-card:nth-child(1) { transform: rotate(-1.8deg); }
.quote-card:nth-child(2) { transform: rotate(1.3deg); margin-top: clamp(0rem, 2.5vw, 2rem); }
.quote-card:nth-child(3) { transform: rotate(-1deg); }
@media (hover: hover) { .quote-card:hover { transform: rotate(0deg) translateY(-6px); box-shadow: var(--shadow-lg); } }
/* Destello del logo en la esquina, en vez de la comilla tipográfica */
.quote-card::before {
	content: "";
	position: absolute;
	top: -1.1rem;
	right: -1.1rem;
	width: 3.2rem;
	height: 3.2rem;
	background: var(--pink);
	-webkit-mask: var(--spark) center / contain no-repeat;
	mask: var(--spark) center / contain no-repeat;
	pointer-events: none;
}
.quote-card:nth-child(2)::before { background: var(--yellow); }
.quote-card:nth-child(3)::before { background: var(--shock); }
.quote-card__q { position: relative; margin: 0; font-size: var(--wp--preset--font-size--base); line-height: 1.58; text-wrap: pretty; }
.quote-card__by {
	margin: 1.3rem 0 0;
	padding-top: 1.1rem;
	border-top: var(--stroke-hair) solid var(--ink);
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1.5;
	color: var(--ink-soft);
}

/* =========================================================================
   16 · CTA GIGANTE
   ====================================================================== */
.cta { position: relative; overflow: hidden; }
.cta__mail {
	display: block;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.6rem, 0.2rem + 5.4vw, 4.6rem);
	line-height: 0.94;
	letter-spacing: -0.042em;
	text-transform: uppercase;
	text-decoration: none;
	word-break: break-word;
	transition: color var(--t) var(--ease-out);
}
.cta__mail:hover { color: var(--shock); }
.cta__meta { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: clamp(1.6rem, 3vw, 2.4rem); padding: 0; list-style: none; }
.cta__meta li {
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1;
	padding: 0.7em 1em 0.65em;
	border: var(--stroke-hair) solid currentColor;
	border-radius: var(--radius-pill);
	margin: 0;
}

/* =========================================================================
   16b · PREGUNTAS FRECUENTES
   ====================================================================== */
.faq { display: grid; }
.faq__item,
.wp-block-details {
	background: var(--white);
	border: var(--stroke) solid var(--ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow-xs);
	padding: 0;
	transition: background-color var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out);
}
.faq__item[open] { background: var(--yellow); box-shadow: var(--shadow-sm); }
.faq__item > summary,
.wp-block-details > summary {
	list-style: none;
	cursor: pointer;
	padding: clamp(1.1rem, 2vw, 1.5rem) clamp(3.4rem, 5vw, 4rem) clamp(1.1rem, 2vw, 1.5rem) clamp(1.2rem, 2vw, 1.7rem);
	position: relative;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.05rem, 0.95rem + 0.6vw, 1.4rem);
	line-height: 1.2;
	letter-spacing: -0.022em;
}
.faq__item > summary::-webkit-details-marker,
.wp-block-details > summary::-webkit-details-marker { display: none; }
.faq__item > summary::after {
	content: "+";
	position: absolute;
	right: clamp(1.1rem, 2vw, 1.6rem);
	top: 50%;
	translate: 0 -50%;
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border: var(--stroke-hair) solid var(--ink);
	border-radius: 50%;
	font-family: var(--ff-mono);
	font-size: 0.95rem;
	line-height: 1;
	transition: rotate 0.3s var(--ease-pop);
}
.faq__item[open] > summary::after { content: "+"; rotate: 45deg; }
.faq__item > :not(summary) {
	margin: 0 clamp(1.2rem, 2vw, 1.7rem) clamp(1.2rem, 2vw, 1.6rem);
	max-width: 62ch;
}

/* =========================================================================
   17 · PROYECTO (ARCHIVO Y FICHA)
   ====================================================================== */
.proyecto-hero { border-bottom: var(--stroke-bold) solid var(--ink); }
/* Los servicios de la ficha sí son enlaces útiles (llevan a su archivo).
   Se les amplía el área pulsable sin mover nada de sitio. */
.proyecto-hero .eyebrow a {
	display: inline-block;
	padding-block: 0.55em;
	margin-block: -0.55em;
}

/* Portada de la ficha: a tamaño natural ocupaba casi una pantalla entera y
   empujaba el caso fuera de vista. Se recorta y se le pone techo. */
/* No se recorta: se estrecha. Centrada y algo más ancha que la columna de
   lectura, marca la espina de la página sin comerse la pantalla. */
.proyecto-portada {
	max-width: 820px;
	margin-inline: auto;
}
.proyecto-portada img { width: 100%; height: auto; }

.proyecto-meta {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: 0;
	background: var(--white);
	border: var(--stroke-bold) solid var(--ink);
	border-radius: var(--radius);
	overflow: hidden;
}
.proyecto-meta__cell { padding: clamp(1.2rem, 2vw, 1.7rem); border-right: var(--stroke) solid var(--ink); }
.proyecto-meta__cell:last-child { border-right: 0; }
.proyecto-meta__k {
	margin: 0 0 0.55rem;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--ink-soft);
}
.proyecto-meta__v {
	margin: 0;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.05rem, 0.9rem + 0.5vw, 1.35rem);
	line-height: 1.12;
	letter-spacing: -0.022em;
	text-wrap: balance;
}

/* Cuerpo del proyecto: columna de lectura, alineada al raíl */
.proyecto-body { max-width: 68ch; margin-inline: auto; }
.proyecto-body > * + * { margin-top: 1.35rem; }
.proyecto-body :where(h2, h3) { margin-top: 2.6rem; }
.proyecto-body :where(h2) { font-size: var(--wp--preset--font-size--xxl); }
.proyecto-body :where(h3) { font-size: var(--wp--preset--font-size--xl); }

.wp-block-post-navigation-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	font-family: var(--ff-mono);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 600;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
}
.wp-block-post-navigation-link a { text-decoration: none; }

/* =========================================================================
   18 · PIE
   ====================================================================== */
.site-footer {
	position: relative;
	background: var(--ink);
	color: var(--paper);
	border-top: var(--stroke-bold) solid var(--ink);
	overflow: hidden;
	/* Lo último de la página no puede quedar bajo el indicador de inicio. */
	padding-bottom: env(safe-area-inset-bottom, 0px);
}
.site-footer :where(p, li, a, h2, h3) { color: var(--paper); }
.site-footer .eyebrow { color: var(--paper); }

.footer-links { list-style: none; margin: 0; padding: 0; }
.footer-links li { margin: 0; }
.footer-links a {
	display: inline-block;
	padding-block: 0.3rem;
	font-family: var(--ff-mono);
	font-size: 0.72rem;
	font-weight: 550;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	text-decoration: none;
	transition: color var(--t) var(--ease-out), transform var(--t) var(--ease-out);
}
@media (hover: hover) { .footer-links a:hover { color: var(--pink); transform: translateX(5px); } }

/* Wordmark gigante recortado por el borde inferior */
.footer-wordmark {
	margin: clamp(2.6rem, 6vw, 5rem) 0 -0.17em;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(3.2rem, 0.2rem + 13.4vw, 15rem);
	line-height: 0.78;
	letter-spacing: -0.052em;
	text-transform: uppercase;
	color: var(--paper);
	white-space: nowrap;
}
/* En pantallas estrechas no cabe de una línea y se cortaba a media palabra:
   mejor que envuelva y llene el ancho, que es el gesto que se busca. */
@media (max-width: 700px) {
	.footer-wordmark { white-space: normal; line-height: 0.84; }
}
.footer-wordmark--outline { color: transparent; -webkit-text-stroke: 2.5px var(--paper); }

.footer-note {
	margin: 0;
	font-family: var(--ff-mono);
	font-size: 0.66rem;
	font-weight: 500;
	font-stretch: 87.5%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	line-height: 1.7;
	color: var(--ink-invert-soft) !important;
}
.footer-note a { color: var(--ink-invert-soft) !important; border-bottom: 1px solid currentColor; text-decoration: none; }
.footer-note a:hover { color: var(--pink) !important; }

/* =========================================================================
   19 · INSIGNIA FLOTANTE
   ====================================================================== */
.badge-float {
	position: fixed;
	right: clamp(1rem, 2.2vw, 2rem);
	bottom: clamp(1rem, 2.2vw, 2rem);
	z-index: 400;
	display: grid;
	place-items: center;
	text-align: center;
	width: 7rem;
	height: 7rem;
	border-radius: 50%;
	background: var(--yellow);
	color: var(--ink);
	border: var(--stroke) solid var(--ink);
	box-shadow: var(--shadow-xs);
	font-family: var(--ff-mono);
	font-size: 0.66rem;
	font-weight: 700;
	font-stretch: 75%;
	line-height: 1.3;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	text-decoration: none;
	padding: 0.7rem;
	transition: transform 0.35s var(--ease-pop), background-color var(--t) var(--ease-out);
}
@media (hover: hover) { .badge-float:hover { transform: rotate(-10deg) scale(1.07); background: var(--pink); } }
@media (max-width: 900px) { .badge-float { display: none; } }

/* =========================================================================
   20 · REVELADO AL SCROLL
   ====================================================================== */
/* El ocultado depende de .reveal-ready, que añade el JS. Si el JS falla,
   el contenido se queda visible en vez de desaparecer para siempre.
   Se anima `translate`, no `transform`: así compone con las rotaciones que
   ya llevan las tarjetas en vez de borrárselas al terminar. */
.reveal-ready .reveal {
	opacity: 0;
	translate: 0 22px;
	transition: opacity var(--t-enter) var(--ease-out), translate var(--t-enter) var(--ease-out);
	transition-delay: calc(var(--i, 0) * 70ms);
}
.reveal-ready .reveal.is-in { opacity: 1; translate: 0 0; }

/* =========================================================================
   21 · RESPONSIVE
   ====================================================================== */
@media (max-width: 1000px) {
}

@media (max-width: 860px) {
	:root { --stroke: 2.5px; --stroke-bold: 3.5px; }

	.quotes { grid-template-columns: minmax(0, 1fr); }
	.quote-card:nth-child(n) { margin-top: 0; transform: rotate(0deg); }

	.stat-grid { grid-template-columns: minmax(0, 1fr); }

	/* Sticky apilado no funciona bien en pantallas cortas: se desactiva */
	.rider__card { position: static; min-height: 0; }

	.servicio { grid-template-columns: 2.8rem minmax(0, 1fr) auto; row-gap: 0.9rem; }
	.servicio__tag { grid-column: 2; justify-self: start; }
	.servicio__go { grid-row: 1 / span 2; align-self: center; }
	@media (hover: hover) { .servicio:hover .servicio__t { transform: none; } }

	.proyecto-meta { grid-template-columns: minmax(0, 1fr); }
	.proyecto-meta__cell { border-right: 0; border-bottom: var(--stroke) solid var(--ink); }
	.proyecto-meta__cell:last-child { border-bottom: 0; }
}

@media (max-width: 520px) {
	/* El destello sobresale de la esquina a propósito, pero en pantallas muy
	   estrechas llegaba justo al borde del viewport y parecía cortado. */
	.quote-card::before {
		top: -0.7rem;
		right: -0.6rem;
		width: 2.4rem;
		height: 2.4rem;
	}
}

@media (max-width: 700px) {
	/* Doble selector a propósito: la regla base es `.lineup.wp-block-post-template`
	   y una media query NO suma especificidad. Con sólo `.lineup` este override
	   perdía, y la rejilla se quedaba en dos columnas de 176 px en el móvil. */
	.lineup.wp-block-post-template,
	.lineup { grid-template-columns: minmax(0, 1fr); }
	.lineup > li:first-child,
	.lineup > li:last-child:nth-child(even) { grid-column: auto; }
	.lineup > li:nth-child(n) { transform: rotate(0deg); }
	.hero__title { letter-spacing: -0.04em; }
	.ticker-stack { width: 114vw; margin-inline: -7vw; }
	.servicio__go { display: none; }
}

@media (max-width: 640px) {
	/* En móvil el CTA de texto largo no cabe junto al menú: vive dentro del
	   desplegable, donde además es lo último que se ve.
	   !important porque .wp-block-buttons.is-layout-flex gana especificidad. */
	.site-header .wp-block-buttons.header-cta { display: none !important; }

	/* Cabecera móvil: la marca sigue leyéndose y el menú deja de ser un icono
	   suelto de 24 px para ser una píldora con el mismo peso que el resto del
	   sistema — borde grueso, relleno rosa y sombra dura. */
	/* Sin alto: la marca no es cuadrada (1.38:1) y con caja cuadrada el
	   dibujo se apoyaba arriba y quedaba descentrado. El alto lo pone el
	   propio SVG. */
	.brand-mark { width: 2.6rem; }
	.brand-lockup { gap: 0.55rem; }
	.brand-lockup .wp-block-site-title { font-size: 0.86rem; letter-spacing: -0.02em; }

	.site-header .wp-block-navigation__responsive-container-open,
	.wp-block-navigation__responsive-container-close {
		display: inline-flex;
		align-items: center;
		gap: 0.5rem;
		min-height: 44px;
		padding: 0.7rem 1.05rem;
		background: var(--pink);
		color: var(--ink);
		border: var(--stroke) solid var(--ink);
		border-radius: var(--radius-pill);
		box-shadow: var(--shadow-xs);
		font-family: var(--ff-mono);
		font-size: 0.68rem;
		font-weight: 700;
		font-stretch: 87.5%;
		letter-spacing: 0.02em;
		line-height: 1;
		text-transform: uppercase;
		margin: 0;
		transition: transform var(--t-micro) var(--ease-pop),
			box-shadow var(--t-micro) var(--ease-out),
			background-color var(--t) var(--ease-out);
	}
	.site-header .wp-block-navigation__responsive-container-open::after {
		content: "";
		width: 1.15em;
		height: 0.88em;
		flex: none;
		background: currentColor;
		-webkit-mask: var(--burger) center / contain no-repeat;
		mask: var(--burger) center / contain no-repeat;
	}
	.site-header .wp-block-navigation__responsive-container-open:active,
	.wp-block-navigation__responsive-container-close:active {
		transform: translate(3px, 3px);
		box-shadow: 0 0 0 var(--ink);
	}
	/* El botón de cerrar repite la píldora, en amarillo para diferenciarlo */
	.wp-block-navigation__responsive-container-close {
		background: var(--yellow);
		position: absolute;
		top: 0.95rem;
		right: var(--gutter);
	}
	.wp-block-navigation__responsive-container-close svg { width: 0.95em; height: 0.95em; }
}

/* Dianas táctiles: en pantallas de dedo todo lo pulsable llega a 40 px de
   alto. Los enlaces de texto crecen con padding, no con tipografía, para
   que el diseño no cambie de escala. */
@media (max-width: 780px) and (pointer: coarse), (max-width: 640px) {
	.footer-links a {
		min-height: 40px;
		display: flex;
		align-items: center;
	}
	/* El correo es la acción de la sección de contacto y su caja medía 24 px
	   de alto: la letra es grande pero la línea va muy apretada, y el dedo no
	   apunta a la letra, apunta a la caja. Se le da aire vertical hasta pasar
	   de 44. No se toca el tamaño de la tipografía. */
	.cta__mail { padding-block: 0.65rem; }
	.brand-lockup .wp-block-site-title a,
	.footer-note a {
		display: inline-flex;
		align-items: center;
		min-height: 40px;
	}
	.cta__meta li,
	.servicio__tag { padding-block: 0.9em 0.85em; }
	.site-header .wp-block-navigation-item__content { padding-block: 0.85rem; }
	.wp-block-button__link,
	.wp-element-button,
	.hero__scroll a { min-height: 44px; }
	/* El icono mide 24 px; el área pulsable se amplía sin moverlo de sitio. */
	.site-header .wp-block-navigation__responsive-container-open {
		padding: 10px;
		margin: -10px;
	}
}

/* El nombre no se esconde: se aprieta. Una cabecera con sólo un símbolo y
   un botón no dice quién eres. */
@media (max-width: 380px) {
	.brand-lockup .wp-block-site-title { font-size: 0.78rem; }
	.brand-mark { width: 2.35rem; }
	.site-header .wp-block-navigation__responsive-container-open { padding-inline: 0.85rem; }
}

/* =========================================================================
   21b · MÓVIL: DECISIONES PROPIAS, NO EL ESCRITORIO ENCOGIDO
   Va al FINAL de la sección responsive a propósito: comparte anchura con
   las media queries de 860 y 700 de arriba y necesita ganarles por orden
   de cascada, no por especificidad.
   ====================================================================== */
@media (max-width: 700px) {
	/* El aire de sección de escritorio (90 px arriba y abajo) suma más de
	   1.200 px de puro vacío a lo largo de la página. En pantalla pequeña el
	   ritmo se lleva con menos. */
	.section { padding-block: 3.4rem; }
	.section--tight { padding-block: 2.8rem; }
	.section-head { margin-bottom: 1.8rem; }


	/* Las cifras dejan de ser tres bloques altos y pasan a tres filas: el
	   número manda a la izquierda y la etiqueta lo acompaña. De 250 px por
	   pieza a menos de 100. */
	.stat-grid { gap: 0.7rem; }
	.stat {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		align-items: center;
		gap: 1rem;
		padding: 0.95rem 1.15rem;
	}
	.stat__n { font-size: 2.5rem; line-height: 0.9; }
	.stat__l { margin: 0; }
	@media (hover: hover) { .stat:hover { transform: none; } }

	/* El sello gira en un hueco que en móvil no existe: fuera. */
	.seal { display: none; }

	/* La ficha de proyecto usa el mismo patrón que las cifras: etiqueta a la
	   izquierda, dato a la derecha. Móvil tiene su propio lenguaje, y conviene
	   que sea el mismo en toda la web. */
	.proyecto-meta__cell {
		display: grid;
		grid-template-columns: 5.6rem minmax(0, 1fr);
		align-items: baseline;
		gap: 0.9rem;
		padding: 0.85rem 1.05rem;
	}
	.proyecto-meta__k { margin: 0; }
	.proyecto-meta__v { font-size: 1.05rem; }

	/* Servicios: la etiqueta sube a la misma línea del título en vez de
	   ocupar una fila para ella sola, y la descripción pasa por debajo. Son
	   35 px menos por fila, cinco veces. */
	.servicio {
		grid-template-columns: 2.1rem minmax(0, 1fr) auto;
		grid-template-areas:
			"n  t   tag"
			".  d   d";
		column-gap: 0.7rem;
		row-gap: 0.45rem;
		padding-block: 1.15rem;
	}
	.servicio__n { grid-area: n; padding-top: 0.3em; }
	/* Con la etiqueta al lado, la columna del título se estrecha: a 1.85rem
	   una palabra como CONTENIDO no cabía y partía por la última letra. */
	.servicio__t { grid-area: t; font-size: clamp(1.25rem, 5.6vw, 1.6rem); }
	.servicio__d { grid-area: d; margin: 0; }
	.servicio__tag {
		grid-area: tag;
		align-self: start;
		margin-top: 0.15rem;
		font-size: 0.66rem;
		padding: 0.5em 0.72em 0.45em;
	}
	/* El grupo intermedio estorba: sus hijos se colocan solos en la rejilla. */
	.servicio__body { display: contents; }

	/* Tarjetas de proyecto: la imagen manda, el titular se aprieta. */
	.proyecto-card__title { font-size: clamp(1.35rem, 6vw, 1.7rem); }
	.proyecto-card__tags { margin-top: 1rem; }
	.proyecto-card__more { margin-top: 0.8rem; }

}

/* =========================================================================
   21c · CARRUSELES DE ARRASTRE (hasta tablet)
   Tres piezas del mismo peso se recorren mejor con el dedo que con 1.200 px
   de scroll vertical. Se deja asomar la siguiente tarjeta: es la única señal
   de "hay más" que funciona sin explicar nada.
   Llega hasta 900 px porque apiladas a lo ancho en tablet desaprovechan la
   pantalla; el ancho de tarjeta se topa en 21rem para que a 900 se vean casi
   tres y a 390 se vea una con su asomo.
   ====================================================================== */
@media (max-width: 900px) {
	.rider,
	.quotes {
		display: flex;
		gap: 0.9rem;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: var(--gutter);
		/* Sale del raíl para poder empezar y terminar en el borde. */
		margin-inline: calc(-1 * var(--gutter));
		padding-inline: var(--gutter);
		/* Aire para que la sombra dura no la recorte el overflow. */
		padding-block: 0.4rem 1.4rem;
		scrollbar-width: none;
	}
	.rider::-webkit-scrollbar,
	.quotes::-webkit-scrollbar { display: none; }
	.rider > *,
	.quotes > * {
		flex: 0 0 min(82%, 21rem);
		scroll-snap-align: start;
		margin-top: 0;
	}
	.rider__card { min-height: 0; position: static; }
	.quote-card:nth-child(n) { transform: rotate(0deg); }
}

/* =========================================================================
   21d · MÓVIL: LA NAVEGACIÓN BAJA AL PULGAR
   -------------------------------------------------------------------------
   El problema medido: en un 390×844, sujetando el móvil con una mano, el
   centro de la píldora "MENÚ" de la esquina superior derecha queda a ~760 px
   del pivote del pulgar. El alcance máximo estirando es ~560. Es decir, para
   abrir el menú había que recolocar la mano SIEMPRE. Y "Escríbenos" —el
   objetivo de negocio— estaba a dos toques, el primero de ellos ahí.

   La solución: una cápsula fija abajo partida en dos. "MENÚ" abre una hoja
   inferior; "ESCRÍBENOS" es un enlace directo. Las dos dianas caen en el
   tercio inferior, que es donde el pulgar llega sin mover la mano.

   Nota de arquitectura: el botón de la cápsula NO reimplementa el menú.
   Dispara el botón real del bloque de navegación de WordPress, que ya trae
   diálogo, trampa de foco, Escape y bloqueo de scroll. Aquí sólo se cambia
   la forma: de pantalla completa a hoja inferior.
   ====================================================================== */
.dock { display: none; }

@media (max-width: 700px) {
	.dock.dock--listo {
		display: grid;
		/* 38/62: el CTA es la acción de negocio y se lleva el espacio. */
		grid-template-columns: 38fr 62fr;
		position: fixed;
		left: var(--gutter);
		right: var(--gutter);
		/* En una tableta pequeña, una cápsula de 600 px de ancho ya no es una
		   cápsula: es una barra. Se centra y se le pone techo. */
		max-width: 30rem;
		margin-inline: auto;
		bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
		z-index: 480;
		background: var(--paper);
		border: var(--stroke-bold) solid var(--ink);
		border-radius: var(--radius-pill);
		box-shadow: var(--shadow-sm);
		transition: translate 200ms var(--ease-out), opacity 160ms linear;
	}
	/* Por encima del velo del menú a propósito: la cápsula ES el control del
	   diálogo (`aria-expanded` + `aria-haspopup`), así que sigue mandando con
	   la hoja abierta — "MENÚ" pasa a cerrar. Y el CTA no se pierde detrás de
	   una capa oscura justo cuando el usuario está decidiendo. */
	.dock.dock--listo { z-index: 100001; }
	/* La cápsula vive dentro de <header>, que tiene nombre de transición de
	   vista. Sin nombre propio se capturaría dentro de la instantánea de la
	   cabecera, y esa instantánea tendría que estirarse hasta abajo del todo
	   para contenerla: al navegar, la "cabecera" taparía la página entera.
	   Con nombre propio se captura aparte y cada una cruza por su lado. */
	.dock.dock--listo { view-transition-name: capsula; }
	/* Con el teclado abierto el dock estorba y encima queda tapado. Se retira
	   mientras se escribe y vuelve al salir del campo. */
	.dock.dock--oculto {
		translate: 0 calc(100% + 24px);
		opacity: 0;
		pointer-events: none;
	}

	.dock__menu,
	.dock__cta {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
		min-height: 52px;
		padding: 0 0.9rem;
		margin: 0;
		background: transparent;
		border: 0;
		color: var(--ink);
		font-family: var(--ff-mono);
		font-size: 0.7rem;
		font-weight: 700;
		font-stretch: 87.5%;
		letter-spacing: 0.02em;
		line-height: 1;
		text-transform: uppercase;
		text-decoration: none;
		cursor: pointer;
		transition: background-color var(--t) var(--ease-out);
	}
	.dock__menu { border-radius: var(--radius-pill) 0 0 var(--radius-pill); }
	.dock__cta {
		background: var(--pink);
		/* La divisoria es el borde izquierdo del CTA: una sola línea, del
		   mismo grosor que el contorno. */
		border-left: var(--stroke-bold) solid var(--ink);
		border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
	}
	.dock__menu::after,
	.dock__cta::after {
		content: "";
		flex: none;
		background: currentColor;
	}
	.dock__menu::after {
		width: 1.1em;
		height: 0.85em;
		-webkit-mask: var(--burger) center / contain no-repeat;
		mask: var(--burger) center / contain no-repeat;
	}
	.dock__cta::after {
		width: 1em;
		height: 1em;
		-webkit-mask: var(--arrow) center / contain no-repeat;
		mask: var(--arrow) center / contain no-repeat;
	}
	.dock__menu:active,
	.dock__cta:active { background-color: var(--yellow); }
	/* Abierto, el mismo botón cierra: las tres barras se vuelven un aspa. */
	.dock__menu[aria-expanded="true"]::after {
		width: 0.85em;
		height: 0.85em;
		-webkit-mask-image: var(--equis);
		mask-image: var(--equis);
	}
	.dock__menu[aria-expanded="true"] { background-color: var(--yellow); }

	/* La cabecera ya no lleva controles: se queda de cabecera de verdad,
	   sólo la marca y el vúmetro. Baja de 70 a 56 px. */
	/* Sólo se esconde el DISPARADOR, no la navegación entera: el diálogo del
	   menú vive dentro de ese mismo <nav>, y ocultarlo se llevaba por delante
	   la hoja. El botón oculto sigue recibiendo el clic que le manda el dock. */
	body.tiene-dock .site-header .wp-block-navigation__responsive-container-open {
		display: none;
	}
	/* El bloque de navegación pasa a superposición en su propio punto de
	   corte (600 px), pero la cápsula aparece a 700. En esa franja la lista
	   seguía dibujándose en línea dentro de la cabecera: navegación duplicada.
	   Se esconde salvo cuando es la hoja. */
	body.tiene-dock .site-header .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}
	body.tiene-dock .site-header {
		--header-h: 56px;
		padding-top: calc(0.55rem + env(safe-area-inset-top, 0px));
		padding-bottom: 0.55rem;
	}

	/* El pie deja sitio al dock para que el último enlace no quede debajo. */
	body.tiene-dock .site-footer {
		padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 84px);
	}

	/* --- La hoja inferior ------------------------------------------------
	   El contenedor del bloque de navegación pasa de lienzo a velo, y su
	   envoltorio interior se convierte en la hoja. */
	body.tiene-dock .wp-block-navigation__responsive-container.is-menu-open {
		background-color: rgba(13, 13, 13, 0.55) !important;
		padding: 0 !important;
		align-items: flex-end;
		animation: velo-entra 160ms linear both;
	}
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-close {
		width: 100%;
		max-width: 100%;
		margin-top: auto;
		background: var(--paper);
		border-top: var(--stroke-bold) solid var(--ink);
		border-radius: var(--radius-lg) var(--radius-lg) 0 0;
		/* Abajo se deja hueco para la cápsula, que queda por encima. */
		padding: 2.2rem var(--gutter) calc(env(safe-area-inset-bottom, 0px) + 84px);
		animation: hoja-entra 240ms var(--ease-out) both;
		/* El tirador: además de decir "esto se arrastra", es la zona que
		   escucha el gesto de deslizar hacia abajo. */
		position: relative;
		/* `none` y no `pan-y`: con `pan-y` el navegador se reserva el derecho
		   a quedarse con el gesto vertical, y como la hoja no tiene nada que
		   desplazar por dentro puede acabar cancelándome el arrastre con un
		   `pointercancel` a mitad. Aquí el gesto es mío de principio a fin. */
		touch-action: none;
	}
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-close::before {
		content: "";
		position: absolute;
		top: 0.65rem;
		left: 50%;
		translate: -50% 0;
		width: 52px;
		height: 5px;
		border-radius: 999px;
		background: var(--ink);
		opacity: 0.28;
	}
	/* Mientras se arrastra no debe haber transición peleando con el dedo. */
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-close.arrastrando {
		animation: none;
		transition: none;
	}
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-close.volviendo {
		animation: none;
		transition: translate 200ms var(--ease-out);
		translate: 0 0 !important;
	}

	/* Los enlaces bajan de tamaño: antes eran enormes porque la pantalla
	   estaba vacía. En una hoja de 3 filas, ese tamaño ya no cabe ni hace
	   falta. */
	body.tiene-dock .is-menu-open .wp-block-navigation-item__content {
		font-size: clamp(1.5rem, 6.5vw, 2rem) !important;
		padding: 0.85rem 0 !important;
	}
	/* El núcleo reserva 46 px de margen y 56 px de relleno para su botón de
	   cerrar. En una hoja de tres enlaces eso son 102 px de vacío antes de la
	   primera palabra. Se anulan y el botón se ancla a la hoja. */
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-dialog {
		position: static;
		margin-top: 0 !important;
	}
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-container-content {
		padding-top: 0 !important;
	}
	/* El botón de cerrar del núcleo desaparece: sería una segunda píldora
	   amarilla a diez centímetros de la primera. El control es la cápsula, que
	   con la hoja abierta muestra el aspa. Cerrar sigue siendo posible de
	   cuatro maneras: la cápsula, arrastrar el tirador, tocar el velo y Esc. */
	body.tiene-dock .is-menu-open .wp-block-navigation__responsive-container-close {
		display: none;
	}

	/* "Escríbenos" ya está en la cápsula, visible por encima del velo: dentro
	   de la hoja sería el mismo botón dos veces a diez centímetros. */
	body.tiene-dock .is-menu-open .wp-block-navigation-item.nav-cta { display: none; }
	/* Con el CTA oculto, el último enlace visible es el penúltimo de la lista. */
	body.tiene-dock .is-menu-open .wp-block-navigation-item:nth-last-child(2) {
		border-bottom: 0;
	}
}

@keyframes velo-entra { from { opacity: 0; } to { opacity: 1; } }
@keyframes hoja-entra { from { translate: 0 100%; } to { translate: 0 0; } }

/* =========================================================================
   21e · EL CROMO SE APARTA AL BAJAR
   -------------------------------------------------------------------------
   Condición doble a propósito. `max-width: 700px` es el móvil en vertical,
   donde vive la cápsula. `max-height: 500px` es el móvil en HORIZONTAL y
   cualquier ventana baja: ahí la cabecera sola ya se comía el 18% del alto,
   que es peor que lo que se ahorraba en vertical, y el plegado no llegaba
   porque iba atado sólo al ancho.
   ====================================================================== */
@media (max-width: 700px), (max-height: 500px) {

	/* --- El cromo se aparta al bajar -------------------------------------
	   Entre cabecera y cápsula se comían ~130 px de una pantalla de 844: un
	   15% permanente. Al bajar se retiran; al subir vuelven.

	   La cabecera NO se va entera, se PLIEGA: el vúmetro de lectura vive en su
	   borde inferior, así que si se fuera del todo se llevaría el avance con
	   ella. Sube justo lo que mide su cuerpo y deja el raíl asomando. La marca
	   se retira, la línea de progreso se queda: la cabecera se colapsa dentro
	   de su propio raíl.

	   Los tiempos son asimétricos a propósito. Irse: 240 ms y curva de entrada
	   y salida, que se lea como una retirada tranquila. Volver: 200 ms y curva
	   de salida, porque si has hecho el gesto de subir es que lo quieres YA.
	   Y la cápsula se va 60 ms después que la cabecera: escalonarlo hace que
	   parezca una sola cosa apartándose, y no dos widgets nerviosos. Al volver
	   entran a la vez, que es lo inmediato. */
	/* Se pliega moviendo `top`, NO con `translate`, y esto no es un capricho:
	   un `transform`/`translate` convierte al elemento en bloque contenedor de
	   sus descendientes `position: fixed`, y dentro de <header> vive el
	   diálogo del menú, que es fijo. Con `translate` la hoja dejaba de
	   anclarse a la ventana y salía disparada fuera de pantalla (medido:
	   y=-286 en una ventana de 844). `top` mueve dónde se ancla un elemento
	   pegajoso sin crear bloque contenedor de nada.

	   `--colapso` lo mide el JS —la altura real depende del contenido— y es
	   el alto de la cabecera menos el raíl, que es justo lo que queda a la
	   vista. */
	/* La coreografía, que aquí no es adorno sino la solución a un fallo.
	   Al plegarse, la cabecera sube 57,5 px y su contenido —el logotipo, que
	   está a unos 8 px de su borde— acaba en y=-49. Esa franja Safari SÍ la
	   pinta, así que el logotipo se veía debajo del reloj del iPhone.

	   No se arregla tapándolo: se arregla no dejando que llegue. El contenido
	   se apaga en 80 ms y la barra no empieza a moverse hasta que ha
	   terminado. Al volver, al revés: primero baja la barra y el contenido
	   aparece cuando ya está dentro de la ventana (120 ms, que es cuando el
	   recorrido va por el 87%). Nada cruza nunca la franja estando visible. */
	.site-header { transition: top 200ms var(--ease-out); }
	.site-header__inner { transition: opacity 180ms var(--ease-out) 120ms; }
	.dock.dock--listo { transition-delay: 0ms; }

	body.cromo-oculto .site-header {
		top: calc(-1 * var(--colapso, 58px));
		transition: top 240ms var(--ease-io) 80ms;
	}
	body.cromo-oculto .site-header__inner {
		opacity: 0;
		transition: opacity 80ms linear;
	}
	body.cromo-oculto .site-header.is-stuck { box-shadow: none; }
	body.cromo-oculto .dock.dock--listo {
		translate: 0 calc(100% + 24px);
		transition-delay: 60ms;
		pointer-events: none;
	}
}

/* =========================================================================
   22 · MOVIMIENTO REDUCIDO
   ====================================================================== */
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
	.reveal-ready .reveal { opacity: 1 !important; transform: none !important; }
	.ticker__track { animation: none !important; }
	/* La marca aparece sin estampado ni rebote */
	.brand-mark svg { animation: dl-aparece 120ms linear both !important; }
	.dl-cuerpo, .dl-orbita, .dl-chispa, .dl-brillo { animation: none !important; }
}

/* =========================================================================
   24 · ENTRADA, TRANSICIONES Y REMATES
   ====================================================================== */

/* --- Levantar el telón -------------------------------------------------
   El titular sube palabra a palabra y el resto entra detrás.

   Las piezas se ocultan ANTES del primer pintado (la clase .js la pone un
   script en línea en el <head>), porque si se pintan y luego se esconden
   para animarlas se ve un parpadeo. Y llevan una animación de rescate a
   1,5 s: si el JS muere a mitad, el héroe aparece igualmente. */
.js .hero .hero__title,
.js .hero .hero__status,
.js .hero .hero__lead,
.js .hero .hero__actions,
.js .hero .hero__scroll,
.js .hero .pass {
	visibility: hidden;
	animation: hero-rescate 0s linear 1.5s forwards;
}
@keyframes hero-rescate { to { visibility: visible; } }

.js .hero.is-ready .hero__title,
.js .hero.is-ready .hero__status,
.js .hero.is-ready .hero__lead,
.js .hero.is-ready .hero__actions,
.js .hero.is-ready .hero__scroll,
.js .hero.is-ready .pass {
	visibility: visible;
	animation: none;
}

.hero.is-ready .hero__title .w {
	display: inline-block;
	animation: rise 0.72s var(--ease-out) backwards;
	animation-delay: calc(0.06s + var(--i, 0) * 55ms);
}
.hero.is-ready .hero-in {
	animation: rise 0.66s var(--ease-out) backwards;
	animation-delay: calc(0.34s + var(--i, 0) * 80ms);
}
@keyframes rise {
	from { opacity: 0; translate: 0 0.5em; }
	to { opacity: 1; translate: 0 0; }
}

/* El pase se inclina siguiendo al puntero; la rotación base se conserva.
   Va en variable para que el móvil pueda ponerla a cero desde aquí abajo. */
.pass {
	--pass-rot: 2.2deg;
	transform: rotate(var(--pass-rot)) perspective(700px)
		rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
	transform-style: preserve-3d;
}
@media (hover: hover) { .pass:hover { --pass-rot: -1.2deg; transform: rotate(var(--pass-rot)) perspective(700px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(-5px); } }
@media (max-width: 640px) {
	.pass { --pass-rot: 0deg; }
}

/* --- La cabecera marca el avance de lectura: nivel de audio -------------
   No es una barra que crece, son SEGMENTOS que se encienden de uno en uno,
   como el vúmetro de una mesa de mezclas. El mismo dato de siempre, dicho en
   el idioma del oficio del cliente.

   Cómo está hecho, y por qué así:
     · El trazo negro de 4,5 px de la cabecera hace de pista apagada. No se
       añade nada: los segmentos rosas se recortan sobre él.
     · El elemento ocupa SIEMPRE el ancho completo, y la máscara de segmentos
       se calcula sobre ese ancho: así el paso entre segmentos es constante.
       Si el ancho fuese el del nivel, los segmentos se estirarían al avanzar.
     · Lo que se anima es `clip-path`, no `width`: no provoca layout.
     · El JS redondea el nivel al segmento entero más cercano, de modo que
       nunca se ve medio segmento encendido. Ahí está la lectura de vúmetro.
   ---------------------------------------------------------------------- */
.site-header {
	--vu-n: 40;
	/* Proporción del paso que ocupa el bloque encendido. El hueco NO puede ir
	   en px fijos: a 1440 px un hueco de 3 px sobre un paso de 45 se lee como
	   una raya sólida con pelos, no como segmentos. En proporción, el ritmo es
	   el mismo en cualquier ancho. */
	--vu-relleno: 0.66;
}
.site-header::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: calc(-1 * var(--stroke-bold));
	height: var(--stroke-bold);
	background: var(--shock);
	pointer-events: none;
	--vu-paso: calc(100% / var(--vu-n));
	--vu-bloque: calc(var(--vu-paso) * var(--vu-relleno));
	--vu-mascara: repeating-linear-gradient(
		to right,
		#000 0 var(--vu-bloque),
		transparent var(--vu-bloque) var(--vu-paso)
	);
	-webkit-mask-image: var(--vu-mascara);
	mask-image: var(--vu-mascara);
	clip-path: inset(0 calc(100% - var(--vu-nivel, 0%)) 0 0);
	transition: clip-path 110ms var(--ease-out);
}
/* Menos segmentos y más anchos según se estrecha la pantalla: a 390 px, 32
   segmentos dan bloques de 8 px que se leen como una línea punteada, no como
   un nivel. El número baja para que el bloque nunca caiga por debajo de ~14 px. */
@media (max-width: 1100px) { .site-header { --vu-n: 24; } }
@media (max-width: 700px)  { .site-header { --vu-n: 16; } }

/* --- Distintivo que sigue al puntero sobre las tarjetas ---------------- */
/* La posición la escribe el JS en `transform` (propiedad de composición: no
   provoca layout ni repintado). Aquí NO se pone transición a `transform`,
   porque el suavizado lo hace el bucle de animación cuadro a cuadro; una
   transición encima pelearía con él y se vería a destiempo.
   `opacity` y `scale` sí van por CSS: son la entrada y la salida.
   `will-change` lo activa y lo apaga el JS, para no dejar una capa de
   composición reservada de forma permanente. */
.card-cursor {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 600;
	display: grid;
	place-items: center;
	width: 4.6rem;
	height: 4.6rem;
	border-radius: 50%;
	background: var(--shock);
	color: var(--ink);
	border: var(--stroke) solid var(--ink);
	font-family: var(--ff-mono);
	font-size: 0.66rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	pointer-events: none;
	contain: layout style paint;
	opacity: 0;
	scale: 0.35;
	transition: opacity 0.2s var(--ease-out), scale 0.32s var(--ease-pop);
}
.card-cursor.is-on { opacity: 1; scale: 1; }

/* --- Siguiente proyecto, a sangre -------------------------------------
   El final de una ficha es el sitio donde más se abandona una web: en vez
   de dos enlaces pequeños, el siguiente proyecto ocupa una banda entera.

   El tamaño va en el CONTENEDOR, no en el enlace, para que la flecha del
   sistema (un ::after en `em`) salga proporcional al titular y no diminuta. */
.next-project {
	display: block;
	font-family: var(--ff-display);
	font-weight: 800;
	font-size: clamp(1.8rem, 0.9rem + 4.2vw, 4.2rem);
	line-height: 0.98;
	letter-spacing: -0.04em;
	text-transform: uppercase;
	transition: translate 0.4s var(--ease-out);
}
/* La flecha va DENTRO del enlace, pegada a la última palabra. Como hermana
   en un contenedor flex se iba al extremo derecho de la banda, lejos del
   texto, y parecía otro elemento distinto. */
.next-project::after { content: none; }
.next-project a {
	color: inherit;
	text-decoration: none;
	text-wrap: balance;
}
.next-project a::after {
	content: "";
	display: inline-block;
	width: 0.62em;
	height: 0.62em;
	margin-left: 0.3em;
	vertical-align: 0.02em;
	background: currentColor;
	-webkit-mask: var(--arrow) center / contain no-repeat;
	mask: var(--arrow) center / contain no-repeat;
}
/* Nada de cambiar el color al pasar por encima: la banda es rosa y el texto
   se volvía invisible. Se mueve, que además indica hacia dónde lleva. */
@media (hover: hover) { .next-project:hover { translate: 0.7rem 0; } }

.next-block .prev-project {
	margin-top: var(--wp--preset--spacing--50);
	opacity: 0.7;
	transition: opacity var(--t) var(--ease-out), translate var(--t) var(--ease-out);
}
@media (hover: hover) { .next-block .prev-project:hover { opacity: 1; translate: -0.35rem 0; } }

/* --- Transición entre páginas ------------------------------------------
   Cross-document: el navegador funde la página saliente con la entrante.
   Donde no está soportado simplemente no pasa nada. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out 0.22s var(--ease-out) both; }
::view-transition-new(root) { animation: vt-in 0.34s var(--ease-out) both; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; translate: 0 14px; } }
/* La cabecera no parpadea: se mantiene fija entre páginas. */
.site-header { view-transition-name: cabecera; }

@media (prefers-reduced-motion: reduce) {
	::view-transition-group(*),
	::view-transition-old(*),
	::view-transition-new(*) { animation: none !important; }
	.card-cursor { display: none; }
}

/* =========================================================================
   23 · IMPRESIÓN
   ====================================================================== */
@keyframes dl-aparece { from { opacity: 0; } to { opacity: 1; } }

@media print {
	body::after, .badge-float, .ticker, .site-header, .hero__scroll { display: none !important; }
	body { background: #fff; color: #000; }
	.card, .is-style-card, .lineup > li, .quote-card, .rider__card { box-shadow: none; }
	.rider__card { position: static; }
}


/* =========================================================================
   22 · ALTO DE CABECERA POR TRAMOS
   -------------------------------------------------------------------------
   `--header-h` no decora nada: es lo que reservan `scroll-padding-top` (para
   que un ancla no aterrice debajo de la barra) y las tarjetas `sticky` del
   rider. Ambas viven FUERA de la cabecera, así que la variable tiene que
   declararse en `:root`; puesta sobre `.site-header` sólo la ve el propio
   `min-height` y el resto se queda con el valor de escritorio.

   La cabecera cambia de alto dos veces al estrechar, y por motivos distintos:
     > 700 px ......... 74 px — CTA visible, relleno de 0,8rem
     641 – 700 px ..... 65 px — CTA visible, relleno del dock (0,55rem)
     <= 640 px ........ 61 px — se va el CTA y manda el alto de la marca
   De ancho a estrecho, que es el orden en que tienen que ganar. Este bloque
   va al final del fichero a propósito: así ninguna media query anterior lo
   pisa por orden de aparición.
   ====================================================================== */
@media (max-width: 700px) {
	:root { --header-h: 66px; }
}
@media (max-width: 640px) {
	:root { --header-h: 62px; }
}
