/**
 * bloques.css — cabecera, pie y bloques de la Home.
 * Solo tokens: ni un color ni un tamaño de marca fuera de tokens.css.
 */

/* =========================================================== CABECERA ==== */

.cdx-cabecera {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--cdx-blanco);
}
.cdx-cabecera__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--cdx-gap);
	min-height: var(--cdx-cabecera-alto);
}
.cdx-cabecera__logo { display: inline-flex; align-items: center; flex: none; }
.cdx-cabecera__logo img, .cdx-cabecera__logo svg { width: auto; height: 40px; }

.cdx-cabecera__acciones { display: flex; align-items: center; gap: clamp(1rem, .5rem + 1.2vw, 1.75rem); margin-left: auto; }

/* ---------- Mensaje destacado junto al logo ---------- */
/* El `header-status` del diseño de referencia, medido en su cabecera: texto a
   20/32 en negro y, delante, un punto de 10 con DOS anillos de 16 que salen de
   él en bucle. Se esconde por debajo de 1200, como el suyo (allí lleva
   `elementor-hidden-tablet` y `elementor-hidden-mobile`): en la banda estrecha
   no cabe junto al CTA y el botón de menú. */
.cdx-cabecera__mensaje {
	display: flex;
	align-items: center;
	gap: 16px;
	margin: 0 0 0 60px;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-negro);
	white-space: nowrap;
}
@media (max-width: 1199px) { .cdx-cabecera__mensaje { display: none; } }

.cdx-punto-vivo {
	position: relative;
	flex: none;
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 100%;
	background: var(--cdx-negro);
}
/* Los dos anillos: mismo tamaño y posición que los suyos (16 a −3/−3), con su
   curva y su ciclo de 2s; el segundo entra a 1,25s, que es la mitad larga del
   ciclo y lo que da la sensación de latido continuo. */
.cdx-punto-vivo::before,
.cdx-punto-vivo::after {
	content: '';
	position: absolute;
	top: -3px;
	left: -3px;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	border: 1px solid var(--cdx-negro);
	opacity: .6;
	animation: cdx-latido 2s ease infinite;
}
.cdx-punto-vivo::after { animation-delay: 1.25s; }
@keyframes cdx-latido {
	0%   { opacity: 1; transform: scale3d(.75, .75, 1); }
	100% { opacity: 0; transform: scale3d(2, 2, 1); }
}
/* Sin movimiento pedido, el punto se queda quieto. */
@media (prefers-reduced-motion: reduce) {
	.cdx-punto-vivo::before,
	.cdx-punto-vivo::after { animation: none; opacity: .6; }
}

/* Botón de menú: el icono de 3 barras asimétricas del diseño (40×16). */
.cdx-menu-boton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px; height: 32px;
	padding: 0; border: 0; outline: 0;
	background: none; cursor: pointer;
	color: var(--cdx-negro);
	flex: none;
}
.cdx-menu-boton svg { display: block; transition: opacity var(--cdx-transicion); }
.cdx-menu-boton:hover svg { opacity: .6; }

/* ---------- Panel lateral de navegación ---------- */
/* Menú a PANTALLA COMPLETA del diseño: velo + área negra en tres franjas que
   entra deslizándose desde la derecha (left: 110% → 0) en .6s. */
.cdx-menu-velo {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, .6);
	z-index: 9999;
	opacity: 0;
	visibility: hidden;
	overflow: hidden;
	transition: opacity .6s, visibility .6s;
}
.cdx-menu-velo[data-abierto="true"] { opacity: 1; visibility: visible; }
.cdx-menu-velo[hidden] { display: block; }   /* lo gestiona la transición, no `hidden` */

.cdx-menu-area {
	position: relative;
	left: 110%;
	width: 100%;
	height: 100%;
	display: flex;
	background: var(--cdx-negro);
	transition: left .6s;
}
.cdx-menu-velo[data-abierto="true"] .cdx-menu-area { left: 0; }

/* --- Franja izquierda: marca arriba, texto de apoyo abajo --- */
.cdx-menu-izq {
	width: 100%;
	max-width: 400px;
	flex-shrink: 0;
	border-right: 1px solid #313131;
	padding: 40px 60px 60px;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
}
/* El hueco lo pone la pieza 1 del JS, que alinea la tinta del logo con la del
   primer ítem del menú. No se puede hacer en CSS: la lista va centrada y en
   `vh`, así que su altura depende de la ventana y de si algún ítem parte en dos
   líneas. Por defecto 0, o sea el relleno de la franja de siempre. */
.cdx-menu-izq__logo { display: block; max-width: 176px; margin-top: var(--cdx-logo-baja, 0px); }
.cdx-menu-izq__logo img { width: 100%; height: auto; }
.cdx-menu-izq__apoyo { max-width: 244px; margin: 0; color: var(--cdx-blanco); font-size: var(--cdx-fs-small); line-height: 1.44; }

/* --- Franja central: los ítems grandes --- */
.cdx-menu-centro { width: 100%; min-width: 0; display: flex; }
.cdx-menu-nav {
	min-height: 100%;
	width: 100%;
	padding: clamp(24px, 5vh, 100px) 0 clamp(24px, 5vh, 100px) 136px;
	display: flex;
	flex-direction: column;
	/* ⚠️ `safe` es obligatorio aquí. Con `center` a secas, en cuanto la lista es
	   más alta que el carril (ventanas altas: a 1600x1200 y a 1280x1200 pasa,
	   porque los ítems largos parten en dos líneas) el sobrante se reparte
	   ARRIBA Y ABAJO, y lo que se desborda por arriba de un contenedor con
	   scroll NO se puede alcanzar: «Inicio» quedaba a −72 px y era inaccesible.
	   Con `safe`, cuando no cabe se comporta como `flex-start` y todo el
	   desbordamiento se va abajo, donde el scroll sí llega.
	   Se deja el `center` suelto delante como reserva para navegadores que no
	   entiendan la palabra clave: ignoran la línea siguiente y se quedan como
	   estaban. */
	justify-content: center;
	justify-content: safe center;
	overflow-y: auto;
}
.cdx-menu-nav::-webkit-scrollbar { width: 0; }

.cdx-menu-lista { list-style: none; margin: 0; padding: 0; text-align: left; }
/* Tamaño atado al ALTO de la ventana: con 8 ítems (la referencia tiene 5) los
   130px del diseño no caben, así que la escala se ajusta para no tener scroll. */
.cdx-menu-lista li:not(:first-child) { margin-top: clamp(4px, 1.4vh, 45px); }
.cdx-menu-lista a {
	display: inline-block;
	padding: 0;
	font-size: clamp(24px, 7.2vh, 130px);
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.077;
	letter-spacing: -.03em;
	color: var(--cdx-blanco);
	opacity: .4;
	transition: opacity var(--cdx-transicion);
}
.cdx-menu-lista a:hover,
.cdx-menu-lista a:focus-visible,
.cdx-menu-lista .current-menu-item > a { opacity: 1; }

/* --- Franja derecha: cerrar + datos de contacto --- */
.cdx-menu-dcha {
	width: 100%;
	max-width: 400px;
	flex-shrink: 0;
	padding: 20px 60px 60px;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
}
.cdx-menu-cerrar {
	width: 70px; height: 70px;
	display: flex; align-items: center; justify-content: center;
	background: #191919; border: 0; padding: 0; outline: 0; cursor: pointer;
	border-radius: 100%;
	color: var(--cdx-blanco);
	flex: none;
	transition: background var(--cdx-transicion);
}
.cdx-menu-cerrar:hover { background: #2b2b2b; }

.cdx-menu-contacto { margin-top: 80px; max-width: 255px; align-self: flex-start; color: var(--cdx-blanco); }
.cdx-menu-contacto__titulo { margin: 0 0 20px; font-size: var(--cdx-fs-h3); font-weight: var(--cdx-peso-fuerte); line-height: 1.35; }
.cdx-menu-contacto__dir { margin: 0; font-size: var(--cdx-fs-small); line-height: 1.66; }
.cdx-menu-contacto__vias { margin-top: 20px; display: flex; flex-direction: column; }
.cdx-menu-contacto__vias a { font-size: var(--cdx-fs-small); line-height: 1.66; color: var(--cdx-blanco); }
.cdx-menu-contacto__vias a[href^="mailto:"] { text-decoration: underline; }

@media (max-width: 1399px) {
	.cdx-menu-izq { max-width: 300px; padding: 20px 30px 30px; }
	.cdx-menu-dcha { max-width: 300px; padding: 20px 30px 30px; }
	.cdx-menu-nav { padding-left: 80px; }
	.cdx-menu-contacto { margin-top: 50px; }
}
@media (max-width: 1199px) {
	.cdx-menu-izq { max-width: 250px; padding: 20px; }
	.cdx-menu-dcha { max-width: 250px; padding: 20px; }
	.cdx-menu-nav { padding-left: 40px; }
}
/* Bajo 992px desaparece la franja de marca y el área pasa a COLUMNA: el carril
   del menú arriba y, al pie, las dos vías de contacto. Antes el bloque entero se
   ocultaba y en móvil no había forma de llamar ni escribir sin salir del panel.

   ⚠️ El botón de cerrar sale del flujo (`position: absolute` contra
   `.cdx-menu-area`, que ya es `relative`) en vez de arrastrar consigo a toda la
   franja derecha: es lo que permite que `.cdx-menu-dcha` vuelva al flujo y
   quede ABAJO, que es donde tiene que ir el contacto. Lleva `z-index` porque el
   carril tiene scroll y los ítems le pasarían por debajo.
   ⚠️ Y `.cdx-menu-centro` necesita `min-height: 0`: sin él, un carril con diez
   ítems no encoge —el mínimo automático de un elemento flex es su contenido— y
   empujaría el contacto fuera de la pantalla en vez de hacer scroll. */
@media (max-width: 991px) {
	.cdx-menu-area { flex-direction: column; }
	.cdx-menu-izq { display: none; }
	.cdx-menu-centro { flex: 1 1 auto; min-height: 0; }
	.cdx-menu-dcha {
		position: static;
		width: 100%; max-width: none;
		flex-shrink: 0;
		padding: 0 24px 32px 50px;
		align-items: flex-start;
	}
	.cdx-menu-nav { padding: 72px 24px 24px 50px; justify-content: flex-start; }
	.cdx-menu-cerrar { position: absolute; top: 16px; right: 16px; z-index: 2; width: 55px; height: 55px; }
	/* Del bloque de contacto se traen SOLO las dos vías, como en la captura del
	   usuario: el rótulo «Contacto» duplicaría el ítem del menú que ya se llama
	   así, y la dirección son tres líneas que aquí no se pueden pulsar. */
	.cdx-menu-contacto { display: block; margin-top: 0; max-width: none; }
	.cdx-menu-contacto__titulo,
	.cdx-menu-contacto__dir { display: none; }
	/* En móvil las dos vías van EN UNA FILA, separadas por un filete vertical
	   (en escritorio siguen apiladas, que es como está la referencia).
	   El filete es `border-left` del segundo enlace, no un elemento aparte: así
	   mide exactamente lo que mide la diana (44px) y desaparece solo si el
	   teléfono no está. Su color es el #313131 del panel, el mismo del filete
	   que separa la franja de marca.
	   Dianas táctiles: `min-height` y no relleno, que es el criterio de §42.3 —
	   la caja de pulsación crece sin mover el texto. 44 es el AAA de WCAG 2.5.5. */
	.cdx-menu-contacto__vias {
		margin-top: 0;
		flex-direction: row;
		align-items: center;
	}
	.cdx-menu-contacto__vias a { display: flex; align-items: center; min-height: 44px; }
	.cdx-menu-contacto__vias a + a {
		margin-left: var(--cdx-vias-sep, 20px);
		padding-left: var(--cdx-vias-sep, 20px);
		border-left: 1px solid #313131;
	}
	/* ⚠ Aquí el cuerpo NO lo puede fijar solo el ALTO de la ventana. El
	   `clamp(24px, 7.2vh, 130px)` de arriba está calibrado para que quepan los
	   diez ítems EN VERTICAL, y en móvil el que manda es el ANCHO: a 375 daba
	   58,5px y «Tu Equipo de Marketing» partía en dos líneas.
	   Por eso se toma el MENOR de los dos: el que cabe a lo alto y el que cabe
	   en UNA línea. El divisor sale medido con la Instrument Sans real a 600 y
	   con el interletraje de −0,03em: el rótulo más largo del menú, «Tu Equipo
	   de Marketing», ocupa 10,405em (los siguientes son «Ayudas Kit consulting»
	   9,574 y «El Blog de Coodex» 7,96). Se divide por 10,8 y no por 10,405
	   para dejar un 3,8 % de holgura.
	   El ancho útil es la ventana menos el relleno del carril: 50+24 aquí. */
	.cdx-menu-lista a { font-size: min(clamp(24px, 7.2vh, 130px), calc((100vw - 74px) / 10.8)); }
}
@media (max-width: 575px) {
	/* El CTA ya encoge en 991 con el resto de píldoras (base.css), como el diseño. */
	.cdx-menu-nav { padding-left: 24px; }
	.cdx-menu-dcha { padding-left: 24px; }
	/* Mismo cálculo, con el relleno de aquí: 24+24. A 375 de ventana da 30,3px
	   y a 320 da 25,2px, con los que el rótulo largo entra en una línea. */
	.cdx-menu-lista a { font-size: min(clamp(24px, 7.2vh, 130px), calc((100vw - 48px) / 10.8)); }
}

/* ⚠ Móvil estrecho: a 320 de ventana quedan 272 útiles y las dos vías del
   contacto miden 234,4 juntas (medido con la Instrument Sans real a 18px), así
   que solo sobran **37,6** para la separación. Con 20+20+1 la fila se pasa 3,4px
   y partiría en dos; con 12+12+1 quedan 12,6 de holgura. Se baja SOLO aquí, en
   el escalón que el tema ya tiene para 320-374. */
@media (max-width: 374px) {
	.cdx-menu-contacto__vias { --cdx-vias-sep: 12px; }
}

/* =============================================================== HERO ==== */

/* El diseño deja 200px desde el borde de la página hasta el H1, con su cabecera
   (90px) SUPERPUESTA encima. La nuestra es sticky y sí ocupa sitio, así que el
   equivalente es 200−90=110. Escalones: 200/150/130 → 110/60/40. */
.cdx-hero { padding-top: 110px; }
@media (max-width: 1199px) { .cdx-hero { padding-top: 60px; } }
@media (max-width: 991px)  { .cdx-hero { padding-top: 40px; } }

/* Cabeza del hero: contexto de posicionamiento. El titular ocupa el ancho
   completo y la columna de información se ancla ABAJO A LA DERECHA sobre él,
   de modo que solo convive con las líneas 2 y 3 del titular. */
.cdx-hero__cabeza { position: relative; }

.cdx-hero__titulo { max-width: none; }
@media (max-width: 1399px) { .cdx-hero__titulo { max-width: 90%; } }
@media (max-width: 991px)  { .cdx-hero__titulo { max-width: 100%; } }

/* ⚠️ **AQUÍ YA NO VA UN INTERLETRAJE PROPIO, y borrarlo fue el arreglo.**
   Entre el 2026-08-25 y el 2026-09-03 el hero llevaba `-3px` (≤767) y `-4px`
   (≤374) para SOLTAR un poco el `-4.2px` global, apurado hasta justo antes de
   provocar un salto de línea. Era un parche local a un problema del token: el
   `-4.2px` era absoluto y en móvil quedaba a -0.07em. Desde que `--cdx-ls-h1`
   es `-.03em` (tokens.css), el h1 de móvil va a **-1.8px**, o sea MÁS SUELTO
   que aquellos -3, así que estas dos reglas ya solo servirían para volver a
   apretarlo. Se quitan: el hero usa el token como el resto de h1. */

/* Mecanismo del diseño: la ÚLTIMA palabra del titular vive dentro de un <span>
   junto al asterisco. Al ser display:flex el span cae en su PROPIA línea y se
   sangra 275px, y palabra y asterisco no se separan nunca. */
.cdx-hero__final {
	display: flex;
	/* El diseño pone `align-items: center`, pero su ornamento es un círculo
	   simétrico. El nuestro es una flecha cuya tinta vive en la parte ALTA de su
	   caja, así que centrada queda flotando: se alinea por línea base y la
	   compensación va en `.cdx-hero__flecha`. */
	align-items: baseline;
	gap: 24px;
	margin-left: 275px;
}
@media (max-width: 1399px) { .cdx-hero__final { margin-left: 100px; } }
@media (max-width: 991px)  { .cdx-hero__final { gap: 10px; } }
@media (max-width: 767px)  { .cdx-hero__final { margin-left: 0; display: inline-flex; } }

/* Media con revelado por scroll. CLAVE: la ALTURA es fija (790px en el diseño,
   500 en tablet) y solo cambia el ANCHO, del 53,6% al 100%. Así la imagen se
   "abre" horizontalmente sin que el bloque crezca ni empuje el contenido. */
/* El envoltorio ocupa SIEMPRE el ancho completo y su `aspect-ratio` (inline, con
   las medidas reales de la imagen) fija el alto de una vez. El marco de dentro
   hereda ese alto y solo anima el ANCHO: al llegar al 100% la foto se ve entera. */
/* El hueco titular→foto es el mismo ritmo que entre secciones (130/80/65): en
   el diseño es su clase `section-margin-top`. Antes se quedaba en 65px fijos.

   ALTO (2026-08-24): lo fija una PROPORCIÓN, no un alto en píxeles. La foto de
   equipo es una panorámica de 1950×627 = **3,11:1**, así que:

       parte visible de la foto = --cdx-hero-ratio ÷ 3,11

   Con la proporción el recorte es el MISMO en toda la escala; con un alto fijo
   no lo era (a 790px se perdía el 19 % a 1600 de ventana pero el 40 % a 1200).
   A 2,5 el hueco mide ~630px a 1600 — justo el alto nativo de la foto, así que
   tampoco se amplía. Referencias: 3,11 → 0 % recortado · **2,5 → 20 %** ·
   2,2 → 29 % · 2,0 → 36 % (se pasaba, y ya ampliaba ×1,26).
   `--cdx-hero-encuadre` mueve el recorte si alguien queda fuera del encuadre. */
.cdx-hero__media {
	--cdx-hero-ratio: 2.5;
	margin-top: var(--cdx-sec-top);
	width: 100%;
	aspect-ratio: var(--cdx-hero-ratio);
}
/* MÓVIL (2026-08-25): antes aquí se cerraba la proporción —2 en ≤767 y 1,6 en
   ≤575— para que la panorámica no quedara en una tira baja. El problema es que
   eso RECORTA: a 2 se ve el 64 % del ancho y a 1,6 solo el 51 %, y el equipo
   ocupa el 73 % central de la foto, así que a 2 se cortaban la persona de la
   izquierda y la de la derecha, y a 1,6 desaparecían las dos.
   Se deja **2,5 también en móvil** (el valor de escritorio): 80 % visible, con
   un 3,5 % de margen a cada lado del grupo, así que no se corta a nadie.
   El precio asumido es un hueco más bajo: ~140px a 375 de ventana. Si algún día
   llega una foto de equipo más alta (§9.2), esto se puede volver a cerrar. */
.cdx-hero__marco {
	/* Punto de partida del revelado: 670px sobre los 1570 del contenedor. */
	width: var(--cdx-revelado, 42.7%);
	height: 100%;
	margin-inline: auto;
	overflow: hidden;
	/* Sin `will-change: width` (§94): no acelera nada (el ancho no se compone en
	   la tarjeta gráfica) y era la última foto del sitio con `will-change`. */
}
.cdx-hero__marco img { width: 100%; height: 100%; object-fit: cover; object-position: var(--cdx-hero-encuadre, center center); }

@media (max-width: 767px) { .cdx-hero__marco { width: 100% !important; } }

@media (prefers-reduced-motion: reduce) {
	.cdx-hero__marco { width: 100%; }
}

/* Intro bajo el hero (texto grande de posicionamiento) */
.cdx-intro-grande {
	font-size: var(--cdx-fs-h3);
	line-height: 1.45;
	letter-spacing: -.01em;
	max-width: 34ch;
	margin: 0;
}
.cdx-dos-columnas {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--cdx-gap);
	align-items: start;
}
@media (max-width: 991px) { .cdx-dos-columnas { grid-template-columns: 1fr; } }

/* ========================================================= CONTADORES ====
   Valores literales del diseño: rejilla de 4 con GAP 20px (no 0: es lo que da
   aire suficiente para que la etiqueta entre en una línea), cada celda con
   línea vertical de 1px #C5C5C5 y 28px de sangría. Cifra 100px, etiqueta 18px
   SIN ancho máximo ni separación (la caja es flex y las pega). */

.cdx-contadores {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	align-items: center;
	gap: 20px;
	list-style: none;
	margin: 0;
	padding: 0;
}
/* TODOS llevan línea a la izquierda, también el primero (como en el diseño). */
.cdx-contador {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	padding-left: 28px;
	border-left: 1px solid var(--cdx-gris-borde);
}
/* `display:flex; align-items:center` como su `.counter-item`: el rodillo y el
   signo son hermanos y se centran entre sí, sin depender de la línea base. */
.cdx-contador__cifra {
	display: flex;
	align-items: center;
	font-size: 48px;
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.1;
	letter-spacing: -2.5px;
	color: var(--cdx-negro-puro);
}
@media (min-width: 992px)  { .cdx-contador__cifra { font-size: 70px; } }
@media (min-width: 1200px) { .cdx-contador__cifra { font-size: 80px; } }
@media (min-width: 1400px) { .cdx-contador__cifra { font-size: 100px; } }

.cdx-contador__texto {
	margin: 0;
	font-size: 18px;
	line-height: 1.44444;
	color: var(--cdx-negro);
}

/* Cortes: 4 → 3 (991) → 2 (767 y por debajo). El `gap: 20px` se mantiene en
   todos (antes abríamos el hueco de fila a 3rem en tablet, que el diseño no
   hace). Van en ORDEN DESCENDENTE de anchura: al ser todos `max-width` con la
   misma especificidad, gana el último que cuadra.

   ⚠️ MÓVIL (2026-08-25) — DESVIACIÓN del diseño, pedida por el usuario. El
   original quita el borde y centra el contenido en ≤767, y baja a UNA columna en
   ≤575. Aquí se queda una **rejilla 2×2 con el borde izquierdo en cada celda**,
   que es lo que pidió: cuatro valores en dos columnas y los bordes alineados.
   Por eso NO se repiten aquí `border-left: 0` ni el centrado: las reglas base
   (borde de 1px y sangría de 28) valen tal cual, y el contenido vuelve a ir
   alineado a la izquierda, que es lo único coherente con un borde lateral. */
@media (max-width: 991px) { .cdx-contadores { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 767px) {
	.cdx-contadores {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		/* `stretch`, no `center`: las etiquetas ocupan distinto número de líneas
		   («Clientes han confiado en nosotros» son tres y «Casos de éxito» una),
		   y centradas cada celda mediría lo que su contenido, así que los bordes
		   de una misma fila empezarían y acabarían a distinta altura. Estirando,
		   las dos celdas de cada fila miden igual y los bordes se alinean. */
		align-items: stretch;
	}
	/* Cifra un punto más grande que el 48 del diseño. El techo lo marca el
	   rodillo de «+200» dentro de la celda: a 375 de ventana quedan 137,5px
	   útiles y mide 126,8 a 52px (10,7 de aire). A 54 se queda en 5,9 y a 56 en
	   1,1, que ya es nada. */
	.cdx-contador__cifra { font-size: 52px; }
	/* Interlineado más cerrado que el 144,444 % del diseño: la etiqueta llega a
	   tres líneas («Clientes han confiado en nosotros») y así el bloque no crece
	   por el aumento de la cifra. */
	.cdx-contador__texto { line-height: 1.3; }
}
/* Móviles estrechos: con 2 columnas el ancho útil por celda se queda en 110px a
   320 de ventana, y el rodillo de «+200» mide 117,3 renderizado. Se recortan el
   hueco y la sangría —el borde se mantiene— hasta devolver 124px de útil, que
   deja 6,7px de aire. Con la sangría de 28 se desbordaba. */
@media (max-width: 374px) {
	.cdx-contadores { gap: 16px; }
	.cdx-contador { padding-left: 16px; }
	/* Aquí la cifra NO sube: con 124px útiles, «+200» mide 117,3 a 48px y ya a
	   50 se pone en 122, con 2px de aire. Se queda en el 48 de base. */
	.cdx-contador__cifra { font-size: 48px; }
}
/* ========================================================== PORTFOLIO ==== */

.cdx-portfolio { background: var(--cdx-negro); color: var(--cdx-blanco); }
.cdx-portfolio h2, .cdx-portfolio h3 { color: var(--cdx-blanco); }
.cdx-portfolio .cdx-enlace { color: var(--cdx-blanco); }

/* Titular opcional a la izquierda + enlace opcional a la derecha: mismo
   patrón que `.cdx-seccion-cabecera` (base.css), que esta clase también
   lleva en el marcado — así hereda su `flex-wrap` de seguridad en móvil y
   solo hace falta redeclarar el margen, propio de este bloque. Pedido por el
   usuario el 2026-09-28; antes el bloque no pintaba título visible y este
   selector solo alojaba el enlace. */
/* Su `quanto__header`: 90px hasta las piezas (80 ≤1199 · 60 ≤991). Teníamos 60. */
/* ⚠️ `align-items: flex-start`, no el `flex-end` que trae `.cdx-seccion-cabecera`
   por defecto: el usuario pidió el título alineado por ARRIBA con el enlace,
   no por abajo. Se sobreescribe solo aquí, no en la clase compartida — las
   otras diez plantillas que la usan siguen con `flex-end`. */
.cdx-portfolio__cabecera { align-items: flex-start; margin-bottom: 90px; }

/* Retícula del diseño: DOS columnas de distinto ancho (42% / 50% con 8% de
   hueco) y la derecha bajada. No es una rejilla regular: cada pieza lleva su
   propio ancho y sangría en variables (`--cdx-p-ancho`, `--cdx-p-sangria`) que
   pone la plantilla, y su proporción va inline en el marco. */
.cdx-rejilla-portfolio { display: flex; align-items: flex-start; }
.cdx-portfolio__col { display: flex; flex-direction: column; }
.cdx-portfolio__col--0 { width: 42%; margin-right: 8%; }
/* Cuánto baja la columna derecha: 126 en la portada y 90 en la plantilla de
   mosaico, los dos medidos. Va en variable porque la retícula la comparten las
   dos páginas y es lo único que cambia entre ellas. */
.cdx-portfolio__col--1 { width: 50%; margin-top: var(--cdx-portfolio-desfase, 126px); }

/* Variante CLARA de la retícula (página de Casos de éxito). La de la portada va
   sobre banda negra; esta va sobre blanco, así que se devuelven los colores al
   texto. La estructura no cambia. */
.cdx-portfolio--claro { background: none; color: var(--cdx-negro); }
.cdx-portfolio--claro h2,
.cdx-portfolio--claro h3 { color: var(--cdx-negro); }
.cdx-portfolio--claro .cdx-enlace { color: var(--cdx-negro); }
/* El servicio bajo el título, en gris sobre blanco (en la banda negra va en
   blanco, que sobre claro no se leería). */
.cdx-portfolio--claro .cdx-proyecto__meta { color: var(--cdx-gris-texto); }

.cdx-proyecto { width: var(--cdx-p-ancho, 100%); margin-left: var(--cdx-p-sangria, 0); }
.cdx-proyecto:not(:last-child) { margin-bottom: 150px; }

.cdx-proyecto__media {
	overflow: hidden;
	/* SIN fondo, como su `.quanto-project-thumb` (medido: transparente). Con un
	   relleno de reserva (teníamos `--cdx-blanco-15`) el hueco se veía como un
	   rectángulo de otro gris sobre la banda oscura mientras la foto entraba, y
	   el barrido acababa en un corte muy visible. El `aspect-ratio` en línea ya
	   reserva el sitio, así que no hace falta pintar nada. */
	background: transparent;
}
.cdx-proyecto__media img {
	width: 100%; height: 100%;
	object-fit: cover;
	transition:
		transform var(--cdx-transicion-lenta),
		translate var(--cdx-rev-dur) var(--cdx-rev-ease) var(--cdx-d, 0s),
		scale var(--cdx-rev-dur) var(--cdx-rev-ease) var(--cdx-d, 0s);
}
/* ⚠⚠ **LAS TRES TRANSICIONES VAN JUNTAS, Y NO ES OPCIONAL.**
   El zoom del hover va en `transform` y el barrido de `.cdx-revelado` va en
   `translate`/`scale`: son propiedades distintas y **los valores** sí se suman
   sin pisarse. Pero `transition` es UNA sola propiedad, así que una segunda
   declaración **reemplaza la lista entera**, no la amplía. Esta regla y la de
   `.cdx-revelado__marco > img` (base.css) tienen la MISMA especificidad (0,1,1)
   y `bloques.css` carga después, así que ganaba esta y el resultado computado
   era `transition-property: transform` a secas: el `translate` y el `scale` del
   barrido **saltaban sin animar** y el efecto quedaba en un simple deslizamiento
   del marco. Por eso hay que repetirlas aquí. */
.cdx-proyecto:hover .cdx-proyecto__media img { transform: scale(1.04); }

/* Pie de cada pieza: 20px hasta el título, y el servicio justo debajo. */
.cdx-proyecto__titulo { margin: 20px 0 0; font-size: var(--cdx-fs-h3); line-height: var(--cdx-lh-tarjeta); letter-spacing: var(--cdx-ls-tarjeta); }
.cdx-proyecto__meta { margin: 0; font-size: 18px; line-height: 1.44; color: var(--cdx-blanco); }

/* Su `project-row-gap`: 150 → 80 (≤1199) → 60 (≤991). Teníamos 100 y 60. */
@media (max-width: 1199px) {
	.cdx-portfolio__col--1 { margin-top: 80px; }
	.cdx-proyecto:not(:last-child) { margin-bottom: 80px; }
	.cdx-portfolio__cabecera { margin-bottom: 80px; }
}
@media (max-width: 991px) {
	.cdx-proyecto:not(:last-child) { margin-bottom: 60px; }
	.cdx-portfolio__cabecera { margin-bottom: 60px; }
	.cdx-proyecto__titulo { margin-top: 10px; }   /* su `quanto-project-content` */
}
/* En móvil se apila todo y cada pieza ocupa el ancho completo, sin sangrías. */
@media (max-width: 767px) {
	.cdx-rejilla-portfolio { flex-direction: column; }
	.cdx-portfolio__col--0, .cdx-portfolio__col--1 { width: 100%; margin-right: 0; margin-top: 0; }
	.cdx-portfolio__col--0 > :last-child { margin-bottom: 60px; }
	.cdx-proyecto { width: 100% !important; margin-left: 0 !important; }
	/* La separación entre piezas y la de la cabecera ya son 60px desde ≤991,
	   igual que el diseño; aquí no se vuelven a bajar. */
}

/* =========================================================== SERVICIOS === */

.cdx-servicios-home { background: var(--cdx-gris-fondo); }
.cdx-servicios-home__titulo { max-width: 12ch; }   /* fuerza el corte en 2 líneas */

/* Tarjetas EN CAJA BLANCA, como el diseño: fondo blanco, sin borde ni sombra,
   relleno 48/40/44 y 24px de hueco entre ellas.
   ALINEACIÓN: el contenido se ancla ARRIBA (nada de `space-between`, que dejaba
   el título a distinta altura según las líneas del extracto). Como el icono
   mide fijo y su margen también, icono y título caen a la misma altura en las
   cuatro tarjetas; el enlace se va abajo del todo con `margin-top:auto`, así
   que también queda alineado. */
.cdx-rejilla-servicios {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 24px;
	list-style: none; margin: 0; padding: 0;
}
.cdx-rejilla-servicios > li { display: flex; }
.cdx-tarjeta-servicio {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	background: var(--cdx-blanco);
	padding: 48px 40px 44px;
	width: 100%;
	height: 100%;
}
.cdx-tarjeta-servicio__icono {
	margin-bottom: 60px;
	line-height: 0;
	color: var(--cdx-negro);
	flex: none;              /* alto fijo: es lo que mantiene los títulos a la par */
}
.cdx-tarjeta-servicio__icono img,
.cdx-tarjeta-servicio__icono svg {
	width: 52px; height: 52px;
	object-fit: contain; object-position: left center;
	display: block;
}
/* El icono enlaza (§83). El enlace se ciñe al icono, 52×52, y no cambia
   nada de la medida: ni hueco ni color. Al pasar por él se relanza la flecha
   de «Saber más», como con el título (el enganche está en base.css). */
.cdx-tarjeta-servicio__icono-enlace { display: inline-block; color: inherit; }
/* Ocupa todo el alto sobrante para poder empujar el enlace al fondo. */
.cdx-tarjeta-servicio__datos { display: flex; flex-direction: column; align-items: flex-start; flex: 1 1 auto; width: 100%; }

@media (max-width: 991px) {
	.cdx-tarjeta-servicio { padding: 35px 30px; }
	.cdx-tarjeta-servicio__icono { margin-bottom: 30px; }
}
.cdx-tarjeta-servicio__titulo { margin: 0 0 16px; font-size: var(--cdx-fs-h3); line-height: var(--cdx-lh-tarjeta); letter-spacing: var(--cdx-ls-tarjeta); }
/* El hueco de 90px del diseño va aquí, como separación MÍNIMA; el enlace se
   pega al fondo de la caja con `margin-top:auto` para que todos coincidan. */
.cdx-tarjeta-servicio__texto { margin: 0 0 90px; font-size: var(--cdx-fs-body); line-height: var(--cdx-lh-body); }
.cdx-tarjeta-servicio .cdx-enlace { margin-top: auto; }
@media (max-width: 1199px) { .cdx-tarjeta-servicio__texto { margin-bottom: 45px; } }
@media (max-width: 991px) {
	.cdx-tarjeta-servicio__titulo { margin-bottom: 10px; }
	.cdx-tarjeta-servicio__texto { margin-bottom: 30px; }
}
@media (max-width: 767px) { .cdx-tarjeta-servicio__texto { margin-bottom: 20px; } }

/* Escalones de columna del diseño (sus clases `col-xxl-3 col-lg-4 col-md-6`):
   4 columnas ≥1400 · 3 entre 992 y 1399 · 2 entre 768 y 991 · 1 por debajo.
   Antes saltábamos de 4 a 2 en 1199 y a 1 en 575: faltaba el escalón de 3 y los
   otros dos caían un breakpoint tarde. El hueco es 24px en todos ellos. */
@media (max-width: 1399px) { .cdx-rejilla-servicios { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 991px)  { .cdx-rejilla-servicios { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .cdx-rejilla-servicios { grid-template-columns: 1fr; } }

/* ============================================================== LOGOS ==== */

/* Rejilla de 6 columnas × 240px de alto con las celdas colocadas de forma
   ASIMÉTRICA (la plantilla pone `grid-column`/`grid-row` a cada una): dos
   arriba, la fila central completa y dos abajo. Los huecos quedan vacíos a
   propósito. Borde 1px #C5C5C5 con margen negativo para que la línea
   compartida no salga doble. */
.cdx-rejilla-logos {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	/* Celda de 240px de alto, FIJA (el diseño la mantiene también en tablet;
	   el clamp que había la dejaba en ~163px a 1024). */
	grid-auto-rows: 240px;
	gap: 0;
	list-style: none;
	margin: 0;
	padding: 0;
}
/* Rótulo: columna 1 de la primera fila, arrancando a la MISMA altura que el
   borde superior de las cajas de esa fila, y sin recuadro. */
.cdx-logos__rotulo {
	grid-column: 1;
	grid-row: 1;
	align-self: start;
	margin: 0;
	font-size: 40px;
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.15;
	letter-spacing: -.02em;
	color: var(--cdx-negro);
}
@media (max-width: 991px) { .cdx-logos__rotulo { font-size: 30px; } }
.cdx-logo-cliente {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
	border: 1px solid var(--cdx-gris-borde);
	margin: -1px 0 0 -1px;                        /* colapsa la línea compartida */
}
/* Tamaño ajustado sobre el sitio: los logos ocupan ~170×84 dentro de una celda
   de 262×240. (Iban topados a 44px de alto y se veían diminutos.) */
.cdx-logo-cliente img {
	width: auto;
	max-width: 75%;
	max-height: 85px;
	object-fit: contain;
	transition: opacity var(--cdx-transicion);
}
.cdx-logo-cliente:hover img { opacity: .6; }

/* Al estrechar se pierde la asimetría: las celdas se recolocan solas.
   El diseño aguanta las 6 columnas hasta 991 (a 1024 seguían siendo 6) y en
   móvil baja a 2, no a 3. */
@media (max-width: 1199px) { .cdx-logo-cliente img { max-width: 82%; } }
@media (max-width: 991px) {
	.cdx-rejilla-logos { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 180px; }
	.cdx-logos__rotulo, .cdx-logo-cliente { grid-column: auto !important; grid-row: auto !important; }
	.cdx-logos__rotulo { grid-column: 1 / -1 !important; align-self: auto; margin-bottom: 1.5rem; }
}
@media (max-width: 767px) { .cdx-rejilla-logos { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 140px; } }

/* ====================================================== RUPTURA (foto) ===
   Franja a ancho completo de ventana entre bloques. El marco recorta y la
   imagen es más alta que él, así el parallax la puede desplazar sin dejar
   huecos. Sin JS (o con menos movimiento pedido) se ve centrada y quieta. */

/* Solo margen ARRIBA: el hueco de debajo lo pone ya el relleno del bloque
   siguiente. Entre secciones el diseño deja 130px en total, no 260. */
.cdx-ruptura {
	margin-top: var(--cdx-sec-top);
	margin-bottom: 0;
}
.cdx-ruptura__marco {
	overflow: hidden;
	height: clamp(16rem, 8rem + 26vw, 34rem);   /* 256 → 544 */
}
.cdx-ruptura__img {
	display: block;
	width: 100%;
	height: 130%;
	object-fit: cover;
	object-position: center;
	transform: translate(0, -11.5%);   /* punto medio del recorrido */
	/* ⚠️ En 2D y SIN `will-change` (§93). Con `translate3d` + `will-change` la
	   foto iba a una capa de la tarjeta gráfica, que la reescala con un filtro
	   bilineal simple: en la ficha de caso se veía más blanda que abierta suelta
	   en el navegador, aunque el fichero era el mismo. En 2D Chrome la pinta con
	   su filtro de alta calidad. El parallax la sigue moviendo igual (pieza 2c). */
}
@media (prefers-reduced-motion: reduce) {
	.cdx-ruptura__img { height: 100%; transform: none; }
}

/* ================================================= PROBLEMA / SOLUCIÓN ===
   LISTADO en filas, no rejilla de tarjetas: cada fila lleva línea arriba,
   `55px 0` de relleno y tres piezas — pregunta (330px) · respuesta + enlace
   (680px) · círculo con flecha a la derecha. Al pasar por CUALQUIER punto de la
   fila el círculo se pone en negro y la fila se ensancha 25px, como el diseño. */

.cdx-lista-ps {
	list-style: none; margin: 0; padding: 0;
	/* Alto de referencia: el de un título de 4 líneas. En escritorio TODAS las
	   filas miden esto, sea cual sea el largo del texto. */
	--cdx-ps-lineas: 4;
	--cdx-ps-alto: calc(var(--cdx-ps-lineas) * var(--cdx-lh-tarjeta) * var(--cdx-fs-h3));
}
.cdx-ps__fila {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 15px;
	padding: 55px 0;
	border-top: 1px solid var(--cdx-gris-borde);
	transition: padding .2s linear;
	overflow: hidden;
}
/* El diseño NO cierra el listado con una línea abajo: cada fila lleva solo la
   de arriba, y la última se queda sin relleno inferior. */
.cdx-ps__fila:last-child { padding-bottom: 0; }
@media (min-width: 992px) {
	.cdx-ps__fila { height: calc(var(--cdx-ps-alto) + 110px); }
	.cdx-ps__fila:hover { padding-inline: 25px; }
}

.cdx-ps__titulo {
	max-width: 330px;
	width: 100%;
	flex-shrink: 0;
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-ps__info { max-width: 680px; width: 100%; flex-shrink: 0; }
.cdx-ps__texto { margin: 0; font-size: var(--cdx-fs-body); line-height: var(--cdx-lh-body); }
.cdx-ps__info .cdx-enlace { margin-top: 20px; }

/* Recorte con puntos suspensivos para que ningún texto empuje la altura: el
   título a 4 líneas y el extracto a las que caben dejando sitio al enlace. */
@media (min-width: 992px) {
	.cdx-ps__titulo,
	.cdx-ps__texto {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}
	.cdx-ps__titulo { -webkit-line-clamp: var(--cdx-ps-lineas); }
	.cdx-ps__texto { -webkit-line-clamp: 3; }
}

/* MÓVIL (2026-08-25): en columna cada fila crecía muchísimo, porque nuestras
   descripciones son largas y aquí abajo no había recorte ninguno (el de arriba
   solo entra a partir de 992). Se limita el extracto a DOS líneas, terminando
   en puntos suspensivos. El título NO se toca: es lo que identifica la fila. */
@media (max-width: 767px) {
	.cdx-ps__texto {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		overflow: hidden;
	}
}

/* Enlace de cierre, en la esquina inferior derecha del listado. */
.cdx-ps__pie { margin: 28px 0 0; display: flex; justify-content: flex-end; }

/* Círculo con flecha: gris claro en reposo, NEGRO al pasar por la fila. */
.cdx-ps__circulo {
	width: 70px; height: 70px;
	flex-shrink: 0;
	display: flex; align-items: center; justify-content: center;
	border-radius: 50%;
	background: var(--cdx-gris-fondo);
	border: 1px solid var(--cdx-gris-fondo);
	color: var(--cdx-negro);
	transition: background .5s, border-color .5s, color .5s;
}
.cdx-ps__fila:hover .cdx-ps__circulo {
	background: var(--cdx-negro);
	border-color: var(--cdx-negro);
	color: var(--cdx-blanco);
}
/* El relevo de las dos flechas también se dispara desde la fila entera. */
.cdx-ps__fila:hover .cdx-ps__circulo .cdx-flecha__a { top: var(--f-fuera-t); left: var(--f-fuera-i); }
.cdx-ps__fila:hover .cdx-ps__circulo .cdx-flecha__b { bottom: var(--f-fin-b); left: 0; }

/* FILA SIN ENLACE (§99, 2026-10-07). Lo pide el interruptor
   `sin_enlace_en_servicio` de la ficha de P/S, y solo en la ficha de servicio.
   La plantilla ya no pinta ni el enlace, ni «Saber más», ni el círculo; aquí se
   quita el gesto de hover —el ensanche de 25 px—, que sin nada que pinchar
   prometería un clic que no existe.
   ⚠️ El texto se queda en su COLUMNA: sin el círculo, `space-between` reparte
   el sitio libre entre DOS piezas en vez de tres y la respuesta se desplazaba
   (medido a 1024: 512 contra 420 de las filas con enlace). Un margen no lo
   arregla, porque el reparto depende del número de piezas. Lo que sí: un
   `::after` vacío del ancho del círculo, que ocupa su sitio como tercera
   pieza. Por debajo de 992 la fila va en columna y no hace falta. */
@media (min-width: 992px) {
	.cdx-ps__fila--sin-enlace:hover { padding-inline: 0; }
	.cdx-ps__fila--sin-enlace::after {
		content: "";
		width: 70px;
		flex-shrink: 0;
	}
}

@media (max-width: 1199px) {
	.cdx-ps__titulo { max-width: 300px; }
	.cdx-ps__info { max-width: 400px; }
}
@media (max-width: 991px) {
	/* El diseño mantiene los 55px también aquí: solo cambia a columna. */
	.cdx-ps__fila { flex-direction: column; gap: 16px; }
	.cdx-ps__titulo, .cdx-ps__info { max-width: 100%; }
	.cdx-ps__titulo { order: 1; }
	.cdx-ps__info { order: 2; }
	.cdx-ps__circulo { order: 0; width: 50px; height: 50px; }
}

/* ------------------------------------------------------ Utilidades ------ */
.cdx-titulo-bloque { margin-bottom: var(--cdx-espacio-bloque); }
.cdx-bloque-pie { margin: var(--cdx-espacio-bloque) 0 0; }

/* ============================================================= CTA ======= */

/* Último bloque de la página: sí necesita relleno abajo, contra el pie. */
.cdx-cta-final { text-align: center; padding-bottom: var(--cdx-sec-bottom); }
/* Ilustración del cierre: por defecto el vector `assets/img/grafico-cta-home.svg`
   y, si el campo `cta_final_imagen` tiene algo, ese ráster. Reducida respecto a
   su tamaño real (900px): acompaña al titular sin comérselo. ~528px a 1600 de
   ventana y 300 en móvil. El `max-width: 100%` de base.css la frena sola en
   pantallas muy estrechas, así que el mínimo no desborda.
   ⚠️ Las medidas NO se tocaron al pasar del WebP al vector: el SVG lleva el
   mismo `width`/`height` 900×753 y el dibujo en la misma posición dentro de ese
   encuadre, así que esta misma regla le da la misma caja. */
.cdx-cta-final__ilustracion {
	display: block;
	margin: 0 auto clamp(1.5rem, 1rem + 2vw, 2.5rem);
	width: clamp(300px, 33vw, 530px);
	height: auto;
}

/* ---------- Ilustración del CTA final, ANIMADA ---------- */
/* Las diez partes del SVG entran desde su propio lado con el MISMO vocabulario
   que `.cdx-fade`: los mismos tokens de duración (1,15s), curva (`power2.out`)
   y escalón (.15s), así que va al compás del resto del sitio. Dos diferencias,
   y las dos a propósito:

   1. ⚠️ EL DISPARO ES ÚNICO. `.cdx-disparo` en la raíz del `<svg>` hace que el
      observador le ponga `es-visible` A ELLA, y de su estado cuelgan las diez
      partes. Con `.cdx-fade` en cada parte, el observador dispararía cada una
      por su cuenta al cruzar SU altura el umbral —la ilustración mide 441px—,
      así que el orden de entrada lo decidiría la velocidad del scroll y no la
      coreografía. Es la razón de que exista `.cdx-disparo`.

   2. ⚠️ EL RECORRIDO NO SON LOS 50px DEL TOKEN. Dentro de un SVG, `translateX`
      va en UNIDADES DEL viewBox, no en píxeles de pantalla: los 50 del token
      serían 55px a 1600 —un 10 % del ancho de la ilustración— y las piezas se
      cruzarían unas con otras. Van **22 unidades**, que son 24,3px a 1600 y
      13,8px a 375. Y precisamente por ir en unidades del viewBox el recorrido
      ESCALA con la ilustración, así que se ve proporcionalmente igual en
      cualquier ancho.

   El turno de cada parte es `data-cdx-paso`, y el retardo se calcula
   multiplicando el token: retemplar la coreografía entera es cambiar
   `--cdx-anim-delay`. El orden va de DENTRO HACIA FUERA —el dibujo se levanta
   desde su núcleo (el cubo, el quesito) y se cierra con los extremos (las
   fichas de la derecha, las barritas de la izquierda)—, y el armazón (la
   retícula isométrica y sus guías) va primero y solo FUNDE, sin desplazarse:
   es el escenario, y moverlo haría bailar el dibujo entero.

   ⚠️ El SVG va EN LÍNEA y no con `<img src>` por esto mismo: un `<img>` está
   aislado y el CSS de la página no puede entrar a animar sus partes. */

.cdx-ilus__parte {
	opacity: 0;
	transition:
		opacity var(--cdx-anim-dur) var(--cdx-anim-ease) var(--cdx-d, 0s),
		transform var(--cdx-anim-dur) var(--cdx-anim-ease) var(--cdx-d, 0s);
	will-change: opacity, transform;
}
.cdx-ilus__parte[data-cdx-dir="left"]  { transform: translateX(calc(-1 * var(--cdx-ilus-offset, 22px))); }
.cdx-ilus__parte[data-cdx-dir="right"] { transform: translateX(var(--cdx-ilus-offset, 22px)); }

/* Turnos. El paso 0 (el armazón) se queda con el retardo 0 de la base. */
.cdx-ilus__parte[data-cdx-paso="1"] { --cdx-d: calc(var(--cdx-anim-delay) * 1); }
.cdx-ilus__parte[data-cdx-paso="2"] { --cdx-d: calc(var(--cdx-anim-delay) * 2); }
.cdx-ilus__parte[data-cdx-paso="3"] { --cdx-d: calc(var(--cdx-anim-delay) * 3); }
.cdx-ilus__parte[data-cdx-paso="4"] { --cdx-d: calc(var(--cdx-anim-delay) * 4); }
.cdx-ilus__parte[data-cdx-paso="5"] { --cdx-d: calc(var(--cdx-anim-delay) * 5); }
.cdx-ilus__parte[data-cdx-paso="6"] { --cdx-d: calc(var(--cdx-anim-delay) * 6); }
.cdx-ilus__parte[data-cdx-paso="7"] { --cdx-d: calc(var(--cdx-anim-delay) * 7); }

.cdx-ilus.es-visible .cdx-ilus__parte { opacity: 1; transform: none; }

/* Sin movimiento: el dibujo, quieto y entero. El JS ya pone `es-visible` de
   entrada cuando hay `prefers-reduced-motion`, pero esto lo deja atado también
   si el estado llega más tarde (por ejemplo tras un filtrado sin recarga). */
@media (prefers-reduced-motion: reduce) {
	.cdx-ilus__parte { opacity: 1; transform: none; transition: none; will-change: auto; }
}
/* Tres líneas en escritorio y algo más de cuerpo que un H2 normal, para que el
   cierre de la página pese. El ×1,15 va sobre el token para que siga sus mismos
   escalones (92 · 80,5 · 69 · 46) sin repetir media queries. Con 24ch reparte
   en 3 líneas de 1280px de ventana en adelante; por debajo pasa a 4, que es lo
   correcto porque ya no cabe. Verificado de 375 a 1920: no desborda nunca. */
.cdx-cta-final__titulo {
	max-width: 24ch;
	margin-inline: auto;
	font-size: calc(var(--cdx-fs-h2) * 1.15);
}
.cdx-cta-final__boton { margin-top: clamp(1.75rem, 1rem + 2.5vw, 3rem); }

/* ================================================================ PIE ==== */

.cdx-pie { background: var(--cdx-negro); color: var(--cdx-blanco); padding-top: clamp(3rem, 1.5rem + 5vw, 6rem); }
.cdx-pie h2, .cdx-pie h3 { color: var(--cdx-blanco); }
.cdx-pie a { transition: opacity var(--cdx-transicion); }
.cdx-pie a:hover { opacity: .6; }

/* Va A SANGRE, de borde a borde de la ventana: en `footer.php` cuelga
   directamente del <footer>, FUERA de `.cdx-contenedor`. Estaba dentro y se
   quedaba con el gutter de 12px del boxed, que parecía un margen mal puesto.
   Al sacarla, la línea inferior hace también de separador a todo lo ancho. */
.cdx-pie__marquesina {
	padding-bottom: clamp(2.5rem, 1.5rem + 4vw, 5rem);
	border-bottom: 1px solid var(--cdx-blanco-15);
}
.cdx-pie__marquesina .cdx-marquesina__item { color: var(--cdx-blanco); }

/* Franja marca + columnas. A la marca se le da MÁS ancho del que necesita su
   texto: así las tres columnas de enlaces quedan agrupadas a la derecha, con
   aire entre ellas y el bloque del logo, y más juntas entre sí al ser más
   estrechas. */
.cdx-pie__cols {
	display: grid;
	grid-template-columns: 2.6fr 1fr 1fr 1.15fr;
	gap: var(--cdx-gap);
	padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
}
/* El diseño no rotula las columnas; el estilo queda por si alguien pone título. */
.cdx-pie__rotulo { font-size: var(--cdx-fs-small); text-transform: uppercase; letter-spacing: .08em; opacity: .5; margin-bottom: 1.25rem; }
.cdx-pie__lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .9rem; }
.cdx-pie__lista a, .cdx-pie__direccion { font-size: var(--cdx-fs-small); line-height: 1.44; font-weight: var(--cdx-peso-normal); }
/* La dirección va seguida, sin saltos forzados: fluye con el ancho de su
   columna y así ocupa las líneas justas. */
.cdx-pie__direccion { max-width: none; text-wrap: pretty; }
.cdx-pie__logo { display: inline-block; }
.cdx-pie__logo img, .cdx-pie__logo svg { height: 44px; width: auto; }

/* Descripción bajo el logo: mismo formato de texto que el cuerpo y en BLANCO
   (antes iba al 60 % de opacidad y se leía apagada). */
.cdx-pie__texto {
	color: var(--cdx-blanco);
	max-width: 34ch;
	margin-top: 1.75rem;
	font-size: var(--cdx-fs-small);
	line-height: 1.6;
}
.cdx-pie__texto p { margin: 0; }

/* Redes: iconos monocromos bajo la descripción. */
.cdx-pie__redes {
	list-style: none;
	margin: 2.25rem 0 0;
	padding: 0;
	display: flex;
	gap: 1.25rem;
}
.cdx-pie__redes a {
	display: grid;
	place-content: center;
	width: 42px; height: 42px;
	border: 1px solid var(--cdx-blanco-15);
	border-radius: 50%;
	color: var(--cdx-blanco);
	transition: background var(--cdx-transicion), color var(--cdx-transicion), border-color var(--cdx-transicion);
}
.cdx-pie__redes a:hover {
	opacity: 1;                       /* gana al :hover general del pie */
	background: var(--cdx-blanco);
	border-color: var(--cdx-blanco);
	color: var(--cdx-negro);
}

/* Logos de partners, centrados y al final de todo. */
.cdx-pie__partners {
	list-style: none;
	margin: 0;
	/* ⚠️ `padding-inline: 0` es IMPRESCINDIBLE, no es cosmético: un <ul> trae
	   ~40px de `padding-inline-start` del navegador, y aquí solo se declaraba
	   `padding-bottom`, que NO lo resetea. El `justify-content: center` centraba
	   los logos dentro de una caja que empezaba 40px más adentro, así que el
	   grupo entero salía ~20px desplazado a la DERECHA, en todos los tamaños.
	   Las otras listas del pie (`.cdx-pie__lista`, `.cdx-pie .cdx-menu`) sí
	   hacían `padding: 0`; esta se quedó fuera. */
	padding-inline: 0;
	padding-top: 0;
	padding-bottom: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(2rem, 1rem + 4vw, 4.5rem);
}
.cdx-pie__partners img { width: auto; max-height: 56px; object-fit: contain; }

/* MÓVIL (2026-08-25): los tres logos se repartían en dos o tres líneas, porque
   el hueco mínimo es de 2rem y a `width:auto` cada logo pide lo suyo. Aquí se
   fuerza UNA sola fila: tres celdas iguales (`flex:1` con `min-width:0`, que es
   lo que permite que una caja flex se encoja por debajo de su contenido) y el
   logo escalado para caber dentro de la suya. */
@media (max-width: 767px) {
	.cdx-pie__partners {
		flex-wrap: nowrap;
		gap: 1rem;
	}
	.cdx-pie__partners li {
		flex: 1 1 0;
		min-width: 0;
		display: flex;
		justify-content: center;
	}
	.cdx-pie__partners img { max-width: 100%; max-height: 40px; }
}

.cdx-pie__legal {
	display: flex; align-items: center; justify-content: space-between;
	gap: var(--cdx-gap); flex-wrap: wrap;
	padding-block: 1.75rem;
	border-top: 1px solid var(--cdx-blanco-15);
	font-size: var(--cdx-fs-legal);
	color: var(--cdx-blanco-60);
}
.cdx-pie__legal .cdx-menu { gap: 1.5rem; }
.cdx-pie__legal .cdx-menu a { font-size: var(--cdx-fs-legal); font-weight: var(--cdx-peso-normal); }
.cdx-pie__copyright { margin: 0; }

/* La línea legal va un punto por debajo del resto del pie: es letra pequeña de
   cierre, no navegación. En móvil baja bastante más y se cierra el interlineado
   para que los cuatro enlaces ocupen el menor número de líneas posible. */
@media (max-width: 767px) {
	.cdx-pie__legal { line-height: 1.25; }
	.cdx-pie__legal .cdx-menu { gap: .5rem 1rem; line-height: 1.25; }
	.cdx-pie__legal .cdx-menu a { line-height: 1.25; }

	/* Cierre del pie CENTRADO, en la misma vertical que los logos de partners:
	   el `space-between` de escritorio dejaba el copyright pegado a un borde y
	   el menú al otro, que en estrecho se leía descolgado. */
	.cdx-pie__legal { flex-direction: column; justify-content: center; text-align: center; }
	.cdx-pie__legal .cdx-menu { justify-content: center; }
}

@media (max-width: 1199px) {
	/* La marca pasa a ocupar toda la fila y las tres columnas quedan debajo. */
	.cdx-pie__cols { grid-template-columns: repeat(3, 1fr); row-gap: 3rem; }
	.cdx-pie__marca { grid-column: 1 / -1; }
	.cdx-pie__texto { max-width: 46ch; }
}
@media (max-width: 767px) { .cdx-pie__cols { grid-template-columns: 1fr 1fr; } }
@media (max-width: 479px) { .cdx-pie__cols { grid-template-columns: 1fr; } }

/* Titular del bloque: 60px hasta el listado y ancho topado a 10em para que
   caiga SIEMPRE en 2 líneas (a 80px son 800px; la 1.ª línea mide 724 y el
   texto entero 1230, así que parte donde toca a cualquier tamaño). */
.cdx-home__ps > h2 { max-width: 10em; margin-bottom: 60px; }

/* =============================================== HERO: extras del diseño === */

/* Flecha ornamental del hero: EL MISMO componente de los enlaces, a escala 8
   (todas las medidas del original ×8). No es un enlace; el JS le dispara el
   relevo cada 5 s y el resto del tiempo queda en reposo. ×6 en tablet, oculta
   en móvil (donde la última palabra vuelve a fluir con el resto del titular).
   El span del titular alinea al centro, así que no hace falta compensar nada
   para apoyarla en la línea base. */
.cdx-hero__flecha {
	--f-caja-an: 128px;     /* 16×8 */
	--f-caja-al: 112px;     /* 14×8 */
	--f-glifo: 88px;        /* 11×8 */
	--f-reposo-t: 8px;      /* invariante: 8 = 112 − 88 − 16 */
	--f-fuera-t: -120px;    /* -15×8 */
	--f-fuera-i: 120px;
	--f-dentro-b: -120px;
	--f-dentro-i: -80px;    /* -10×8 */
	--f-fin-b: 16px;        /* 2×8 */
	--f-dur: .6s;
	/* La caja deja `--f-fin-b` de aire DEBAJO de la flecha: es el hueco por
	   donde entra la segunda en el relevo. Sin compensar, la flecha se queda
	   flotando esos 16px por encima de la línea base y no se apoya en el mismo
	   suelo que la palabra de al lado.
	   ⚠️ Se compensa con `top`, NO con `margin-bottom`. Un margen negativo aquí
	   NO HACE NADA: al ser un elemento flex sin texto dentro, el navegador le
	   sintetiza la línea base desde su **borde inferior**, y el margen no entra
	   en ese cálculo. Medido a 140px: con `margin-bottom:-16` el desvío era el
	   mismo que sin nada (−16px); con `top:16` es **0**.
	   Aprovecha el `position: relative` que la caja ya necesita para sus glifos
	   absolutos, así que no cambia el alto del titular (449px en los dos casos).
	   Al ir en `--f-fin-b`, la variante ×6 de tablet (12px) se ajusta sola. */
	top: var(--f-fin-b);
}
@media (max-width: 1199px) {
	.cdx-hero__flecha {
		--f-caja-an: 96px; --f-caja-al: 84px; --f-glifo: 66px;
		--f-reposo-t: 6px;  /* 6 = 84 − 66 − 12 */
		--f-fuera-t: -90px; --f-fuera-i: 90px;
		--f-dentro-b: -90px; --f-dentro-i: -60px; --f-fin-b: 12px;
	}
}
/* MÓVIL (2026-08-25): antes se ocultaba (`display:none`). Ahora también sale,
   con su ciclo animado, a la escala que mantiene la PROPORCIÓN del diseño: allí
   el glifo mide 88 sobre un cuerpo de 140, o sea 0,63×. A 60px de cuerpo toca
   ~38 → ×3,5 (0,64×); a 54px, ~34 → ×3 (0,61×).
   Los invariantes del relevo se cumplen en las dos: 3,5 = 49 − 38,5 − 7 y
   3 = 42 − 33 − 6. */
@media (max-width: 767px) {
	.cdx-hero__flecha {
		--f-caja-an: 56px; --f-caja-al: 49px; --f-glifo: 38.5px;
		--f-reposo-t: 3.5px;
		--f-fuera-t: -52.5px; --f-fuera-i: 52.5px;
		--f-dentro-b: -52.5px; --f-dentro-i: -35px; --f-fin-b: 7px;
	}
}
@media (max-width: 374px) {
	.cdx-hero__flecha {
		--f-caja-an: 48px; --f-caja-al: 42px; --f-glifo: 33px;
		--f-reposo-t: 3px;
		--f-fuera-t: -45px; --f-fuera-i: 45px;
		--f-dentro-b: -45px; --f-dentro-i: -30px; --f-fin-b: 6px;
	}
}

/* Columna de información del hero: 380px anclados abajo a la derecha. A partir
   de 1199px deja de flotar y pasa a fluir bajo el titular, alineada a la derecha. */
.cdx-hero__info {
	position: absolute;
	right: 0;
	bottom: 0;
	max-width: 380px;
}
@media (max-width: 1199px) {
	.cdx-hero__info {
		position: relative;
		right: auto; bottom: auto;
		margin-top: 20px;
		margin-inline-start: auto;
	}
}
@media (max-width: 991px) { .cdx-hero__info { max-width: 100%; } }
@media (max-width: 767px) { .cdx-hero__info { margin-inline: auto; } }

.cdx-hero__info-texto {
	margin: 0;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-negro);
}

/* Bloque "clientes destacados": línea + avatares apilados + cifra. */
.cdx-destacados {
	margin-top: 28px;
	padding-top: 20px;
	border-top: 1px solid var(--cdx-gris-borde);
	display: flex;
	align-items: center;
	gap: 20px;
}
@media (max-width: 1199px) { .cdx-destacados { justify-content: center; } }
/* MÓVIL (2026-08-25): antes pasaba a COLUMNA en ≤575 (círculos arriba, textos
   debajo) y se comía mucho alto. Se queda en UNA fila —círculos a la izquierda,
   textos a la derecha— porque cabe de sobra: 3 círculos de 48 solapados 8 son
   128px, más 16 de hueco y los 119 que mide «Casos de éxito» a 18px = 263px,
   y hasta a 320 de ventana hay 296 disponibles. */
@media (max-width: 575px) {
	.cdx-destacados { flex-direction: row; gap: 16px; }
	.cdx-destacados__avatar,
	.cdx-destacados__mas { width: 48px; height: 48px; }
	.cdx-destacados__mas { font-size: 20px; }
}

/* Avatares de 52px superpuestos 8px. El z-index desciende de izquierda a
   derecha para que cada uno quede por delante del siguiente (son elementos
   flex: el z-index les aplica aunque sean position:static). */
.cdx-destacados__avatares { display: flex; align-items: center; position: relative; z-index: 0; }
.cdx-destacados__avatar,
.cdx-destacados__mas {
	width: 52px; height: 52px;
	border-radius: 100%;
	overflow: hidden;
	flex-shrink: 0;
}
.cdx-destacados__avatares > :not(:first-child) { margin-left: -8px; }
.cdx-destacados__avatares > :nth-child(1) { z-index: 3; }
.cdx-destacados__avatares > :nth-child(2) { z-index: 2; }
.cdx-destacados__avatares > :nth-child(3) { z-index: 1; }
.cdx-destacados__avatares > :nth-child(4) { z-index: 0; }
.cdx-destacados__avatar img { width: 100%; height: 100%; object-fit: cover; }
.cdx-destacados__mas {
	display: flex; align-items: center; justify-content: center;
	background: var(--cdx-negro); color: var(--cdx-blanco);
	font-size: 22px; line-height: 1;
}
/* Desde 2026-09-01 el círculo es un ENLACE a Casos de éxito (los avatares son
   un anticipo de esos casos). Lo que es interactivo tiene que parecerlo, así que
   se invierte al pasar por encima —el mismo gesto que `.cdx-boton`— y lleva su
   anillo de foco para el teclado.
   ⚠️ El anillo va con `outline`, no con `border`: el elemento tiene
   `overflow: hidden` y un borde le cambiaría la caja, descuadrando el solape de
   8px con el avatar siguiente. */
a.cdx-destacados__mas { transition: background-color .25s var(--cdx-anim-ease), color .25s var(--cdx-anim-ease); }
/* ⚠ El fondo al pasar por encima NO es blanco. Se probó primero invertir a
   blanco puro, como hace `.cdx-boton`, y aquí no vale: este bloque va sobre el
   fondo general de la página, que también es blanco, así que el círculo se
   disolvía y el gesto no se apreciaba.
   ⚠️ **Y el gris de los fondos de sección (`--cdx-gris-fondo`, #f5f5f5) TAMPOCO
   basta**: contra el blanco de la página da **1,09:1**, que a efectos prácticos
   es el mismo blanco. Se fue con él una vuelta entera. Va con
   `--cdx-gris-borde` (#c5c5c5), que es **1,73:1** contra el blanco —el salto se
   ve— y deja el «+» negro a **11,1:1**, muy por encima del AA.
   💡 El de al lado, `--cdx-gris-suave` (#f0f0f0), habría sido otra vuelta en
   balde: 1,14:1. Para un fondo que solo tiene que DISTINGUIRSE del blanco, el
   número que manda es el contraste, no el nombre del token. */
a.cdx-destacados__mas:hover,
a.cdx-destacados__mas:focus-visible { background: var(--cdx-gris-borde); color: var(--cdx-negro); }
a.cdx-destacados__mas:focus-visible { outline: 2px solid var(--cdx-negro); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { a.cdx-destacados__mas { transition: none; } }
.cdx-destacados__cifra {
	display: block;
	font-size: 24px;
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.41667;
	letter-spacing: -.01em;
	color: var(--cdx-negro-puro);
}
.cdx-destacados__texto {
	margin: 0;
	font-size: 18px;
	line-height: 1.44444;
	color: var(--cdx-negro);
}
/* Los datos ya no van centrados: al estar en fila, se alinean a la izquierda
   pegados a los círculos. */
@media (max-width: 575px) { .cdx-destacados__datos { text-align: left; } }

/* ===================================== PÁRRAFOS DESTACADOS DEL DISEÑO ===== */

/* Bloque "sobre nosotros": UNA sección con dos filas sangradas (31% y 59% del
   ancho útil) separadas por 60px, tal cual el diseño. */
.cdx-home__sobre { display: flex; flex-direction: column; }
.cdx-sobre__titular { margin-left: 31%; }
.cdx-sobre__info { margin-left: 59%; margin-top: 60px; }
.cdx-sobre__texto { margin: 0; font-size: var(--cdx-fs-body); line-height: var(--cdx-lh-body); color: var(--cdx-negro); }
.cdx-sobre__enlace { margin-top: 28px; }

@media (max-width: 1199px) {
	.cdx-sobre__titular { margin-left: 15%; }
	.cdx-sobre__info { margin-left: 40%; }
}
@media (max-width: 991px) {
	.cdx-sobre__titular, .cdx-sobre__info { margin-left: 0; }
	.cdx-sobre__info { margin-top: 40px; max-width: 640px; }
	.cdx-sobre__enlace { margin-top: 20px; }
}

/* "Muchas agencias te venden…" → titular grande que pasa de gris a negro según
   avanza el scroll. Medido en el diseño: 44px/122.727%/600, ls -1.5px. El JS lo
   parte en LÍNEAS y tiñe cada una por separado (por eso se ven unas negras y la
   última todavía gris); cada línea es un degradado recortado sobre el texto. */
.cdx-texto-invertido {
	font-size: 44px;
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.22727;
	letter-spacing: -1.5px;
	margin: 0;
}
@media (max-width: 1399px) { .cdx-texto-invertido { font-size: 40px; } }
@media (max-width: 1199px) { .cdx-texto-invertido { font-size: 35px; } }
@media (max-width: 991px)  { .cdx-texto-invertido { font-size: 30px; } }
/* MÓVIL (2026-08-25): sube el cuerpo y se abre el interlineado. A 25px, con el
   párrafo de debajo a 20/1.6, los dos textos se parecían demasiado y el titular
   no se leía como titular. */
@media (max-width: 767px)  { .cdx-texto-invertido { font-size: 31px; line-height: 1.3; } }
@media (max-width: 575px)  { .cdx-texto-invertido { font-size: 28px; line-height: 1.3; } }

/* Cada línea que crea el JS. Mientras no se haya partido, el texto se ve negro. */
.cdx-texto-invertido__linea {
	display: block;
	color: transparent;
	background-image: linear-gradient(to right, var(--cdx-negro-puro) 50%, #ddd 50%);
	background-size: 200% 100%;
	background-position-x: 100%;
	-webkit-background-clip: text;
	background-clip: text;
	/* Corta: el valor lo marca el scroll, esto solo lima el escalonado. */
	transition: background-position-x .12s linear;
}
/* Sin JS o con menos movimiento pedido: todo negro desde el principio. */
@media (prefers-reduced-motion: reduce) {
	.cdx-texto-invertido__linea { background-position-x: 0; transition: none; }
}
/* Reserva de seguridad: si el navegador no soporta recorte de texto, se ve negro. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
	.cdx-texto-invertido__linea { color: var(--cdx-negro-puro); background: none; }
}

/* Menú legal del pie (lista horizontal simple). */
.cdx-pie .cdx-menu { display: flex; flex-wrap: wrap; align-items: center; list-style: none; margin: 0; padding: 0; }

/* ================================================== PÁGINA DE SERVICIOS ====
   Replica de la página de servicios del diseño de referencia. Tres bloques:
   hero de titular suelto, marco de foto a sangre con rótulo vertical y la
   parrilla de servicios a 4 columnas.

   Desviaciones pedidas: sin bloque de tarifas y SIN titular de sección en la
   parrilla, que es lo que libera la retícula completa. En el original el
   titular ocupa la mitad izquierda y las tarjetas van a 2 columnas en la mitad
   derecha; aquí van a 4 a ancho completo con el MISMO formato de tarjeta.     */

/* ---------- Hero de página (solo titular) ---------- */
/* Mismo escalonado de relleno superior que el hero de la portada. El original
   pone 200px, pero se midió contra SU cabecera: la nuestra tiene otra altura,
   así que se mantiene la convención propia para que todas las páginas casen. */
.cdx-hero-pagina { padding-top: 110px; padding-bottom: 0; }
@media (max-width: 1199px) { .cdx-hero-pagina { padding-top: 60px; } }
@media (max-width: 991px)  { .cdx-hero-pagina { padding-top: 40px; } }

/* Cuerpo, interlineado e interletraje los pone ya la regla global de `h1` en
   base.css (fs-h1 / lh-titulo / ls-h1): aquí solo el margen. */
.cdx-hero-pagina__titulo { margin: 0; }

/* Texto introductorio opcional bajo el h1 de una página de listado (hoy solo
   Casos de éxito, campo `texto_introductorio`). Mismo tratamiento que la
   entradilla de la ficha de servicio (`.cdx-hero-servicio__entradilla`):
   cuerpo normal, ancho a media retícula, en gris de texto secundario. */
.cdx-hero-pagina__texto {
	margin: var(--cdx-espacio-bloque) 0 0;
	max-width: 46ch;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-texto);
}

/* ---------- Marco de foto de ancho de CONTENEDOR ---------- */
/* La imagen de ruptura de la portada va a sangre; esta NO: en el original mide
   el ancho del contenedor — medido 1570 × 685 a 1600, o sea 2,29:1 — así que
   aquí se le da esa proporción en vez del `clamp` de alto de la portada, que
   dejaba una tira mucho más plana.
   El parallax es el de la portada sin tocar nada: el marco sigue llevando
   `[data-cdx-parallax]` y la imagen su 130% de alto, que es el margen que el JS
   recorre. */
.cdx-ruptura--con-rotulo { position: relative; }
.cdx-ruptura__caja { position: relative; }
.cdx-ruptura--con-rotulo .cdx-ruptura__marco {
	height: auto;
	aspect-ratio: 1570 / 685;
}
/* En móvil una tira de 2,29:1 se queda en nada de alto, así que se abre la
   proporción y se respeta un mínimo. */
@media (max-width: 767px) {
	.cdx-ruptura--con-rotulo .cdx-ruptura__marco { aspect-ratio: 16 / 10; min-height: 200px; }
}

/* ---------- Franja de foto SIN RECORTE LATERAL ----------
   Para una foto de grupo, donde recortar por los lados se lleva a la gente de
   los extremos. La usa la cabecera de la página de EQUIPO.

   ⚠️ **El recorte no lo hacía la proporción del marco, lo hacía el parallax.**
   La franja normal escala la foto al 130 % de alto para tener recorrido que
   mover, y eso estrecha la caja visible: con el marco a 2,292 la caja efectiva
   queda en 2,292/1,3 = 1,763, y con una foto de 3,11 solo se ve el **56,7 %**
   del ancho. O sea que se perdía casi la mitad, no el 26 % que daría el marco
   por sí solo.

   Por eso aquí la foto va a `height: 100%` —sin recorrido, sin parallax— y el
   marco toma **la proporción real de la foto**, que la plantilla calcula y pasa
   en `--cdx-marco-ratio`. Así se ve entera de lado a lado.

   Se pierde el parallax en esta franja concreta, a cambio de que salga todo el
   equipo. Es un intercambio deliberado. */
.cdx-ruptura--completa .cdx-ruptura__marco {
	height: auto;
	aspect-ratio: var(--cdx-marco-ratio, 1570 / 685);
}
.cdx-ruptura--completa .cdx-ruptura__img {
	height: 100%;
	transform: none;
	will-change: auto;
	object-position: var(--cdx-marco-encuadre, 50% 50%);
}
@media (max-width: 767px) {
	/* ⚠⚠ **2,5 y NO 16/10, que es el mismo error que ya se corrigió en la
	   portada.** Aquí había `16 / 10` (=1,6) «para que la panorámica no quedara
	   en una tira ilegible», y eso RECORTA: la foto de equipo es de 1950×627
	   (**3,11:1**), así que a 1,6 solo se ve el **51 %** del ancho. Como el grupo
	   ocupa el 73 % central, desaparecían las personas de los dos extremos —que
	   es exactamente lo que reportó el usuario.
	   La portada se topó con esto el 2026-08-25 y lo resolvió dejando su **2,5**
	   también en móvil (ver `.cdx-hero__media`): a 2,5 se ve el **80 %**, con un
	   3,5 % de margen a cada lado del grupo, así que no se corta a nadie. Se
	   copia ese valor para que las dos fotos de equipo del sitio queden con el
	   MISMO encuadre.
	   El precio es el mismo que asumió la portada: una franja más baja, ~140px a
	   375 de ventana. Si algún día llega una foto de equipo más alta (§9.2), las
	   dos se pueden volver a cerrar a la vez.
	   ⚠ Y no se toca el `aspect-ratio` de escritorio, que sigue siendo el real
	   del adjunto (`--cdx-marco-ratio`, 0 % recortado). */
	.cdx-ruptura--completa .cdx-ruptura__marco { aspect-ratio: 2.5; min-height: 0; }
	.cdx-ruptura--completa .cdx-ruptura__img { object-fit: cover; }
}

/* ---------- Enlace vertical «Ver Servicios» ---------- */
/* Replica del enlace del original: rótulo girado en la esquina superior derecha
   con una flecha que sube y baja, y solo visible desde 1600 px de ventana.

   Dos diferencias, las dos obligadas al medir el original:

   1. Allí cuelga en el canal EXTERIOR (`right: -30px`) y a 1600 justos se sale
      de la ventana: medido, su caja va de 1592 a 1624 con la ventana en 1600, o
      sea 24 px recortados. Por eso lo esconden por debajo de 1600. Aquí no se
      recorta: en vez de colgarlo fuera, el MARCO le cede su columna a la
      derecha, así que el rótulo cae junto a la foto sin pisarla y sin sacar
      barra horizontal.
   2. Su flecha es un PNG; aquí va dibujada en SVG, sin fichero que cargar. */
.cdx-ruptura__ir {
	position: absolute;
	right: var(--cdx-margen-lateral);   /* era 12 fijos: con el margen de portátil (§130) quedaba fuera del contenido */
	top: 0;
	z-index: 2;
	display: none;
	align-items: center;
	gap: 12px;
	writing-mode: vertical-lr;
	text-orientation: mixed;
	font-size: var(--cdx-fs-body);
	line-height: 1;
	color: var(--cdx-negro);
	text-decoration: none;
	transition: opacity var(--cdx-transicion);
}
.cdx-ruptura__ir:hover { opacity: .6; }
@media (min-width: 1600px) { .cdx-ruptura__ir { display: flex; } }

/* La flecha sube y baja, como el original (1,5 s, ida y vuelta). */
.cdx-ruptura__ir-flecha { flex: none; animation: cdx-sube-baja 1.5s ease-in-out infinite alternate; }
@keyframes cdx-sube-baja {
	from { transform: translateY(-4px); }
	to   { transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
	.cdx-ruptura__ir-flecha { animation: none; }
}

/* Desde 1600 el marco deja libre la columna del rótulo (32 del rótulo + 12 de
   aire), que es lo que evita la superposición sobre la foto. Por debajo el
   rótulo no se pinta, así que la foto ocupa el contenedor completo.

   Va con `:has()` y no con la clase del bloque a propósito: el marco de la ficha
   de servicio usa el mismo bloque pero NO lleva rótulo, y con la clase suelta se
   habría quedado con 44 px de hueco a la derecha sin nada que lo justifique. */
@media (min-width: 1600px) {
	.cdx-ruptura__caja:has(.cdx-ruptura__ir) .cdx-ruptura__marco { margin-right: 44px; }
}

/* ---------- Parrilla ancha (el hueco de 114 del original) ---------- */
/* Su parrilla declara los huecos por separado y con escalones distintos en cada
   eje: el vertical sube antes que el horizontal. Se replican tal cual.        */
/* ⚠️ **El hueco de fila en móvil sube de 45 a 65.** Apiladas a una columna, y
   sobre todo desde que la tarjeta solo lleva filete IZQUIERDO (§53.4), 45px
   dejaban las piezas casi pegadas: la tarjeta no tiene caja ni relleno vertical,
   así que ese hueco es toda la separación que hay entre el «Saber más» de una y
   el icono de la siguiente. **65 es el escalón que el propio tema usa para el
   ritmo de sección** en esa anchura (`--cdx-sec-top` a ≤991), así que la rampa
   queda 114 → 80 → 65 en vez del salto de 80 → 45.
   Alcanza a los TRES listados que piden esta variante: la página de Servicios,
   «Otros servicios» de la ficha y «Servicios aplicados» de las fichas de
   proyecto y de caso. El bloque de la portada usa la variante de caja blanca,
   que ya lleva su propio relleno, y no se toca. */
.cdx-rejilla-servicios--ancha { column-gap: 12px; row-gap: 65px; }
@media (min-width: 576px)  { .cdx-rejilla-servicios--ancha { row-gap: 80px; } }
@media (min-width: 768px)  { .cdx-rejilla-servicios--ancha { row-gap: 114px; } }
@media (min-width: 1400px) { .cdx-rejilla-servicios--ancha { column-gap: 114px; } }
/* Portátil (1400-1599, §130): con el margen lateral de 48 las cuatro tarjetas
   estrechan y «Posicionamiento» se salía 11 px de la suya. El hueco baja a 80
   SOLO en esa franja; desde 1600, los 114 medidos. */
@media (min-width: 1400px) and (max-width: 1599px) { .cdx-rejilla-servicios--ancha { column-gap: 80px; } }

/* Variante de 3 columnas (servicios relacionados de la ficha). */
.cdx-rejilla-servicios--tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 991px) { .cdx-rejilla-servicios--tres { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) { .cdx-rejilla-servicios--tres { grid-template-columns: 1fr; } }

/* ---------- Tarjeta sin caja, con filete ---------- */
/* Su `style-2`: no hay caja de color, la tarjeta se apoya en un filete vertical
   y una sangría.
   ⚠️ **DESVIACIÓN a propósito del original**: por debajo de 768 la referencia
   pone filete a los DOS lados, y aquí va **solo el de la izquierda**. Lo pidió el
   usuario el 2026-09-03 y tiene razón: apilada a una columna, la tarjeta con
   filete a los dos lados se lee como una caja a medio cerrar —no tiene ni arriba
   ni abajo— en vez de como una columna apoyada en su margen. El izquierdo solo
   es además el mismo recurso que usa `.cdx-beneficio` a todas las anchuras.
   Alcanza a los tres sitios que piden esta variante: la página de Servicios,
   «Otros servicios» de la ficha y «Servicios aplicados» de las fichas de
   proyecto y de caso. */
.cdx-tarjeta-servicio--filete {
	background: none;
	padding: 0 0 0 30px;
	border-left: 1px solid var(--cdx-gris-borde);
}
@media (min-width: 768px) {
	.cdx-tarjeta-servicio--filete { padding-left: 40px; }
}

/* ---------- Titular DENTRO de la parrilla ---------- */
/* Estructura del diseño de referencia: el titular de sección no va encima de la
   parrilla sino DENTRO, como primera celda ocupando dos columnas. Así la fila 1
   queda «titular + 2 tarjetas» y desde la fila 2 entran las 4 columnas.

   Al ser una celda de la propia rejilla, hereda el hueco de 114 y las tarjetas
   se recolocan solas en cada escalón: no hay que posicionar nada a mano. */
.cdx-rejilla-servicios__titular { grid-column: span 2; }
/* A 2 columnas el titular ocupa la fila entera, y a 1 columna vuelve a una
   celda normal (si no, `span 2` desbordaría la rejilla). */
@media (max-width: 767px) { .cdx-rejilla-servicios__titular { grid-column: span 1; } }

/* El titular se alinea con la primera línea de las tarjetas de su fila, que
   arrancan por el icono. */
.cdx-rejilla-servicios__titular .cdx-titulo-seccion { margin: 0; max-width: 22ch; }

/* La parrilla es el último bloque antes del pie, así que le toca el relleno
   inferior del ritmo (excepción 3 de §5.2). */
.cdx-servicios-pagina { padding-bottom: var(--cdx-sec-bottom); }

/* =================================================== FICHA DE SERVICIO ====
   Maqueta de `single-servicio.php`. El esqueleto (hero suelto → marco de foto →
   contenido) viene de la plantilla de ficha del diseño de referencia; los
   quince bloques de contenido comparten UN SOLO patrón de retícula, el mismo
   que usa el diseño en casi todas sus secciones: titular en la mitad izquierda
   y contenido en la derecha.                                                  */

/* ---------- Patrón partido: título | contenido ---------- */
/* Medido a 1600: dos mitades de 797 con canal de 12 px cada una, así que entre
   los bordes de texto quedan 24. Por debajo de 992 el diseño apila.          */
.cdx-seccion-partida {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 24px;
	align-items: start;
}
@media (max-width: 991px) {
	.cdx-seccion-partida {
		grid-template-columns: 1fr;
		row-gap: var(--cdx-espacio-bloque);
	}
}
/* El titular no llena su mitad: en el original ocupa 696 de los 785 útiles. */
.cdx-seccion-partida__titulo { max-width: 89%; }
/* ⚠️ El carrusel de testimonios NO puede ensanchar su columna (§84.5). Con las
   reseñas recortadas a 5 líneas (`line-clamp`), el ancho mínimo del texto pasa
   a ser el de la reseña entera en una línea, y el `1fr` de la rejilla lo
   obedecía: la columna se iba de 698 a 1576 px a 1440, fuera de la sección.
   `min-width: 0` la devuelve a su mitad exacta. Solo en esta columna. */
.cdx-seccion-partida__cuerpo:has(> .cdx-testimonios) { min-width: 0; }
@media (max-width: 991px) { .cdx-seccion-partida__titulo { max-width: 100%; } }

/* DOS REPARTOS MÁS, que NO son mitad y mitad. En `/design-studio/` cada uno de
   estos dos bloques tiene el suyo, medido a 1600 sobre los 1570 útiles del
   contenedor:

     testimonios (--filete): 626 | canal 152 | 792, y FILETE VERTICAL en el
       borde derecho de la columna del titular (x=637,5). El titular lleva 92
       de sangría derecha (los 80 de su margen más los 12 de su relleno), que
       es lo que deja el titular en los 533 medidos.
     FAQs (--faqs): 502 | canal 167 | 901.

   Se escriben en `fr` con los números medidos para que se lea de dónde salen:
   con el canal ya descontado, los `fr` reparten exactamente esas anchuras. */
.cdx-seccion-partida--filete {
	grid-template-columns: 626fr 792fr;
	column-gap: 152px;
}
.cdx-seccion-partida--filete .cdx-seccion-partida__titulo {
	max-width: 100%;
	padding-right: 92px;
	border-right: 1px solid var(--cdx-gris-borde);
}
.cdx-seccion-partida--faqs {
	grid-template-columns: 502fr 901fr;
	column-gap: 167px;
}
.cdx-seccion-partida--faqs .cdx-seccion-partida__titulo { max-width: 100%; }
@media (max-width: 1199px) {
	.cdx-seccion-partida--filete { column-gap: 80px; }
	.cdx-seccion-partida--filete .cdx-seccion-partida__titulo { padding-right: 40px; }
	.cdx-seccion-partida--faqs { column-gap: 80px; }
}
@media (max-width: 991px) {
	/* Apilados, el filete vertical no tiene sentido: se quita. */
	.cdx-seccion-partida--filete,
	.cdx-seccion-partida--faqs { grid-template-columns: 1fr; column-gap: 0; }
	.cdx-seccion-partida--filete .cdx-seccion-partida__titulo {
		padding-right: 0;
		border-right: 0;
	}
}

/* Cuerpo e interlineado los pone la regla global de `h2`. */
.cdx-titulo-seccion { margin: 0; }

/* En la ficha el texto corrido va a la mitad de la retícula, así que el tope de
   75ch de `.cdx-prosa` no llega a actuar: se suelta para que use su columna. */
.cdx-seccion-partida__cuerpo .cdx-prosa { max-width: none; }

/* ---------- Hero de la ficha ---------- */
.cdx-hero-servicio__icono {
	color: var(--cdx-negro);
	line-height: 0;
	margin-bottom: 32px;
}
.cdx-hero-servicio__icono svg { width: 52px; height: 52px; display: block; }
@media (max-width: 991px) {
	.cdx-hero-servicio__icono { margin-bottom: 20px; }
	.cdx-hero-servicio__icono svg { width: 40px; height: 40px; }
}
/* Entradilla: cuerpo de texto normal, a media retícula y separada del titular
   con el mismo hueco «titular → contenido» del sistema. */
.cdx-hero-servicio__entradilla {
	margin: var(--cdx-espacio-bloque) 0 0;
	max-width: 46ch;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-texto);
}

/* ---------- Titulares de sección de la ficha, a dos líneas ---------- */
/* Los titulares de la ficha son frases largas («Beneficios de trabajar con
   Coodex», «Casos de éxito de Diseño páginas web», «Últimas entradas sobre
   Diseño páginas web»…) y a 80 px en 1561 de ancho salían en una sola línea
   que barría la pantalla de lado a lado. Acotando la CAJA DEL TITULAR a la
   mitad del contenedor —780 px a 1600— parten en dos, que es como se leen los
   titulares del diseño de referencia.

   Se acota el TITULAR y no la cabecera entera porque `.cdx-seccion-cabecera`
   es una fila de `space-between` que en otras páginas lleva un enlace a la
   derecha; encogiéndola entera se lo llevaría por delante.

   ⚠️ SOLO DE 1200 PARA ARRIBA. Por debajo el contenedor ya es estrecho y la
   mitad daría tres y cuatro líneas; en móvil el titular ocupa el 100 %, que es
   lo que se pidió. Y va acotado a `body.single-servicio` para no tocar la
   portada ni la página de Servicios, que comparten el patrón.

   ⚠️ NO se le pone a los bloques cuyo titular YA va a media caja por su propia
   retícula: el de blog vive en un `1fr 1fr` (`.cdx-blog-cabecera`) y el de FAQs
   y el de testimonios, en el patrón partido. Ponerles el 50 % encima los
   dejaba en un cuarto de ancho — el del blog se quedó en 384 px y seis líneas.

   ⚠️ Y NO es el mismo 50 % en toda la banda. El titular va a 80 px de 1200
   para arriba, así que la frase más larga necesita ~740 px para partir en DOS
   y no en tres. A 1600 el 50 % son 781 y entra; a 1280 serían 621 y salían
   TRES líneas (medido). Por eso la mitad de verdad empieza en 1400 y entre
   1200 y 1399 el tope se afloja al 64 %. */
@media (min-width: 1200px) {
	body.single-servicio .cdx-seccion-cabecera .cdx-titulo-seccion { max-width: 64%; }
}
@media (min-width: 1400px) {
	body.single-servicio .cdx-seccion-cabecera .cdx-titulo-seccion { max-width: 50%; }
}

/* ---------- Pestañas «qué hacemos» ---------- */
/* Lista de pestañas a la izquierda del panel, con filete de separación. Sin JS
   funciona como lista legible: los paneles se ven todos (ver .cdx-tabs sin
   [data-cdx-listo]). El JS solo añade el comportamiento y los roles ARIA.    */

/* Banda gris del sistema. El bloque queda encerrado en su propio fondo en vez
   de flotar entre dos bloques blancos, y de paso separa las pestañas de la
   descripción que va justo encima. El relleno inferior lo pone
   `.tiene-fondo` (§5.2), que la sección lleva en el HTML. */
.cdx-servicio-tabs { background: var(--cdx-gris-fondo); }

/* CARRIL VERTICAL a la izquierda y panel a la derecha.
   ---------------------------------------------------------------------------
   Antes era una fila horizontal de rótulos subrayados. Se cambió por dos
   razones medidas, no por gusto:

   1. **La fila no cabía.** Seis rótulos a 18 px suman 1130 y a 1024 solo hay
      1000 útiles: partía en dos líneas y así quedó documentado en §20.1 como
      «inevitable». En vertical no hay nada que quepa o deje de caber.
   2. **El panel se quedaba sin medida de lectura.** De los SIETE servicios que
      muestran el bloque, solo «Diseño páginas web» tiene fotos en sus
      pestañas; en los otros seis el panel era un párrafo de hasta 2380
      caracteres a 1561 px de ancho. En columna, el texto se queda en 1106 y la
      prosa lo acota a sus 75ch.

   El carril además repite el vocabulario que ya usa la ficha —filas separadas
   por filete y marca vertical a la izquierda, como los beneficios y la tarjeta
   de servicio— en vez de traer un subrayado que no está en ninguna otra parte.

   ⚠️ La retícula SOLO se aplica con `data-cdx-listo`. Sin JS los paneles están
   todos visibles y, si la sección fuera de dos columnas, se repartirían por
   ellas en zigzag. Sin JS se queda en flujo normal, que es la degradación
   limpia de siempre. */
.cdx-tabs[data-cdx-listo] {
	display: grid;
	grid-template-columns: 24% 1fr;
	column-gap: 80px;
	align-items: start;
}
@media (max-width: 1199px) {
	.cdx-tabs[data-cdx-listo] { grid-template-columns: 28% 1fr; column-gap: 48px; }
}
@media (max-width: 991px) {
	.cdx-tabs[data-cdx-listo] { grid-template-columns: 1fr; row-gap: 40px; }
}

/* Sin JS el carril NO se pinta: el rótulo lo da el titular de cada panel, y si
   se vieran los dos habría el nombre repetido. El JS lo muestra al marcar
   `data-cdx-listo`. */
.cdx-tabs__lista { display: none; }
.cdx-tabs[data-cdx-listo] .cdx-tabs__lista {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Cada fila es el `quanto-awards-box` de `/about-us/`, leído de su hoja y
   medido a 1600: filete arriba y abajo (el de arriba se le quita a todas menos
   a la primera, así que las líneas quedan colapsadas), relleno de 28/0, rótulo
   a 24/33,84 con peso 600 e interletraje −0,24, y **texto en NEGRO**.

   El efecto también es el suyo, literal: un telón negro que sube desde ABAJO
   (`scaleY` con el origen cambiado de `top` a `bottom`), el texto pasando a
   blanco y la fila metiéndose 15 px hacia dentro. Todo en 0,4 s ease-in-out.

   Aquí el telón se queda fijo en la pestaña ACTIVA, que es lo que marca cuál
   estás viendo; al pasar por encima, las demás lo enseñan en previsualización.

   ⚠️ El `z-index: 0` del botón NO sobra: es lo que crea el contexto de apilado
   que deja al `::before` en −1 detrás del texto sin irse detrás del fondo gris
   de la sección. Es exactamente lo que hace el suyo.

   (Lo único que NO se replica es el punto blanco de la captura: es el cursor
   personalizado que Quanto pone en TODO el sitio, no parte de este bloque.) */
.cdx-tabs__boton {
	appearance: none;
	position: relative;
	z-index: 0;
	display: block;
	width: 100%;
	background: none;
	border: 0;
	border-top: 1px solid var(--cdx-gris-borde);
	border-bottom: 1px solid var(--cdx-gris-borde);
	padding: 28px 0;
	font: inherit;
	font-size: var(--cdx-fs-h4);
	line-height: 1.41;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: -.24px;
	text-align: left;
	color: var(--cdx-negro-puro);
	cursor: pointer;
	transition: padding .4s ease-in-out, color .4s ease-in-out;
}
/* Filetes colapsados: solo la primera fila lleva el de arriba. */
.cdx-tabs__lista > li:not(:first-child) .cdx-tabs__boton { border-top: 0; }

.cdx-tabs__boton::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: var(--cdx-negro);
	transform: scaleY(0);
	transform-origin: center top;
	transition: transform .4s ease-in-out;
}
.cdx-tabs__boton:hover::before,
.cdx-tabs__boton:focus-visible::before,
.cdx-tabs__boton[aria-selected="true"]::before {
	transform: scaleY(1);
	transform-origin: center bottom;
}
.cdx-tabs__boton:hover,
.cdx-tabs__boton:focus-visible,
.cdx-tabs__boton[aria-selected="true"] {
	color: var(--cdx-blanco);
	padding-inline: 15px;
}
@media (max-width: 1199px) { .cdx-tabs__boton { padding-block: 22px; } }
/* En móvil el carril va ENCIMA del panel, así que sus filas son lo primero que
   hay que pasar para llegar al contenido: seis a 66 px sumaban 396 px de
   pantalla antes de ver nada. Se aprietan a 46 (17/11 en vez de 20/18), que
   deja el carril en 276: un 30 % menos. */
@media (max-width: 767px) {
	.cdx-tabs__boton { font-size: 17px; line-height: 1.4; padding-block: 11px; }
}
@media (prefers-reduced-motion: reduce) {
	.cdx-tabs__boton, .cdx-tabs__boton::before { transition: none; }
}

/* Panel: foto y texto, con un canal ANCHO. Los 24 px de antes eran los del
   patrón partido, donde a la izquierda solo hay un titular; aquí hay dos masas
   de contenido y se tocaban.

   El reparto NO es mitad y mitad: la foto se queda en 5/12. Es lo que permite
   ENCOGERLA SIN RECORTARLA — ver el bloque de abajo. */
/* TEXTO A LA IZQUIERDA Y FOTO A LA DERECHA, y las dos ARRIBA, no centradas.
   El reparto es 7fr 5fr: la columna ancha es la del texto. A 1600, con el
   panel en 1106: texto 632, foto 452.

   La colocación va por `grid-column`/`grid-row` explícitos y no por `order`
   porque el orden del HTML es foto → texto (que es el que interesa cuando se
   apilan en móvil) y aquí hace falta el contrario sin tocar el marcado. */
.cdx-tab { display: grid; grid-template-columns: 7fr 5fr; column-gap: 60px; align-items: start; }
.cdx-tab__contenido { grid-column: 1; grid-row: 1; }
.cdx-tab__marco { grid-column: 2; grid-row: 1; }
/* ⚠️ El panel deja de partirse EN 1199, no en 991. Con el carril quitándole
   una cuarta parte al bloque, a 1024 el panel se queda en 661 y el reparto
   dejaba la foto en 259 y el texto en 362: 27 caracteres por línea, que no
   es una medida de lectura. Apilados, la foto va a 661 y el texto también. */
@media (max-width: 1199px) {
	.cdx-tab { grid-template-columns: 1fr; row-gap: 32px; }
	.cdx-tab__contenido, .cdx-tab__marco { grid-column: 1; grid-row: auto; }
}

/* Sin foto no hay nada que repartir: el texto ocupa el panel entero y lo acota
   la medida de lectura de `.cdx-prosa` (75ch). Es el caso de SEIS de los siete
   servicios que muestran el bloque. */
.cdx-tab:not(:has(.cdx-tab__marco)) { grid-template-columns: 1fr; }

/* ⚠️ LA FOTO NO SE RECORTA. Se probó con marco + `object-fit: cover` para
   igualar el alto de los seis paneles, y se comía parte del encuadre. Lo que
   hacía falta era ENCOGERLA proporcionalmente: va a su proporción natural
   (originales de 2210×1754, 1,26:1) dentro de una columna más estrecha.
   A 1600: columna de 621 → foto de 621×493, contra los 623 de alto que
   imponía antes ocupando media retícula. */
.cdx-tab__marco { display: block; }
.cdx-tab__imagen {
	display: block;
	width: 100%;
	height: auto;
}

/* Texto y foto ARRIBA los dos. Estuvo centrado en vertical («los paneles
   cortos se quedaban pegados arriba dejando un vacío debajo»), pero centrar
   descuadra el arranque de las dos columnas: ahora empiezan a la misma
   altura y el vacío, si lo hay, queda todo abajo. */
.cdx-tab__contenido { align-self: start; }

/* Titular de dentro del panel: iba al `h4` del sistema (24) por la regla
   general de `.cdx-prosa`, y se quedaba corto para lo que es —el titular del
   panel—. Sube un escalón y medio sobre el `h3`, siguiendo la escala en vez de
   inventar un tamaño suelto. */
.cdx-tab__contenido h3,
.cdx-tab__contenido h4 {
	font-size: calc(var(--cdx-fs-h3) * 1.15);
	line-height: 1.25;
	letter-spacing: var(--cdx-ls-tarjeta);
	margin: 2rem 0 20px;
}
/* El primero abre el panel: sin hueco por arriba.
   ⚠️ NO BASTA CON EL HIJO DIRECTO. El contenido migrado conserva los
   envoltorios de Elementor (`div.elementor-element > div.elementor-widget-
   container > h4`), así que el hijo directo del panel es un `div` sin margen y
   quien lo tiene es el titular de dentro: sus 2rem SE ESCAPAN POR COLAPSO y
   empujaban la columna entera 32 px por debajo de la foto. Medido: caja del
   texto en y=1711, igual que la foto, pero la primera línea en y=1743.
   Se anula también en el primer descendiente de la primera pieza. */
.cdx-tab__contenido > :first-child,
.cdx-tab__contenido > :first-child :first-child { margin-top: 0; }

/* Con JS, los paneles que no tocan se esconden. */
.cdx-tabs[data-cdx-listo] .cdx-tab[hidden] { display: none; }
/* El titular de cada pestaña solo hace falta cuando NO hay JS: con pestañas
   activas el rótulo ya lo da el botón. */
.cdx-tabs[data-cdx-listo] .cdx-tab__titulo { display: none; }

/* ---------- Beneficios (parrilla de iconos) ---------- */
/* Las columnas van por CLASE y no por variable: `repeat()` exige un entero
   literal. El PHP elige 3 o 4 según cuántos beneficios haya, para que la
   última fila no quede coja (los seis por defecto en cuatro columnas dejaban
   una segunda fila de dos). */
.cdx-rejilla--beneficios {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 56px 40px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.cdx-rejilla--beneficios-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cdx-rejilla--beneficios-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Los escalones se declaran sobre la clase base: al ir DESPUÉS en el fichero y
   con la misma especificidad, ganan a los modificadores. El de 2 se repite
   dentro del primer escalón porque si no bajaría a 3, que son más de los que
   hay. */
@media (max-width: 1199px) {
	.cdx-rejilla--beneficios { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.cdx-rejilla--beneficios-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) { .cdx-rejilla--beneficios { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Cada beneficio se apoya en un FILETE VERTICAL con sangría, el mismo recurso
   que la tarjeta de servicio de la página de Servicios
   (`.cdx-tarjeta-servicio--filete`): así la parrilla se lee como columnas y no
   como piezas sueltas flotando. */
.cdx-beneficio {
	padding-left: 40px;
	border-left: 1px solid var(--cdx-gris-borde);
}
@media (max-width: 767px) { .cdx-beneficio { padding-left: 30px; } }

/* El hueco va en la CAJA, no en la pieza: dentro puede ir un <img> subido o el
   SVG geométrico de reserva, y así los dos quedan alineados igual.
   Eran 60 px, heredados de la tarjeta de servicio, y con un icono ilustrado de
   52 dejaban el texto descolgado: se bajan a 28. */
.cdx-beneficio__icono-caja { line-height: 0; color: var(--cdx-negro); margin-bottom: 28px; }

/* La caja baja de 52 a 40: más discreta, que es lo que se pidió, y suficiente
   para un dibujo de línea.

   ⚠️ Bajar el número NO bastaba para que los seis se vieran iguales. Los PNG
   del origen traían MÁRGENES TRANSPARENTES distintos, y `object-fit: contain`
   encaja el LIENZO, no el dibujo: el de «Rápidos» salía un 58 % más grande que
   el de «Experiencia» (lado equivalente 28,5 contra 18,1). Se han regenerado
   los seis recortados a su caja de tinta y centrados en un lienzo cuadrado de
   160 (adjuntos 2183-2188), con una escala intermedia entre «misma caja» y
   «misma tinta». Medido sobre los ficheros nuevos: la razón entre el mayor y
   el menor baja de 1,58 a 1,28.

   El lienzo cuadrado es lo que permite que la caja siga siendo cuadrada y los
   títulos de los seis arranquen a la misma altura, aunque el dibujo de dentro
   sea apaisado (Experiencia) o vertical (Eficiencia). */
.cdx-beneficio__icono-caja img,
.cdx-beneficio__icono-caja svg {
	display: block;
	width: 40px; height: 40px;
	object-fit: contain; object-position: left center;
}
@media (max-width: 991px) { .cdx-beneficio__icono-caja { margin-bottom: 20px; } }
.cdx-beneficio__titulo { margin: 0 0 12px; }
.cdx-beneficio__texto { margin: 0; font-size: var(--cdx-fs-body); line-height: var(--cdx-lh-body); }

/* ⚠️ EN MÓVIL SE QUEDA EN DOS COLUMNAS. Había un escalón a una sola columna por
   debajo de 480 y dejaba la lista larguísima. Para que quepan dos, todo lo de
   dentro encoge: a 375 la columna útil pasa a ser de **150 px**
   ((351 − 20 de canal) / 2 − 16 de sangría).

   ⚠️ ESTE BLOQUE VA AL FINAL DE LA SECCIÓN A PROPÓSITO. Estuvo escrito arriba,
   junto a la retícula, y no entraba: los escalones de `.cdx-beneficio`,
   `__icono-caja`, `__titulo` y `__texto` se declaran MÁS ABAJO con la misma
   especificidad, así que ganaban ellos. Es la lección 8 del §10 otra vez —solo
   entraron los dos selectores que no tenían competencia posterior—. */
@media (max-width: 479px) {
	.cdx-rejilla--beneficios { gap: 32px 20px; }
	.cdx-beneficio { padding-left: 16px; }
	.cdx-beneficio__icono-caja { margin-bottom: 14px; }
	.cdx-beneficio__icono-caja img,
	.cdx-beneficio__icono-caja svg { width: 32px; height: 32px; }
	/* El título iba al `h3` del sistema (22 a este escalón) y se quedaba grande
	   para 150 px de columna. Y el hueco hasta la descripción baja de 12 a 6. */
	.cdx-beneficio__titulo { font-size: 18px; line-height: 1.25; margin: 0 0 6px; }
	/* ⚠️ 15 px era demasiado poco: el mínimo para texto de lectura en móvil son
	   16, y por debajo se lee peor en pantalla pequeña. Se sube a 16 y se
	   compensa apretando un punto la interlínea, para que las dos columnas de
	   150 px sigan cabiendo sin que el bloque crezca. */
	.cdx-beneficio__texto { font-size: 16px; line-height: 1.4; }
}

/* ---------- Bloque complementario (foto + texto) ---------- */
/* Calcado del bloque «Simple in approach but world class branding solutions»
   de la plantilla de agencia de branding. NO es una caja con fondo: es una
   composición a dos columnas sobre blanco, con la foto a la izquierda a su
   proporción natural y el texto a la derecha, BAJADO y con sangría.

   Medido allí a 1600, sobre los 1570 útiles del contenedor:
     columna izquierda 791, con 60 de sangría derecha → foto de 731
     columna derecha   779, con 36 de sangría izquierda → texto de 743
     el bloque de texto arranca 60 px por debajo de la foto
     titular 80/89,6 ls −2 · párrafo 20/32 a 24 del titular · enlace a 48

   (Antes era una caja gris a mitades en la que la foto, vertical, imponía
   863 px de alto a un texto de 271.) */
.cdx-servicio-caja__interior {
	display: grid;
	grid-template-columns: 791fr 779fr;
	column-gap: 0;
	align-items: start;
}
@media (max-width: 991px) { .cdx-servicio-caja__interior { grid-template-columns: 1fr; row-gap: 32px; } }

.cdx-servicio-caja__marco { display: block; padding-right: 60px; }
@media (max-width: 1199px) { .cdx-servicio-caja__marco { padding-right: 40px; } }
@media (max-width: 991px)  { .cdx-servicio-caja__marco { padding-right: 0; } }
/* La foto va a su proporción natural: aquí no se recorta nada. */
.cdx-servicio-caja__imagen { display: block; width: 100%; height: auto; }

.cdx-servicio-caja__cuerpo { padding-left: 36px; margin-top: 60px; }
@media (max-width: 1199px) { .cdx-servicio-caja__cuerpo { padding-left: 24px; margin-top: 40px; } }
@media (max-width: 991px)  { .cdx-servicio-caja__cuerpo { padding-left: 0; margin-top: 0; } }
/* Titular de SECCIÓN, no de tarjeta: allí va a 80, el mismo cuerpo que el
   resto de titulares de bloque. Antes iba a 28. */
.cdx-servicio-caja__titulo {
	margin: 0 0 24px;
	font-size: var(--cdx-fs-h2);
	line-height: var(--cdx-lh-titulo-2);
	letter-spacing: var(--cdx-ls-h2);
}
.cdx-servicio-caja__texto { max-width: none; }
.cdx-servicio-caja__cuerpo .cdx-enlace { margin-top: 48px; }
@media (max-width: 991px) { .cdx-servicio-caja__cuerpo .cdx-enlace { margin-top: 32px; } }

/* ---------- CTA intermedio ---------- */
/* Franja A SANGRE Y CENTRADA, calcada de la de «Let's shape something new» del
   pie de la plantilla de portfolio personal: fondo negro, relleno de 130
   arriba y abajo, titular grande, línea de apoyo a 24 y píldora BLANCA a 48.
   (Antes era una caja negra dentro del contenedor, con el titular a la
   izquierda y el botón a la derecha.)

   El titular va a 92 y no a los 140 del original: nuestras frases son largas
   —«Necesito un diseño web profesional»— y a 140 ocupaban cinco líneas. Es el
   mismo cuerpo que el CTA final de la portada, así que los dos cierres del
   sitio riman. */
.cdx-servicio-cta {
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
}
.cdx-servicio-cta__interior {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}
.cdx-servicio-cta__titulo {
	margin: 0;
	color: var(--cdx-blanco);
	font-size: calc(var(--cdx-fs-h2) * 1.15);
	line-height: var(--cdx-lh-titulo-2);
	letter-spacing: var(--cdx-ls-h2);
	max-width: 20ch;
}
/* Sobre negro el texto secundario va en el gris claro de la paleta (#c5c5c5),
   el mismo token que las líneas de rejilla. */
.cdx-servicio-cta__texto {
	margin: 24px 0 0;
	max-width: 60ch;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-borde);
}
/* ---------- CTA INVERTIDO (fondo blanco, contenido negro) ----------
   Es la versión de esta misma franja que usa el original en su cierre («Let's
   shape something new»): misma maqueta centrada, colores dados la vuelta.
   La usa la página de EQUIPO; la ficha de servicio se queda con la negra.

   ⚠️ La variante NO lleva `tiene-fondo`: esa clase es la que le dice al ritmo
   entre bloques (§5.2) que la sección pinta fondo propio y por tanto se come el
   hueco blanco de 130. Aquí el fondo ES el blanco de la página, así que si
   llevara `tiene-fondo` el cierre quedaría pegado al bloque anterior. */
.cdx-servicio-cta--claro { background: var(--cdx-blanco); color: var(--cdx-negro); }
.cdx-servicio-cta--claro .cdx-servicio-cta__titulo { color: var(--cdx-negro); }
.cdx-servicio-cta--claro .cdx-servicio-cta__texto { color: var(--cdx-gris-texto); }

/* El aire contra el pie ya NO se pone aquí: lo da la regla única de `base.css`
   (caso 3 del ritmo). Se retiró al centralizarla. */

/* La flecha ornamental, suelta y encima del titular. */
.cdx-servicio-cta__flecha { margin-bottom: 40px; }
@media (max-width: 991px) { .cdx-servicio-cta__flecha { margin-bottom: 28px; } }
/* Sin texto al lado no hay línea base que compensar, así que se deshace el
   `top` que la flecha del hero necesita para apoyarse en el suelo del titular. */
.cdx-hero__flecha--suelta { top: 0; }

/* Píldora blanca del original: 20/38 de relleno y radio 60, más grande que la
   del sistema (14/20/14/24 y radio 40). */
.cdx-servicio-cta .cdx-boton { margin-top: 48px; }
.cdx-boton--grande {
	padding: 20px 38px;
	border-radius: 60px;
	font-size: var(--cdx-fs-h3);
	line-height: 1;
	letter-spacing: var(--cdx-ls-tarjeta);
	gap: 8px;
}

/* ⚠️ LA FLECHA TAMBIÉN CRECE. El texto de este botón va a 28 y no a los 18 del
   botón normal (×1,56), pero la flecha se quedaba en su tamaño base y al lado
   de esa letra se veía diminuta.

   Se reescala a ×1,5 —factor limpio y muy cerca del 1,56 del texto— tocando
   SOLO las variables del componente, que es como está pensado para crecer.

   ⚠️ **Hay que mantener el INVARIANTE del relevo** o al reiniciar sin
   transición se ve un salto:
       --f-reposo-t = --f-caja-al − --f-glifo − --f-fin-b
   Aquí: **1,5 = 21 − 16,5 − 3**. ✔

   💡 Va en `.cdx-boton--grande` y no en cada plantilla, así que vale para los
   DOS botones de este tamaño que hay en el sitio: el cierre de la página de
   equipo y el CTA intermedio de la ficha de servicio. */
.cdx-boton--grande .cdx-flecha {
	--f-caja-an: 24px;
	--f-caja-al: 21px;
	--f-glifo: 16.5px;
	--f-reposo-t: 1.5px;
	--f-fuera-t: -22.5px;
	--f-fuera-i: 22.5px;
	--f-dentro-b: -22.5px;
	--f-dentro-i: -15px;
	--f-fin-b: 3px;
}
/* Desde 991 el botón baja a cuerpo de texto (20), así que la flecha vuelve a su
   tamaño base: a ×1,5 se pasaría de grande. */
@media (max-width: 991px) {
	.cdx-boton--grande .cdx-flecha {
		--f-caja-an: 16px; --f-caja-al: 14px; --f-glifo: 11px;
		--f-reposo-t: 1px; --f-fuera-t: -15px; --f-fuera-i: 15px;
		--f-dentro-b: -15px; --f-dentro-i: -10px; --f-fin-b: 2px;
	}
}
@media (max-width: 991px) {
	.cdx-boton--grande { padding: 16px 28px; font-size: var(--cdx-fs-body); }
	.cdx-servicio-cta .cdx-boton { margin-top: 32px; }
}

/* ---------- Problema/solución de la ficha ---------- */
/* Ya NO tiene estilo propio: usa exactamente el de la portada, filas de alto
   fijo y círculo con flecha incluidos (§20.3). La variante de alto libre
   `--estatica` que había aquí se retiró al no usarla nadie. */

/* ---------- Rejilla de logos simple (clientes del servicio) ---------- */
/* La de la portada es asimétrica y coloca cada celda a mano; esta es regular.
   Comparten la celda `.cdx-logo-cliente`, con su borde colapsado a -1px.

   Es la del bloque de logos de `/design-studio/`, medida allí: seis columnas
   de 261,7 con filas de 240 (no de 200, como estaba) y el logo centrado en
   la celda. */
.cdx-rejilla-logos-simple {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	grid-auto-rows: 240px;
	gap: 0;
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (max-width: 1199px) { .cdx-rejilla-logos-simple { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 180px; } }
@media (max-width: 767px)  { .cdx-rejilla-logos-simple { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 140px; } }

/* ---------- «Coodex en prensa» ----------
   Recupera un bloque del sitio antiguo: los medios que han hablado de Coodex,
   con su logo enlazado a la noticia.

   NO estrena retícula: es la misma `.cdx-rejilla-logos-simple` de los clientes,
   con sus celdas de borde colapsado. Lo único propio es el número de columnas,
   que lo fija la plantilla en `--cdx-prensa-cols` a partir de cuántas
   apariciones haya: con 6 columnas fijas y 2 recortes de prensa quedaban cuatro
   celdas vacías colgando a la derecha.

   ⚠️ La celda es un `<a>`, no un `<li>` mudo: aquí el logo LLEVA A LA NOTICIA,
   que es el sentido del bloque. Por eso hereda además el foco visible. */
.cdx-prensa__rejilla {
	grid-template-columns: repeat(var(--cdx-prensa-cols, 4), minmax(0, 1fr));
	/* ⚠️ **Sin tope de ancho.** Al vivir dentro de la columna derecha del patrón
	   partido, las celdas se reparten esa columna y ya salen proporcionadas.
	   Cuando el bloque iba a ancho completo sí hacía falta toparlas (con dos
	   logos y `1fr` cada celda salía de 780×240 para un rótulo de 400 px), pero
	   ahora ese tope las dejaría encogidas y descentradas dentro de la columna. */
	margin-top: 40px;
}
@media (max-width: 991px) { .cdx-prensa__rejilla { margin-top: 32px; } }
@media (max-width: 1199px) { .cdx-prensa__rejilla { grid-template-columns: repeat(min(var(--cdx-prensa-cols, 4), 3), minmax(0, 1fr)); } }
@media (max-width: 767px)  { .cdx-prensa__rejilla { grid-template-columns: repeat(min(var(--cdx-prensa-cols, 4), 2), minmax(0, 1fr)); } }

.cdx-prensa__enlace {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: 1.5rem;
}
/* Rótulo del bloque de logos: en `/design-studio/` NO es un titular de
   sección de 80px, sino una línea a CUERPO DE TEXTO justo encima de la
   rejilla (20/26, interletraje +0,4, a 24 de la parrilla). Es lo que hace que
   el bloque se lea como pie de los testimonios y no como sección aparte. */
.cdx-rotulo-logos {
	margin: 0 0 24px;
	font-size: var(--cdx-fs-body);
	line-height: 1.3;
	letter-spacing: .4px;
	font-weight: var(--cdx-peso-normal);
	color: var(--cdx-negro);
}
@media (max-width: 991px) { .cdx-rotulo-logos { margin-bottom: 20px; } }

/* La franja de logos va PEGADA a la cabecera, no a 130 px de ella. Desde que
   subió por encima de la descripción (§21.1) ya no es una sección más, es el
   remate del arranque de la ficha: con el hueco entero del ritmo se leía como
   un bloque suelto. Baja al hueco interno del sistema (60), con sus escalones.

   El selector lleva las DOS clases (0,2,0) para ganarle a
   `.cdx-bloque { padding-top: var(--cdx-sec-top) }` sin depender del orden de
   los ficheros. */
.cdx-bloque.cdx-servicio-logos { padding-top: 60px; }
@media (max-width: 1199px) { .cdx-bloque.cdx-servicio-logos { padding-top: 48px; } }
@media (max-width: 767px)  { .cdx-bloque.cdx-servicio-logos { padding-top: 36px; } }

/* ---------- Casos de éxito relacionados (pieza del carrusel) ---------- */
/* La pieza del `portfolio-slider` de referencia y, debajo, a 20, el título
   recortado a una línea y el servicio precedido de un guion.
   (Antes era una tarjeta de parrilla con la foto forzada a 4/3.)

   ⚠️ EL MARCO RECORTA, y esto cambió: antes la foto iba a proporción natural,
   porque así es como se comporta el suyo. Pero el suyo puede permitírselo: sus
   seis fotos de demo son TODAS de 1544×1400, así que le salen seis cajas
   idénticas de 667×604 sin hacer nada. Las nuestras vienen de la migración y
   cada una tiene su tamaño, así que la fila salía descuadrada.

   Se le fija la proporción del suyo —1544/1400 = 1,103, medida sobre sus
   propios ficheros— y se recorta con `cover`. A 1600, con la pieza en 656:
   656×595. Lo que sobra se pierde por los lados, que es lo que se pidió. */
.cdx-tarjeta-caso__enlace { display: block; color: inherit; text-decoration: none; }
.cdx-tarjeta-caso__foto {
	display: block;
	aspect-ratio: 1544 / 1400;
	overflow: hidden;
	background: var(--cdx-gris-fondo);
}
.cdx-tarjeta-caso__foto img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	/* Su zoom crece desde el borde IZQUIERDO, no desde el centro. */
	transform-origin: left center;
	transition: transform .5s cubic-bezier(.37, .08, .02, .93);
}
.cdx-tarjeta-caso__enlace:hover .cdx-tarjeta-caso__foto img { transform: scale(1.1); }

.cdx-tarjeta-caso__pie { display: block; margin-top: 20px; }
@media (max-width: 991px) { .cdx-tarjeta-caso__pie { margin-top: 10px; } }
.cdx-tarjeta-caso__titulo {
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
/* Guion corto delante del servicio, como su `ri-subtract-line`. */
.cdx-tarjeta-caso__servicio {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 3px;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	color: var(--cdx-negro);
}
@media (max-width: 991px) { .cdx-tarjeta-caso__servicio { margin-top: 2px; font-size: 16px; } }

/* ---------- Guión delante del nombre del servicio ---------- */
/* El servicio de una pieza de portfolio se pinta en TRES sitios, siempre con
   `cdx_servicio_de_pieza()` y siempre bajo el título:
     · la tarjeta del carrusel de casos (ficha de servicio)
     · la pieza de la galería de `/mejores/`
     · la pieza de la retícula de portfolio — que es COMPARTIDA entre la
       portada y la página de Casos de éxito
   El guión estaba solo en la primera. Va en las tres, que es lo que hace el
   diseño de referencia con su `quanto-project-date`.

   ⚠️ Esto CAMBIA LA PORTADA: su bloque de portfolio usa la misma parte. Es un
   cambio de CSS, así que el HTML de la portada no se mueve —la comparación
   byte a byte sigue dando 0—, pero lo que se ve sí. Está hecho a propósito,
   por consistencia; si se quisiera dejar la portada sin guión habría que
   acotar la regla con `.cdx-portfolio--claro` o similar.

   Los dos `<p>` van a `flex` (de bloque) y no a `inline-flex`: así conservan
   su margen superior tal cual estaba. */
/* ⚠️ **flex-start, NO center.** Con align-items: center el guión se centraba
   respecto a TODO el bloque de texto, así que en cuanto el servicio partía en
   dos o tres líneas —«Desarrollador web y E-commerce» en la ficha de equipo a
   dos columnas— el guión se quedaba flotando a media altura, lejos de la
   palabra a la que acompaña. Va arriba, a la altura de la PRIMERA línea. */
.cdx-proyecto__meta,
.cdx-pieza-galeria__dato,
.cdx-miembro__cargo {
	display: flex;
	align-items: flex-start;
	gap: 8px;
}
.cdx-tarjeta-caso__servicio { align-items: flex-start; }
.cdx-tarjeta-caso__servicio::before,
.cdx-proyecto__meta::before,
.cdx-pieza-galeria__dato::before,
.cdx-miembro__cargo::before {
	content: '';
	width: 14px;
	height: 1px;
	background: currentColor;
	flex: none;
	/* Alineado arriba, el filete de 1px se iría al borde mismo de la caja, por
	   encima de las mayúsculas. Se baja media línea para que quede centrado en
	   la PRIMERA línea, que es donde estaba cuando el texto ocupaba solo una.
	   Las dos declaraciones son a propósito: la unidad lh (la interlínea del
	   propio elemento) lo clava a cualquier cuerpo, y la de arriba es el
	   respaldo — un navegador que no entienda lh descarta esa declaración y se
	   queda con el em, que es la misma cuenta con la interlínea de 1,444 que
	   tienen los cuatro sitios. */
	margin-top: .7em;
	margin-top: calc((1lh - 1px) / 2);
}

/* ---------- Testimonios (carrusel) ---------- */
/* El de `/design-studio/`: una cita cada vez, con dos botones redondos debajo.
   Medido allí a 1600 — cita a 28/37,8 con −0,28 de interletraje, ficha del
   autor a 32 de la cita, nombre a 36/47,9 con −1 (sí, MÁS GRANDE que la
   cita: es lo que hace su diseño) y cargo a 18 debajo, a 16.

   SIN JS se ven todas seguidas, separadas por filete, y los botones no se
   pintan: el CSS solo apila y esconde cuando el JS marca `data-cdx-listo`
   (misma degradación que las pestañas). */
.cdx-testimonio {
	margin: 0;
	padding: 40px 0;
	border-top: 1px solid var(--cdx-gris-borde);
}
.cdx-testimonio:first-child { padding-top: 0; border-top: 0; }
.cdx-testimonio:last-child { padding-bottom: 0; }
.cdx-testimonio__texto {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-testimonio__texto p { margin: 0 0 .75em; }
.cdx-testimonio__texto p:last-child { margin-bottom: 0; }
/* Reseña de Google (§84): la misma tarjeta, con sus cinco estrellas en NEGRO
   encima del texto (el amarillo de Google no casa con el sitio). */
/* Línea de valoración: la «G» con sus colores (§84.3) y, a 12, las estrellas. */
.cdx-testimonio__valoracion { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; line-height: 0; }
.cdx-testimonio__google { width: 22px; height: 22px; flex: none; }
.cdx-testimonio__estrellas { display: flex; gap: 4px; color: var(--cdx-negro); }
.cdx-testimonio__estrellas svg { width: 18px; height: 18px; flex: none; }
/* Recorte de la reseña a 5 líneas, con «Leer más» y fundido (§84.4 y §84.6, pieza 16). Solo en
   las reseñas: los testimonios propios son cortos y no se tocan. */
/* §84.6: ya no con `line-clamp` (ponía «…»), sino por ALTO, 5 líneas (`5lh`),
   y con el MISMO degradado a blanco del texto SEO de la portada
   (`.cdx-home-intro`, §71.3), solo en las que de verdad se recortan: la clase
   `es-recortada` la pone la pieza 16 al medir. El degradado ocupa 3 líneas
   (§84.7), no los 180 px de la portada, porque aquí se ven 5 y no 10.
   Como allí, el pseudoelemento no EXISTE con la reseña abierta. */
.cdx-testimonio--resena .cdx-testimonio__texto {
	position: relative;
	max-height: 5lh;
	overflow: hidden;
}
/* §84.9: el fundido ya NO se crea ni se destruye: existe siempre en la reseña
   recortada y lo que cambia es su OPACIDAD, con la misma duración y curva que
   el despliegue (pieza 16). Como va anclado a `bottom: 0` del texto, mientras
   el texto crece o encoge el fundido viaja con su borde de abajo, y se
   desvanece o aparece a la vez. Aparecer y desaparecer de golpe era lo brusco,
   sobre todo en «Leer menos».
   ⚠️ A diferencia de la portada (§71.3, donde apagarlo con `opacity` «no se
   aplicaba»), aquí la regla de apagado tiene MÁS especificidad que la de
   encendido (lleva `.es-abierta` de más), así que gana siempre. Medido. */
.cdx-testimonio--resena.es-recortada .cdx-testimonio__texto::after {
	content: '';
	opacity: 1;
	transition: opacity .5s cubic-bezier(.22, .61, .36, 1);
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	/* §84.7: 3 líneas y no 2, y con paradas intermedias: con 2 líneas y un
	   degradado lineal se leía como si solo tapara la última. Así la
	   antepenúltima apenas se toca, la penúltima ya se nota y la última se
	   funde del todo. */
	height: 3lh;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .35) 33%, rgba(255, 255, 255, .75) 66%, var(--cdx-blanco) 100%);
	pointer-events: none;
}
.cdx-testimonio--resena.es-recortada.es-abierta .cdx-testimonio__texto::after { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
	.cdx-testimonio--resena.es-recortada .cdx-testimonio__texto::after { transition: none; }
}
.cdx-testimonio--resena.es-abierta .cdx-testimonio__texto { max-height: none; }
.cdx-testimonio__mas {
	margin-top: 16px;
	padding: 10px 0;
	border: 0;
	background: none;
	color: var(--cdx-negro);
	font: inherit;
	font-size: var(--cdx-fs-small);
	font-weight: var(--cdx-peso-fuerte);
	text-decoration: underline;
	text-underline-offset: 4px;
	cursor: pointer;
}
.cdx-testimonio__mas[hidden] { display: none; }
.cdx-testimonio__autor { margin-top: 32px; }
.cdx-testimonio__nombre {
	display: block;
	font-size: 36px;
	line-height: 1.33;
	letter-spacing: -1px;
	font-weight: var(--cdx-peso-normal);
	color: var(--cdx-negro-puro);
}
.cdx-testimonio__cargo {
	display: block;
	margin-top: 16px;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	color: var(--cdx-negro);
}
@media (max-width: 991px) {
	.cdx-testimonio__autor { margin-top: 20px; }
	.cdx-testimonio__nombre { font-size: 26px; }
}
@media (max-width: 575px) { .cdx-testimonio__nombre { font-size: 20px; } }

/* Con JS: BARRIDO LATERAL, igual que su Swiper. Medido en su
   `.testimonial3-slider`: `effect: slide`, `speed: 300`, curva `ease`,
   `slidesPerView: 1`, `loop: true` y **`autoHeight: false`**.

   ⚠️ **`autoHeight: false` es lo que mantiene los botones quietos**, y es todo
   el truco: las citas van en una FILA FLEX, así que las cinco (aquí dos) miden
   lo mismo —la de la más larga— y la ventana del carrusel nunca cambia de
   alto. Medido en su demo: sus 5 slides dan 301,9 px exactos los cinco. Si en
   vez de eso se esconde la inactiva, la caja encoge con cada cita y los
   botones bailan, que es lo que pasaba aquí.

   La ventana recorta con `overflow: clip` y NO con `hidden` (lección 19:
   `hidden` crea contenedor de desplazamiento). */
.cdx-testimonios[data-cdx-listo] .cdx-testimonio {
	padding: 0;
	border-top: 0;
}
.cdx-testimonios[data-cdx-listo] .cdx-testimonios__pista {
	display: flex;
	flex-wrap: nowrap;
	/* El índice lo pone el JS. `-100%` por paso, como su Swiper: sus slides
	   miden exactamente el ancho de la ventana y el hueco declarado
	   (`spaceBetween: 20`) no llega a aplicarse — medido, `margin-right: 0`. */
	transform: translateX(calc(var(--cdx-t-i, 0) * -100%));
	transition: transform .3s ease;
}
.cdx-testimonios[data-cdx-listo] .cdx-testimonio {
	flex: 0 0 100%;
	min-width: 0;
}
.cdx-testimonios[data-cdx-listo] { overflow: clip; }

/* Quien prefiere no ver movimiento salta de cita sin barrido. */
@media (prefers-reduced-motion: reduce) {
	.cdx-testimonios[data-cdx-listo] .cdx-testimonios__pista { transition: none; }
}

/* Botones redondos: los mismos 70px (60 ≤991, 50 ≤767) sobre el gris del
   sistema que usa el diseño, y el mismo hueco de 8 y separación de 48. */
.cdx-testimonios__navegacion { display: none; }
.cdx-testimonios[data-cdx-listo] .cdx-testimonios__navegacion {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 48px;
}
@media (max-width: 1199px) { .cdx-testimonios[data-cdx-listo] .cdx-testimonios__navegacion { margin-top: 30px; } }
@media (max-width: 991px)  { .cdx-testimonios[data-cdx-listo] .cdx-testimonios__navegacion { margin-top: 20px; } }
.cdx-testimonios__boton {
	appearance: none;
	width: 70px;
	height: 70px;
	display: grid;
	place-content: center;
	padding: 0;
	border: 1px solid var(--cdx-gris-fondo);
	border-radius: 50%;
	background: var(--cdx-gris-fondo);
	color: var(--cdx-negro);
	cursor: pointer;
	transition: background-color .3s, border-color .3s, color .3s;
}
.cdx-testimonios__boton:hover {
	background: var(--cdx-negro);
	border-color: var(--cdx-negro);
	color: var(--cdx-blanco);
}
@media (max-width: 991px) { .cdx-testimonios__boton { width: 60px; height: 60px; } }
@media (max-width: 767px) { .cdx-testimonios__boton { width: 50px; height: 50px; } }
/* La punta ocupa 12 de los 16 de alto del viewBox, así que a 26px de caja
   mide 12,2 × 19,5: los 13 × 20 que mide la suya. */
.cdx-chevron { display: block; width: 26px; height: 26px; }
@media (max-width: 991px) { .cdx-chevron { width: 22px; height: 22px; } }

/* ---------- Equipo ---------- */
.cdx-rejilla-equipo {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 48px 24px;
	list-style: none; margin: 0; padding: 0;
}
@media (max-width: 1199px) { .cdx-rejilla-equipo { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .cdx-rejilla-equipo { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.cdx-miembro__foto { overflow: hidden; aspect-ratio: 3 / 4; background: var(--cdx-gris-fondo); }
.cdx-miembro__foto img {
	display: block; width: 100%; height: 100%; object-fit: cover;
	transition: transform .5s cubic-bezier(.37, .08, .02, .93);
}
.cdx-miembro:hover .cdx-miembro__foto img { transform: scale(1.05); }
/* El diseño separa la ficha de la foto 20px (15 en tablet). */
.cdx-miembro__nombre { margin: 20px 0 0; font-size: var(--cdx-fs-h3); }
.cdx-miembro__cargo { margin: 2px 0 0; font-size: 18px; line-height: 1.444; color: var(--cdx-gris-texto); }
@media (max-width: 991px) { .cdx-miembro__nombre { margin-top: 15px; } }
/* ⚠ A DOS columnas los cuerpos de escritorio quedan desproporcionados: con
   ~163px de columna, «Adrián Rodríguez» a 22 parte en dos líneas y el cargo a
   18 en tres, y la ficha pesa más que su propia foto. Se bajan a 18 y 16.
   16 es el suelo: por debajo se incumple el mínimo de cuerpo en móvil (§42.3). */
@media (max-width: 767px) {
	.cdx-miembro__nombre { font-size: 18px; }
	.cdx-miembro__cargo { font-size: 16px; }
}

/* ---------- Capítulos de contenido del servicio ---------- */
/* Sustituyen a los bloques alternos de foto + texto, que alternaban el lado de
   la imagen. El porqué, medido, está en la cabecera de
   `template-parts/servicio-bloques-alternos.php`; en corto: fotos de 558
   estiradas a 769 (ampliadas un 38 %), filas de 551 de alto por culpa de la
   foto con textos de 213, y de los tres servicios que muestran el bloque solo
   uno tiene imágenes.

   Ahora es el patrón partido de toda la ficha —rótulo a la izquierda,
   contenido a la derecha— repetido y separado por filete, que es el mismo
   recurso del carril de pestañas y de los beneficios. A 1600: 617 + 864 con
   canal de 80. */
/* El bloque pide MÁS AIRE por arriba del que da el ritmo, porque llega justo
   detrás de las filas de problema/solución y sin él los dos bloques se leían
   pegados. Los 60 de más van en el PROPIO BLOQUE y no como relleno inferior
   del anterior: así, cuando un servicio no tiene capítulos —once de los
   catorce—, el hueco tampoco existe y el ritmo se queda en sus 130. */
.cdx-servicio-capitulos { padding-top: calc(var(--cdx-sec-top) + 60px); }
@media (max-width: 991px) { .cdx-servicio-capitulos { padding-top: calc(var(--cdx-sec-top) + 40px); } }

.cdx-capitulo {
	display: grid;
	grid-template-columns: 5fr 7fr;
	column-gap: 80px;
	align-items: start;
	border-top: 1px solid var(--cdx-gris-borde);
	padding-top: 48px;
}
.cdx-capitulo + .cdx-capitulo { margin-top: 72px; }
@media (max-width: 1199px) {
	.cdx-capitulo { column-gap: 48px; padding-top: 40px; }
	.cdx-capitulo + .cdx-capitulo { margin-top: 56px; }
}
@media (max-width: 991px) {
	.cdx-capitulo { grid-template-columns: 1fr; row-gap: 20px; padding-top: 32px; }
	.cdx-capitulo + .cdx-capitulo { margin-top: 40px; }
}

/* La cabeza se queda ARRIBA aunque el cuerpo sea largo: es el rótulo de la
   sección, no un pie. Con cinco capítulos de texto largo (el caso de «Google
   Ads y Social Ads») centrarla la dejaría flotando a media altura. */
.cdx-capitulo__numero {
	display: block;
	margin-bottom: 14px;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: -.18px;
	color: var(--cdx-gris-texto);
}
/* Mismo cuerpo que el titular del panel de pestañas: son dos rótulos del mismo
   rango dentro de la ficha, y así no hace falta un tamaño suelto más. */
.cdx-capitulo__titulo {
	margin: 0;
	font-size: calc(var(--cdx-fs-h3) * 1.15);
	line-height: 1.25;
	letter-spacing: var(--cdx-ls-tarjeta);
}

.cdx-capitulo__enlace { margin-top: 32px; }

/* CON IMAGEN: la FOTO a la izquierda y todo el contenido —número, título,
   texto y enlace— a la derecha.

   El reparto es **5fr 7fr**, y la columna estrecha es la de la foto a
   propósito: las del repetidor miden 558 de ancho y en 617 se amplían un 11 %,
   mientras que en la columna ancha (864) se ampliarían un 55 %.

   Va con `:has()` porque la foto es opcional: SIN foto se queda el reparto de
   siempre (rótulo a la izquierda, texto a la derecha), que es lo que tiene
   sentido cuando no hay nada que poner en la otra columna. En «Google Ads y
   Social Ads» son cinco capítulos sin una sola imagen: dejarles 617 px de
   columna vacía sería peor que no tener columna. */
.cdx-capitulo:has(.cdx-capitulo__marco) { grid-template-columns: 5fr 7fr; }
.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__marco { grid-column: 1; grid-row: 1 / span 2; }
.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cabeza { grid-column: 2; grid-row: 1; }
.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cuerpo { grid-column: 2; grid-row: 2; margin-top: 24px; }
/* Apilado, el orden es TÍTULO → FOTO → TEXTO. El del HTML es cabeza → cuerpo →
   marco (que es el que interesa en desktop, donde la foto ocupa su columna
   entera), así que aquí se recoloca con `order`: la foto se mete entre el
   rótulo y el texto en vez de quedarse descolgada al final. */
@media (max-width: 991px) {
	.cdx-capitulo:has(.cdx-capitulo__marco) { grid-template-columns: 1fr; }
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cabeza,
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cuerpo,
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__marco { grid-column: 1; grid-row: auto; }
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cabeza { order: 1; }
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__marco  { order: 2; margin-top: 20px; }
	.cdx-capitulo:has(.cdx-capitulo__marco) .cdx-capitulo__cuerpo { order: 3; margin-top: 20px; }
}

.cdx-capitulo__marco { margin: 0; }
.cdx-capitulo__imagen { display: block; width: 100%; height: auto; }

/* ---------- Qué más podemos hacer ---------- */
.cdx-rejilla-cards {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 48px 24px;
	list-style: none; margin: 0; padding: 0;
}
@media (max-width: 991px) { .cdx-rejilla-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 575px) { .cdx-rejilla-cards { grid-template-columns: 1fr; } }

.cdx-card-mas__enlace { display: block; color: inherit; text-decoration: none; }
.cdx-card-mas__foto { display: block; overflow: hidden; aspect-ratio: 4 / 3; background: var(--cdx-gris-fondo); }
.cdx-card-mas__foto img {
	display: block; width: 100%; height: 100%; object-fit: cover;
	transition: transform .6s cubic-bezier(.37, .08, .02, .93);
}
.cdx-card-mas__enlace:hover .cdx-card-mas__foto img { transform: scale(1.06); }
.cdx-card-mas__pie { display: flex; align-items: flex-start; justify-content: space-between; gap: 15px; margin-top: 24px; }
.cdx-card-mas__titulo { margin: 0; }
/* Círculo con flecha del diseño: 70px, 50 en tablet, y se invierte al pasar. */
.cdx-card-mas__circulo {
	flex: none;
	width: 70px; height: 70px;
	display: grid; place-content: center;
	border: 1px solid var(--cdx-gris-fondo);
	background: var(--cdx-gris-fondo);
	border-radius: 50%;
	transition: background-color .3s, border-color .3s, color .3s;
}
@media (max-width: 991px) { .cdx-card-mas__circulo { width: 50px; height: 50px; } }
.cdx-card-mas__enlace:hover .cdx-card-mas__circulo {
	background: var(--cdx-negro);
	border-color: var(--cdx-negro);
	color: var(--cdx-blanco);
}

/* ---------- Últimas entradas del blog ---------- */
/* El bloque de blog de `/design-studio/`: banda gris, cabecera a mitades con
   el enlace «ver todos» abajo a la derecha y TRES tarjetas en fila.
   (La fila de dos columnas con filete que había aquí antes es su `style-2`,
   la de las páginas de listado, no la de esta página.)                      */
.cdx-servicio-blog { background: var(--cdx-gris-fondo); }

/* Cabecera: mitad y mitad, con el enlace pegado al pie de su columna. Los 60
   de separación con las tarjetas son el `gap` medido en su contenedor. */
.cdx-blog-cabecera {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 24px;
	align-items: end;
	margin-bottom: var(--cdx-espacio-bloque);
}
@media (max-width: 991px) {
	.cdx-blog-cabecera { grid-template-columns: 1fr; row-gap: 24px; align-items: start; }
}
.cdx-blog-cabecera__accion { justify-self: end; }
@media (max-width: 991px) { .cdx-blog-cabecera__accion { justify-self: start; } }

.cdx-rejilla-entradas {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 48px 24px;
	list-style: none; margin: 0; padding: 0;
}
/* Sus escalones son los de Bootstrap que lleva la tarjeta (`col-xl-4
   col-md-6 col-sm-12`): tres columnas solo desde 1200, dos entre 576 y 1199 y
   una por debajo. A 1024 en tres columnas las fotos quedaban en 312 de ancho
   por 300 de alto, casi cuadradas. */
@media (max-width: 1199px) { .cdx-rejilla-entradas { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 575px)  { .cdx-rejilla-entradas { grid-template-columns: 1fr; } }

/* Foto de ALTO FIJO, no de proporción: son sus 400px (340 ≤1399, 300 ≤1199,
   280 ≤991), que es lo que le da al bloque su franja alta. */
.cdx-tarjeta-entrada__foto {
	display: block;
	overflow: hidden;
	height: 400px;
	background: var(--cdx-gris-suave);
}
@media (max-width: 1399px) { .cdx-tarjeta-entrada__foto { height: 340px; } }
@media (max-width: 1199px) { .cdx-tarjeta-entrada__foto { height: 300px; } }
@media (max-width: 991px)  { .cdx-tarjeta-entrada__foto { height: 280px; } }
.cdx-tarjeta-entrada__foto img {
	display: block; width: 100%; height: 100%; object-fit: cover; object-position: center;
	transition: transform .5s;
}
.cdx-tarjeta-entrada__foto:hover img { transform: scale(1.1); }

.cdx-tarjeta-entrada__cuerpo { margin-top: 24px; }
@media (max-width: 991px) { .cdx-tarjeta-entrada__cuerpo { margin-top: 20px; } }
/* Titular a DOS líneas: el suyo va recortado, y si no las tarjetas de una
   fila dejan la fecha a alturas distintas. */
/* ⚠️ **El tamaño se fija AQUÍ, no se hereda del tag.** La tarjeta se pinta con
   nivel 3 en la ficha de servicio y al pie de la entrada, pero con **nivel 2**
   en el listado (§65.3: allí cuelga directa del h1 y un h3 se saltaría el h2).
   Sin `font-size` propio eso la mandaba al `h2` global, que son **80 px** de
   titular de sección: los títulos del listado salían gigantes. Son los 28/37,8
   medidos en la demo, y los escalones de móvil los trae ya el token. */
.cdx-tarjeta-entrada__titulo {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.cdx-tarjeta-entrada__titulo a {
	color: inherit;
	text-decoration: none;
	background-image: linear-gradient(currentColor, currentColor);
	background-size: 0 2px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size .25s cubic-bezier(.785, .135, .15, .86);
}
.cdx-tarjeta-entrada__titulo a:hover { background-size: 100% 2px; }

/* Fecha con el filete corto delante: 30×1 centrado en la línea, a 42 de
   sangría, como el suyo. */
.cdx-tarjeta-entrada__fecha {
	position: relative;
	margin: 10px 0 0;
	padding-left: 42px;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	color: var(--cdx-negro);
}
.cdx-tarjeta-entrada__fecha::before {
	content: '';
	position: absolute;
	left: 0;
	top: 50%;
	width: 30px;
	height: 1px;
	background: var(--cdx-negro);
}
@media (max-width: 991px) { .cdx-tarjeta-entrada__fecha { font-size: 16px; } }

/* ---------- FAQs (acordeón nativo) ---------- */
/* `<details>`/`<summary>`: sin JS y accesible de serie. Lo usan la ficha de
   servicio y el bloque de FAQs de la portada, que comparten estas clases.
   El signo de abrir/cerrar se DIBUJA con dos barras en CSS: nada que cargar. */
.cdx-faq {
	border-top: 1px solid var(--cdx-gris-borde);
}
.cdx-faq:last-child { border-bottom: 1px solid var(--cdx-gris-borde); }

/* Pregunta a 24 (el cuerpo `h4` del sistema), NO a 28: es el que mide su
   acordeón, y a 28 las preguntas largas ocupaban tres líneas. */
.cdx-faq__pregunta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: 32px 0;
	cursor: pointer;
	list-style: none;                 /* Firefox */
	font-size: var(--cdx-fs-h4);
	line-height: 1.41;
	letter-spacing: 0;
	font-weight: 600;
	transition: color .3s;
}
/* Abierta, la pregunta se acerca a su respuesta: 16 abajo en vez de 32. */
.cdx-faq[open] .cdx-faq__pregunta { padding-bottom: 16px; }
/* Fuera el triangulito nativo: el indicador es el chevron dibujado. */
.cdx-faq__pregunta::-webkit-details-marker { display: none; }
.cdx-faq__pregunta::marker { content: ''; }
.cdx-faq__pregunta:hover { color: var(--cdx-gris-texto); }

/* Indicador: CHEVRON que gira media vuelta al abrir, como el de su acordeón
   (antes era un «+» que pasaba a «−»). Mismo trazado que el suyo —`M2 5 L8 11
   L14 5`, puntas redondeadas— y el mismo giro de −180° en 0,2s.
   Va como imagen de fondo, así que el color es fijo: es lo que hace el suyo, y
   por eso no acompaña al gris del `:hover`. El grosor sí se sube a 1,5 para
   que empareje con el chevron de los botones del carrusel. */
.cdx-faq__pregunta::after {
	content: '';
	flex: none;
	width: 20px;
	height: 20px;
	background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230f0f0f' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");
	background-size: 20px;
	background-position: center;
	background-repeat: no-repeat;
	transition: transform .2s ease-in-out;
}
.cdx-faq[open] .cdx-faq__pregunta::after { transform: rotate(-180deg); }

.cdx-faq__respuesta {
	padding: 0 0 32px;
	max-width: none;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
}
.cdx-faq__respuesta > :first-child { margin-top: 0; }
.cdx-faq__respuesta > :last-child { margin-bottom: 0; }

@media (max-width: 1199px) {
	.cdx-faq__pregunta { padding: 20px 0; gap: 16px; }
	.cdx-faq[open] .cdx-faq__pregunta { padding-bottom: 10px; }
}
@media (max-width: 991px) {
	.cdx-faq__pregunta { padding: 15px 0; }
	.cdx-faq[open] .cdx-faq__pregunta { padding-bottom: 8px; }
	.cdx-faq__respuesta { padding-bottom: 24px; }
}

/* El acordeón entero es el último bloque de la ficha, contra el pie. */
.cdx-servicio-faqs { padding-bottom: var(--cdx-sec-bottom); }
/* Si detrás va la prosa libre del editor, el relleno lo pone ella. */
.cdx-servicio-faqs:has(+ .cdx-servicio-prosa) { padding-bottom: 0; }
.cdx-servicio-prosa { padding-bottom: var(--cdx-sec-bottom); }

/* ============================================ PARRILLA DE GALERÍA (regular) ====
   Parrilla REGULAR del listado de Proyectos (`/proyectos/`). ⚠️ **La usa SOLO
   esa página**: el comentario que decía que la compartía con la galería de la
   ficha de caso quedó desfasado en §28.5, cuando esa galería pasó a tener
   parrilla propia (`.cdx-galeria-proyecto`, con el patrón 2+1).

   No confundir con las otras dos retículas del sitio:
     · la de MOSAICO (`.cdx-rejilla-portfolio`), asimétrica 42/50 con la columna
       derecha bajada, que usan la portada y la página de Casos de éxito;
     · la de TARJETAS de servicio (`.cdx-rejilla-servicios`), de 4 columnas.

   Sale de la plantilla de GALERÍA de la referencia, medida a 1600: hueco de 48
   en los dos ejes, marco con `overflow:hidden`, y al pasar por encima la foto
   crece a 1,1 desde el borde izquierdo, no desde el centro.

   ⚠️ **TRES columnas, no las dos de la referencia** (decisión del usuario,
   2026-09-28: primero cuatro, después tres el mismo día en la sesión
   siguiente — con 66 proyectos, a dos columnas la página no se acababa). Los
   escalones son los del sistema, no inventados — 3 → 2 (≤1199) → 1 (≤575). */

.cdx-rejilla-galeria {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	/* Su fila declara dos huecos: 24 de base y 48 desde 992 (`g-4 g-lg-5`). */
	gap: 24px;
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (min-width: 992px) { .cdx-rejilla-galeria { gap: 48px 24px; } }
@media (max-width: 1199px) { .cdx-rejilla-galeria { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 575px)  { .cdx-rejilla-galeria { grid-template-columns: 1fr; } }

/* MASONRY de escritorio (PRUEBA, usuario 2026-10-22, §125). La plantilla
   reparte las piezas en tres `<ul>` de columna y da a cada `<li>` su orden
   original (`--cdx-orden`) y la proporción de su foto (`--cdx-proporcion`).
   · Desde 1200: tres columnas independientes, cada foto con su altura, y más
     aire que la parrilla regular — 64 entre columnas y 120 entre piezas (eran 88; el usuario pidió más aire vertical).
   · Por debajo: las columnas se deshacen con `display: contents`, sus `<li>`
     vuelven a ser celdas de la parrilla de arriba y `order` las recoloca en
     el orden de lectura. La foto recupera la proporción fija de siempre. */
.cdx-rejilla-galeria__columna { display: contents; list-style: none; margin: 0; padding: 0; }
.cdx-rejilla-galeria--masonry > .cdx-rejilla-galeria__columna > li { order: var(--cdx-orden, 0); }
@media (min-width: 1200px) {
	.cdx-rejilla-galeria--masonry { gap: 64px; align-items: start; }
	.cdx-rejilla-galeria--masonry .cdx-rejilla-galeria__columna {
		display: flex;
		flex-direction: column;
		gap: 120px;
	}
	.cdx-rejilla-galeria--masonry .cdx-pieza-galeria__media { aspect-ratio: var(--cdx-proporcion, 1544 / 1400); }
	/* ⚠️ Las tres columnas arrancan ALINEADAS arriba (usuario, 2026-10-22): se
	   probó a bajar la central 160 px y no lo quiere, al principio no debe
	   haber hueco. La asimetría la dan solo las alturas. */
}

.cdx-pieza-galeria__enlace { display: block; color: inherit; text-decoration: none; }

/* Proporción FIJA, la de sus fotos (1544×1400). En la demo el marco se ajusta a
   la proporción natural de cada imagen, pero allí todas miden lo mismo; las
   nuestras vienen de la migración y son de tamaños dispares, así que se fija la
   proporción y se recorta con `cover`. Si no, la parrilla quedaría desigual. */
.cdx-pieza-galeria__media {
	display: block;
	aspect-ratio: 1544 / 1400;
	background: transparent;
	/* ⚠️ Sin esto el zoom del hover se salía del encuadre: al quitar
	   `.cdx-revelado` (§74.2) se perdió también su `overflow: hidden`, que
	   antes recortaba el barrido y de propina recortaba este zoom. Pedido por
	   el usuario: que el zoom quede DENTRO del marco, no que lo desborde. */
	overflow: hidden;
}
.cdx-pieza-galeria__media img {
	display: block;
	width: 100%; height: 100%;
	object-fit: cover;
	transition: transform var(--cdx-transicion-lenta);
}
/* ⚠️ Hover MÁS SUTIL, a petición del usuario (2026-09-28, sesión de
   continuidad de §75): copiado tal cual del de Casos de éxito de la Home
   (`.cdx-proyecto:hover .cdx-proyecto__media img { transform: scale(1.04) }`,
   en `bloques.css`) — mismo 1,04 y mismo origen CENTRO (sin
   `transform-origin`, que por defecto es `center`). Esto sustituye al 1,1
   desde el borde izquierdo de §74.2, que era el gesto de la referencia
   Quanto y no el de nuestro propio bloque de Casos de éxito. */
.cdx-pieza-galeria__enlace:hover .cdx-pieza-galeria__media img { transform: scale(1.04); }

/* Pie de la pieza: 20 px hasta el título (10 en tablet) y el dato justo detrás. */
.cdx-pieza-galeria__titulo {
	margin: 20px 0 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
}
.cdx-pieza-galeria__dato { margin: 3px 0 0; font-size: 18px; line-height: 1.444; color: var(--cdx-gris-texto); }
/* Línea libre del campo `texto_tarjeta`, entre el título y el servicio. Va en
   NEGRO y a cuerpo de texto: es contenido del proyecto, no un dato derivado
   como el servicio, así que pesa más que él. */
.cdx-pieza-galeria__texto {
	margin: 6px 0 0;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	color: var(--cdx-negro);
}
@media (max-width: 991px) {
	.cdx-pieza-galeria__titulo { margin-top: 10px; }
	.cdx-pieza-galeria__texto { margin-top: 4px; font-size: 16px; }
	.cdx-pieza-galeria__dato { margin-top: 2px; font-size: 16px; }
}

/* ⚠️ **AQUÍ NO VA SUBRAYADO.** Hubo uno —un degradado que crecía bajo el
   título al pasar por la tarjeta— y se quitó el 2026-09-03 a petición del
   usuario: **la referencia no lo tiene**. Comprobado leyendo su
   `/quanto/portfolio-gallery/`: el enlace del título computa
   `text-decoration: none` y `background-image: none`, y sus únicas reglas de
   pieza son `.quanto-project-thumb:hover img { transform: scale(1.1) }` y
   `transform-origin: left center`. El zoom de la foto ES todo el hover.
   El `span.cdx-pieza-galeria__rotulo` se conserva en el marcado: no estorba y
   evita tocar la plantilla por un cambio de estilo. */

/* Último bloque antes del pie: le toca el relleno inferior del ritmo. */
.cdx-galeria-pagina { padding-bottom: var(--cdx-sec-bottom); }

/* ================================================ FICHA DE CASO DE ÉXITO ====
   Maqueta de `single-caso_exito.php`. Reutiliza casi todo: el patrón partido
   `.cdx-seccion-partida`, el marco con parallax, la parrilla de servicios y la
   franja negra del CTA de la ficha de servicio. Lo propio son la ficha de pares
   dato/valor y las filas de resultados.                                       */

/* ---------- Ficha de pares dato / valor ---------- */
/* Medido en su plantilla de ficha: celdas de 363 en dos columnas con huecos de
   22 en vertical y 40 en horizontal; rótulo a 18/400 con interlineado 26 y
   valor a 24/600 con interletraje -0,24. */
.cdx-ficha {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 22px 40px;
	margin: var(--cdx-espacio-bloque) 0 0;
}
@media (max-width: 575px) { .cdx-ficha { grid-template-columns: 1fr; } }

.cdx-ficha__par { min-width: 0; }
.cdx-ficha__rotulo {
	margin: 0;
	font-size: 18px;
	line-height: 26px;
	font-weight: 400;
	color: var(--cdx-gris-texto);
}
.cdx-ficha__valor {
	margin: 0;
	font-size: 24px;
	line-height: 1.41;
	letter-spacing: -0.24px;
	font-weight: 600;
	color: var(--cdx-negro);
}

/* Enlace al proyecto en vivo, en el hueco donde el diseño pone su botón. */
.cdx-caso-resumen__web { margin-top: 32px; }

/* ---------- Resultados: filas numeradas ---------- */
/* Mismo patrón de fila que el resto de listados del diseño: filete arriba y
   relleno generoso. El número va al peso del rótulo pequeño del diseño (18/600),
   no como una cifra grande: los resultados son FRASES, no datos, así que no se
   usa el bloque de contadores de la portada. */
.cdx-lista-resultados {
	list-style: none;
	margin: 0;
	padding: 0;
	counter-reset: none;
}
.cdx-resultado {
	display: flex;
	align-items: baseline;
	gap: 40px;
	padding: 40px 0;
	border-top: 1px solid var(--cdx-gris-borde);
}
.cdx-resultado:last-child { border-bottom: 1px solid var(--cdx-gris-borde); }
.cdx-resultado__numero {
	flex: none;
	width: 3ch;
	font-size: 18px;
	line-height: 1.444;
	font-weight: 600;
	letter-spacing: -0.18px;
	color: var(--cdx-gris-texto);
	/* Cifras de ancho fijo: Instrument Sans no las trae por defecto y una
	   columna de números desalineada se nota mucho (§5.8). */
	font-variant-numeric: tabular-nums;
}
.cdx-resultado__texto {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
}
@media (max-width: 991px) {
	.cdx-resultado { gap: 20px; padding: 24px 0; }
}

/* ---------- Galería de la ficha (caso de éxito Y proyecto) ---------- */
/* Réplica de la parrilla de su ficha de proyecto, medida sobre la demo a 1600,
   1024 y 375. El patrón se repite cada TRES piezas: dos cuadradas en una fila y
   una apaisada a todo el ancho de esas dos.

   ⚠️ **NO es la parrilla de la página de Proyectos.** Aquella (`.cdx-rejilla-
   galeria`) tiene hueco de 48 desde 992 porque su fila declara `g-4 g-lg-5`;
   esta declara solo `gap: 24px 0` y se queda en 24 en los dos ejes a cualquier
   ancho. Por eso es una parrilla propia y no un modificador: compartir clase
   habría arrastrado el hueco de una a la otra.

   ⚠️ Va **12 px MÁS METIDA que el contenedor por cada lado**, en todos los
   anchos: en el original cada columna lleva `padding: 0 12px` dentro de un
   carril que ya está a 12. Medido a 1600: las fotos van de 24 a 1570 (1546)
   mientras el marco del hero va de 12 a 1582 (1570). Se ve: la galería es más
   estrecha que la foto de arriba, y es así a propósito.

   Medido a 1600: cuadradas **761 × 681,19**, apaisada **1546 × 674,69**.
   A 1024 sigue a dos columnas (449 y 922). A 375 va a una. */
.cdx-galeria-proyecto {
	list-style: none;
	margin: 0;
	padding: 0 12px;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
}
.cdx-galeria-proyecto__celda--ancha { grid-column: 1 / -1; }

/* ⚠️ Proporciones FIJAS, las de SUS fotos (1564×1400 = 1,117 y 3208×1400 =
   2,291). En su demo todas las fotos miden eso, así que a tamaño natural le
   salen filas cuadradas gratis; las nuestras vienen de la migración y van de
   2,005 a 1,000, así que sin fijarlas la fila sale descuadrada (lección 25). */
.cdx-galeria-proyecto__marco {
	display: block;
	overflow: hidden;
	aspect-ratio: 1564 / 1400;
}
.cdx-galeria-proyecto__celda--ancha .cdx-galeria-proyecto__marco { aspect-ratio: 3208 / 1400; }

/* Parallax: sus cuatro fotos llevan `data-speed="0.8"` y **la columna que las
   contiene recorta** (`overflow: hidden`), que es justo lo que hace la pieza 2c.
   Misma mecánica que el marco de ruptura: la foto mide 130 % y se desliza
   dentro; el reposo es el punto medio del recorrido.

   ⚠️ Y **NADA de animación de entrada**: su widget declara
   `"mas-image-animation":"none"`. La galería anterior entraba con el barrido
   lateral de `.cdx-revelado`, que en el original no existe. */
.cdx-galeria-proyecto__img {
	display: block;
	width: 100%;
	height: 130%;
	object-fit: cover;
	object-position: center;
	transform: translate(0, -11.5%);   /* 2D y sin `will-change` (§93): ver `.cdx-ruptura__img` */
}
@media (prefers-reduced-motion: reduce) {
	.cdx-galeria-proyecto__img { height: 100%; transform: none; }
}

/* A una columna desde 767, como el original. ⚠️ La apaisada **conserva su
   proporción**: a 375 mide 327 × 142,7 en su demo. Es tentador igualarla a la
   cuadrada para que no salga tan baja, pero eso ya no sería su parrilla. */
/* ⚠️ Y desde el 2026-10-16 (§115), en móvil TODAS CUADRADAS y del mismo tamaño,
   también la que en escritorio va ancha: el usuario lo quiere así, igual que la
   galería de los casos. (Antes la ancha conservaba su 2,291 y salía a 308×134.) */
@media (max-width: 767px) {
	.cdx-galeria-proyecto { grid-template-columns: minmax(0, 1fr); }
	.cdx-galeria-proyecto .cdx-galeria-proyecto__celda .cdx-galeria-proyecto__marco { aspect-ratio: 1 / 1; }
}

/* ⚠️ ESCRITORIO (usuario, 2026-10-16, §106): la galería del final de proyectos
   y casos va al MISMO ANCHO QUE EL TEXTO DESARROLLADO, no al del contenedor.
   El texto es `.cdx-contenedor.cdx-prosa`: `75ch` centrados con 12 de relleno
   —999 de caja y 975 de texto a 1600—. Aquí lo mismo: `75ch` con el cuerpo del
   texto (el `ch` se mide con la letra del propio elemento, así que se fija
   para que salga idéntico) y el `padding: 0 12px` que ya tenía, centrada.
   Las proporciones de las celdas no cambian: se encogen las fotos, no se
   recortan más. Y de paso ninguna foto de galería se amplía ya por falta de
   píxeles a 1600 (la apaisada pasa de 1546 a 975 de ancho).
   ⚠️ SOLO EN PROYECTOS (`.single-proyecto`). En los casos de éxito el texto va en
   la mitad derecha del bloque partido y la galería centrada quedaba mal
   alineada: el usuario la devolvió al ancho completo del contenedor
   (2026-10-16, §109). */
/* ⚠️ CASOS DE ÉXITO: DOS FILAS CON ANCHOS DISTINTOS (usuario, 2026-10-16, §112;
   supera al mosaico de cuadrados iguales de §111, «demasiado estático»).

   Rejilla de 12 columnas y DOS filas de la misma altura (400 px a 1600, 25vw por
   debajo). Una foto ALTA a la izquierda ocupa las dos filas y el resto se reparte
   con anchos distintos. Medido a 1600 (columna 106,8 + hueco 24):

     6 fotos   [ alta 3 ][  4  ][   5   ]        368 | 499 | 630
               [ alta 3 ][  3 ][  3 ][  3 ]     368 | 368 | 368
     5 fotos   [ alta 3 ][   5   ][  4  ]        368 | 630 | 499
               [ alta 3 ][  4  ][   5   ]        espejo
     4 fotos   [ alta 4 ][   5   ][alta 3]       499 | 630 | 368
               [ alta 4 ][   5   ][alta 3]

   Ninguna celda pasa de 630 px: las fotos de 1000 px no se amplían ni en una
   pantalla normal, y en retina lo justo. La plantilla pone las de más calidad en
   las celdas más grandes (la de 500 px de The Outlet cae en una pequeña).
   Con otro número de fotos: 3 columnas de cuadrados (lo de §111).
   Mismo hueco de 24 y mismo parallax de la parrilla de proyectos. */
.cdx-galeria-proyecto--mosaico { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cdx-galeria-proyecto--mosaico .cdx-galeria-proyecto__marco { aspect-ratio: 1 / 1; }

.cdx-galeria-proyecto--mosaico:is(.cdx-galeria-proyecto--n4, .cdx-galeria-proyecto--n5, .cdx-galeria-proyecto--n6) {
	grid-template-columns: repeat(12, minmax(0, 1fr));
	grid-template-rows: repeat(2, min(25vw, 400px));
}
.cdx-galeria-proyecto--mosaico:is(.cdx-galeria-proyecto--n4, .cdx-galeria-proyecto--n5, .cdx-galeria-proyecto--n6) .cdx-galeria-proyecto__celda { min-height: 0; }
.cdx-galeria-proyecto--mosaico:is(.cdx-galeria-proyecto--n4, .cdx-galeria-proyecto--n5, .cdx-galeria-proyecto--n6) .cdx-galeria-proyecto__marco {
	aspect-ratio: auto;
	height: 100%;
}

.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m1 { grid-column: 1 / span 3;  grid-row: 1 / span 2; }
.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m2 { grid-column: 4 / span 4;  grid-row: 1; }
.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m3 { grid-column: 8 / span 5;  grid-row: 1; }
.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m4 { grid-column: 4 / span 3;  grid-row: 2; }
.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m5 { grid-column: 7 / span 3;  grid-row: 2; }
.cdx-galeria-proyecto--n6 .cdx-galeria-proyecto__celda--m6 { grid-column: 10 / span 3; grid-row: 2; }

.cdx-galeria-proyecto--n5 .cdx-galeria-proyecto__celda--m1 { grid-column: 1 / span 3;  grid-row: 1 / span 2; }
.cdx-galeria-proyecto--n5 .cdx-galeria-proyecto__celda--m2 { grid-column: 4 / span 5;  grid-row: 1; }
.cdx-galeria-proyecto--n5 .cdx-galeria-proyecto__celda--m3 { grid-column: 9 / span 4;  grid-row: 1; }
.cdx-galeria-proyecto--n5 .cdx-galeria-proyecto__celda--m4 { grid-column: 4 / span 4;  grid-row: 2; }
.cdx-galeria-proyecto--n5 .cdx-galeria-proyecto__celda--m5 { grid-column: 8 / span 5;  grid-row: 2; }

.cdx-galeria-proyecto--n4 .cdx-galeria-proyecto__celda--m1 { grid-column: 1 / span 4;  grid-row: 1 / span 2; }
.cdx-galeria-proyecto--n4 .cdx-galeria-proyecto__celda--m2 { grid-column: 5 / span 5;  grid-row: 1; }
.cdx-galeria-proyecto--n4 .cdx-galeria-proyecto__celda--m3 { grid-column: 10 / span 3; grid-row: 1 / span 2; }
.cdx-galeria-proyecto--n4 .cdx-galeria-proyecto__celda--m4 { grid-column: 5 / span 5;  grid-row: 2; }

/* Móvil: UNA SOLA COLUMNA, una foto debajo de otra (usuario, 2026-10-16, §114;
   antes 2 columnas). Sin posiciones de la rejilla de escritorio y con la misma
   proporción y el mismo hueco que la galería de proyectos en móvil (CUADRADAS
   desde §115, 24 px), para que las dos fichas se vean igual en el teléfono. */
@media (max-width: 767px) {
	.cdx-galeria-proyecto--mosaico,
	.cdx-galeria-proyecto--mosaico:is(.cdx-galeria-proyecto--n4, .cdx-galeria-proyecto--n5, .cdx-galeria-proyecto--n6) {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: none;
		grid-auto-rows: auto;
		gap: 24px;
	}
	.cdx-galeria-proyecto--mosaico .cdx-galeria-proyecto__celda[class*="--m"] { grid-column: auto; grid-row: auto; }
	.cdx-galeria-proyecto--mosaico .cdx-galeria-proyecto__celda .cdx-galeria-proyecto__marco {
		aspect-ratio: 1 / 1;
		height: auto;
	}
}

@media (min-width: 1200px) {
	.single-proyecto .cdx-caso-galeria .cdx-galeria-proyecto {
		max-width: 75ch;
		margin-inline: auto;
		font-size: var(--cdx-fs-body);
	}
}

/* ---------- Sub-bloques dentro de «El proyecto» ---------- */
/* Soluciones y Resultados ya no son secciones sueltas: viven en la columna
   DERECHA del bloque partido, debajo del texto y de la ficha de datos, cada uno
   con su rótulo encima.

   El rótulo va a **40**, la mitad justa del titular de sección (80): destacado,
   pero claramente por debajo del «El proyecto» que tiene al lado. No es un
   tamaño inventado — es el escalón que el propio H2 usa por debajo de 767 —, y
   baja 40/36/32/28 para no acercarse nunca al cuerpo de texto (20). */
.cdx-detalles__sub { margin: 0 0 20px; font-size: 40px; line-height: 1.15; letter-spacing: -.6px; }
.cdx-detalles__parte { margin-top: 60px; }
@media (max-width: 1199px) { .cdx-detalles__sub { font-size: 36px; } }
@media (max-width: 991px)  { .cdx-detalles__sub { font-size: 32px; } .cdx-detalles__parte { margin-top: 48px; } }
@media (max-width: 767px)  { .cdx-detalles__sub { font-size: 28px; margin-bottom: 16px; } .cdx-detalles__parte { margin-top: 40px; } }
/* Cierre tras las partes (§131): mismo hueco que entre ellas. */
.cdx-detalles__cierre { margin-top: 60px; }
@media (max-width: 991px) { .cdx-detalles__cierre { margin-top: 48px; } }
@media (max-width: 767px) { .cdx-detalles__cierre { margin-top: 40px; } }

/* Dentro de la columna, las filas de resultados aprietan: ya no disponen del
   ancho completo del contenedor, sino de los 761 de la mitad derecha. */
.cdx-detalles__parte .cdx-resultado { gap: 24px; padding: 28px 0; }
.cdx-detalles__parte .cdx-resultado__texto { font-size: var(--cdx-fs-h4); line-height: 1.3; letter-spacing: -.01em; }

/* ---------- Último bloque contra el pie ---------- */
/* En estas fichas el último bloque no es siempre el mismo (depende de qué campos
   estén rellenos), así que el relleno inferior del ritmo se le da al que quede
   último, acotado a las dos plantillas por la clase del `body`. Así no se toca
   ninguna otra página.
   ⚠️ `single-proyecto` faltaba: desde que las dos fichas comparten parte (§28.1)
   la de proyecto podía quedarse pegada al pie igual que la de caso. */
/* Retirada: la hace ahora la regla ÚNICA de `base.css` (caso 3 del ritmo),
   que vale para TODAS las páginas y no solo para estas dos fichas. */

/* ---------- «Qué más podemos hacer»: fila anclada ---------- */
/* El bloque «We help you to build digital business» de `/design-studio/`:
   banda negra, titular blanco y una fila de cajas oscuras que se recorre en
   HORIZONTAL mientras la página baja. Medido allí a 1600. */
/* ⚠️ La sección NO puede llevar `overflow: hidden`: rompe el `position:
   sticky` del carril —cualquier ancestro con overflow distinto de `visible`
   lo desactiva— y la fila se quedaba quieta. El recorte horizontal ya lo hace
   el propio carril. */
.cdx-servicio-que-mas {
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
}
.cdx-servicio-que-mas .cdx-titulo-seccion { color: var(--cdx-blanco); }

/* ---------- El hueco entre el titular y la fila (§65.1) ---------- */
/* El aire que deja la regla global de `.cdx-seccion-cabecera` —60 px— es
   demasiado AQUÍ, y solo aquí, porque debajo no empieza el contenido: empieza
   un carril de alto de ventana con las cajas centradas, que ya trae su propio
   vacío. Se baja a 24 **con el selector acotado a este bloque**: la regla
   global la comparten media docena de secciones del sitio y moverla las movería
   todas.
   ⚠️ Solo de 768 para arriba: en móvil el carril no existe —la fila es una
   parrilla normal— y ahí los 45 px del escalón son el ritmo correcto. */
@media (min-width: 768px) {
	.cdx-servicio-que-mas .cdx-seccion-cabecera { margin-bottom: 24px; }
}

/* Sin JS y por debajo de 1200 es una PARRILLA, como en el original. */
.cdx-proceso__pista {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 40px;
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (max-width: 767px) { .cdx-proceso__pista { grid-template-columns: 1fr; gap: 20px; } }

/* ⚠️⚠️ DE 1200 PARA ARRIBA: FILA CORRIDA Y **ANCLADA** (§68).
   -------------------------------------------------------------------------
   El anclaje es lo importante de este bloque y **está puesto**: la fila se
   queda clavada y las cajas se desplazan en horizontal mientras la página baja.
   El alto que hay que recorrer lo pone el JS en `--cdx-proceso-alto`
   (pieza 9), igual que siempre.

   💡 **LO QUE CAMBIA ES DÓNDE VIVE EL NEGRO.** Antes lo pintaba la SECCIÓN, que
   mide `carril + recorrido`; como el recorrido son ~489 px de pista de scroll,
   el negro se comía toda la pantalla por debajo de las cajas y el hueco hasta
   el final del bloque iba de 619 a 130 px según bajabas.

   Ahora el negro es **solo la banda anclada**, que tiene **alto fijo**:

     .cdx-servicio-que-mas   negro  → cubre el relleno de arriba y el titular
     .cdx-proceso            BLANCO → la pista de scroll deja de ser negra
     .cdx-proceso__carril    negro  → la banda de las cajas, de alto fijo

   Resultado: mientras las cajas están ancladas se ve la banda negra y, justo
   debajo, **el corte al blanco**. El borde inferior del negro **no se mueve**
   —está anclado con la banda— y el hueco bajo las cajas es siempre el mismo.

   ⚠️ **Esto invalida el motivo por el que el carril era `100vh`.** El comentario
   viejo decía que con la banda corta «el borde inferior del negro entraba en
   pantalla a mitad del recorrido y subía hacia las cajas». Era cierto **cuando
   el negro lo pintaba la sección**: el borde estaba al final del recorrido y
   subía. Ahora el borde es el de la banda, que está anclada, así que se queda
   quieto. El corte es intencionado.

   💡 **El aire de arriba va en `top`, no en relleno.** Un `top` de anclaje no
   ocupa nada mientras el carril no está anclado, así que deja sitio para la
   cabecera pegajosa sin separar el titular de las cajas (lección 103).        */
@media (min-width: 1200px) {
	/* La caja alta que da el recorrido. En BLANCO: es pista de scroll, no
	   contenido, y no tiene por qué ser negra. */
	.cdx-proceso[data-cdx-listo] {
		height: var(--cdx-proceso-alto, auto);
		background: var(--cdx-color-fondo);
	}

	/* ⚠️ Centrado con FLEX EN COLUMNA, no con `grid` + `align-content`. Con
	   rejilla, el `.cdx-contenedor` de dentro deja de encoger —la columna se
	   dimensiona a su `max-width` de 1604— y se salía 19 px del carril, con lo
	   que la fila perdía la alineación con la retícula de la página. */
	.cdx-proceso[data-cdx-listo] .cdx-proceso__carril {
		position: sticky;
		top: var(--cdx-cabecera-alto);
		/* ALTO FIJO: 40 de aire + 492 de caja + 120 de aire. No depende de la
		   ventana ni del contenido de alrededor.
		   ⚠️ El aire de abajo es el DOBLE que el de arriba, y es a propósito: el
		   de arriba solo tiene que separar las cajas de la cabecera, y el de
		   abajo es el que da peso a la banda contra el corte al blanco. */
		padding-top: 40px;
		padding-bottom: 120px;
		background: var(--cdx-negro);
		display: flex;
		flex-direction: column;
		overflow: hidden;
	}

	/* La sección deja de poner aire por debajo: el último píxel negro lo pone
	   la banda, y lo que va detrás es ya el blanco de la pista. */
	.cdx-servicio-que-mas:has(.cdx-proceso[data-cdx-listo]) { padding-bottom: 0; }

	/* La fila, corrida. Los 110 px de hueco y los 430 de caja son los medidos
	   en el original (§20.5) y no se tocan. */
	/* ⚠️ `data-cdx-fila` (2026-10-07): la fila CABE ENTERA y no hay nada que
	   recorrer —3 cajas o menos a partir de ~1500—. Antes eso devolvía el bloque
	   a la parrilla de dos columnas y las cajas salían de ~760 de ancho; el
	   usuario pidió que midan EXACTAMENTE lo mismo en todos los servicios. Ahora
	   sigue en fila con sus 430, solo que sin anclaje ni desplazamiento. */
	.cdx-proceso[data-cdx-listo] .cdx-proceso__pista,
	.cdx-proceso[data-cdx-fila] .cdx-proceso__pista {
		display: flex;
		flex-wrap: nowrap;
		gap: 110px;
		/* Sin `will-change` (§94): sus tarjetas llevan foto de fondo, ver §93. */
	}
	.cdx-proceso[data-cdx-listo] .cdx-proceso__pieza,
	.cdx-proceso[data-cdx-fila] .cdx-proceso__pieza { flex: 0 0 430px; }
}
@media (min-width: 1200px) and (max-width: 1399px) {
	.cdx-proceso[data-cdx-listo] .cdx-proceso__pista,
	.cdx-proceso[data-cdx-fila] .cdx-proceso__pista { gap: 80px; }
}

.cdx-proceso__caja {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 208px;
	height: 100%;
	min-height: 492px;
	padding: 54px 48px;
	background: #191919;
	color: var(--cdx-blanco);
	text-decoration: none;
	transition: background-color .5s ease-in-out, color .5s ease-in-out;
}
@media (max-width: 991px) { .cdx-proceso__caja { padding: 40px 30px; gap: 100px; min-height: 0; } }
@media (max-width: 767px) { .cdx-proceso__caja { padding: 30px 20px; } }

/* LA FOTO ES EL FONDO DE LA CAJA. La caja se queda EXACTAMENTE como la del
   diseño de referencia —430×492, que ya es un formato vertical— y la foto la
   rellena entera recortada a esa proporción (0,874).

   Antes ocupaba una banda que crecía con `flex: 1`, y por eso las cuatro
   fotos salían a alturas distintas: la banda se quedaba con lo que sobraba, y
   sobra menos cuando el título ocupa dos líneas que cuando ocupa una (medido:
   234 en tres cards y 272 en la del título corto). Como fondo, las cuatro son
   idénticas por construcción.

   El recorte se come los lados: los originales son de 1238×890 (1,39 apaisado)
   y la caja pide 0,874, así que se pierde el 37 % del ancho. Es lo que se
   pidió: encuadrar a vertical aunque se recorte. */
.cdx-proceso__caja--foto {
	position: relative;
	overflow: hidden;
	background: var(--cdx-negro);
	/* ⚠️ La proporción se declara, no se hereda del contenido. Con la foto
	   absoluta, la caja se queda sin nada que le dé alto: por debajo de 992,
	   donde el `min-height` de 492 se apaga, se hundía a 351×216 —apaisada, o
	   sea justo lo contrario de lo que se busca—. Con la proporción de la caja
	   del diseño de referencia (430/492) el formato vertical se mantiene en
	   todos los anchos. */
	aspect-ratio: 430 / 492;
}
.cdx-proceso__marco {
	position: absolute;
	inset: 0;
	margin: 0;
	display: block;
	overflow: hidden;
}
/* Velo sobre la foto: sin él, el número y el título en blanco dependen de lo
   claro que sea cada imagen. Al pasar se levanta y la foto se ve mejor.

   Era un velo PLANO al 55 % y tapaba demasiado. Ahora es un degradado que
   aprieta solo donde hay texto —arriba el número, abajo el título— y se abre
   en el centro, que es justo donde está el motivo de la foto: la imagen se ve
   bastante más y el texto no pierde contraste. */
.cdx-proceso__marco::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(15, 15, 15, .58) 0%,
		rgba(15, 15, 15, .22) 34%,
		rgba(15, 15, 15, .22) 58%,
		rgba(15, 15, 15, .62) 100%
	);
	transition: opacity .5s ease-in-out;
}
.cdx-proceso__imagen {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	/* El zoom crece desde el borde izquierdo, como el del carrusel y el de su
	   `quanto-project-thumb`. */
	transform-origin: left center;
	transition: transform .5s cubic-bezier(.37, .08, .02, .93);
}
/* El número y el título van POR ENCIMA de la foto. */
.cdx-proceso__caja--foto .cdx-proceso__numero,
.cdx-proceso__caja--foto .cdx-proceso__titulo {
	position: relative;
	z-index: 1;
	color: var(--cdx-blanco);
}
a.cdx-proceso__caja--foto:hover .cdx-proceso__imagen { transform: scale(1.06); }
a.cdx-proceso__caja--foto:hover .cdx-proceso__marco::after { opacity: .55; }
@media (prefers-reduced-motion: reduce) {
	.cdx-proceso__imagen { transition: none; }
	a.cdx-proceso__caja--foto:hover .cdx-proceso__imagen { transform: none; }
}
/* Al pasar, la caja se vuelve del revés: blanca con el texto en negro, que es
   lo que hace la suya (allí con un telón de tiras animadas; aquí con una
   transición, que da el mismo resultado sin cien nodos por caja).
   ⚠️ Solo en las cajas SIN foto: sobre una foto a sangre el vuelco a blanco no
   se vería. Las que llevan foto tienen su propio efecto, más abajo. */
a.cdx-proceso__caja:not(.cdx-proceso__caja--foto):hover { background: var(--cdx-blanco); color: var(--cdx-negro); }
a.cdx-proceso__caja:not(.cdx-proceso__caja--foto):hover .cdx-proceso__titulo { color: var(--cdx-negro); }

/* ---------- Cajas CON enlace: «Ver más» y zoom (2026-10-07) ----------
   Encargo del usuario: no se distinguía qué cajas llevan a algún sitio. Dos
   señales, una en reposo y otra al pasar:

   · En reposo, el «Ver más» (píldora clara con la flecha del sistema). Las
     cajas sin enlace no lo llevan, y esa es la diferencia que se ve de un
     vistazo.
   · Al pasar, ZOOM, el de los listados de proyectos: `scale(1.04)` con
     `--cdx-transicion-lenta`, los mismos valores que `.cdx-proyecto:hover`.
     En las cajas con FOTO ya se ampliaba la foto dentro de su marco —que es
     justo lo que hace la ficha de proyecto— y eso no se toca. En las cajas SIN
     foto no hay nada dentro que ampliar, así que crece la caja entera, junto
     con el vuelco a blanco que ya tenía.

   ⚠️ El hueco mínimo entre número y pie baja de 208 a 120 SOLO en las cajas con
   enlace y solo donde rige el alto de 492 (≥992): con el botón debajo del
   título, 208 de mínimo empujaba la caja a ~498 en los títulos de dos líneas y
   descuadraba la banda anclada, que tiene el alto fijo (40 + 492 + 120). Es un
   MÍNIMO: con `space-between` la caja sigue midiendo 492 y el número sigue
   arriba del todo; lo único que cambia es que ya no se desborda. */
.cdx-proceso__pie {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 24px;
}
.cdx-proceso__caja--foto .cdx-proceso__pie {
	position: relative;
	z-index: 1;
}
@media (min-width: 992px) {
	a.cdx-proceso__caja { gap: 120px; }
}
a.cdx-proceso__caja:not(.cdx-proceso__caja--foto) {
	transition:
		background-color .5s ease-in-out,
		color .5s ease-in-out,
		transform var(--cdx-transicion-lenta);
}
a.cdx-proceso__caja:not(.cdx-proceso__caja--foto):hover { transform: scale(1.04); }
/* Sobre la caja ya vuelta a blanco, la píldora blanca desaparecería: se
   invierte a negra, que es el botón normal del sitio. */
.cdx-proceso__mas { transition: background var(--cdx-transicion), color var(--cdx-transicion); }
a.cdx-proceso__caja:not(.cdx-proceso__caja--foto):hover .cdx-proceso__mas {
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
}
@media (prefers-reduced-motion: reduce) {
	a.cdx-proceso__caja:not(.cdx-proceso__caja--foto):hover { transform: none; }
}

.cdx-proceso__numero {
	display: block;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: -.18px;
	color: inherit;
}
.cdx-proceso__titulo {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	color: var(--cdx-blanco);
	transition: color .5s ease-in-out;
}

/* ---------- Carrusel horizontal (casos de éxito) ---------- */
/* El `portfolio-slider` de referencia: 2,3 piezas a la vista con 40 de hueco.
   De ahí salen sus 667 de ancho a 1600: (1585 − 1,3×40) / 2,3 = 666,5.

   ⚠️ LOS ESCALONES YA NO SE DEDUCEN: están leídos de la CONFIGURACIÓN REAL de
   su Swiper (`slider.swiper.params`), que es lo que se debería haber hecho la
   primera vez. Sus `breakpoints` literales:

       ≥1200 → 2,3 piezas · hueco 40
       ≥992  → 2,0        · hueco 30
       ≥768  → 1,5        · hueco 25
       ≥576  → 1,3        · hueco 20

   (Teníamos 2,3 · 1,6 · 1,15, que eran inventados.) Por debajo de 576 su
   configuración se queda sin `breakpoint` que aplicar y vuelve a los valores
   raíz —2,3 piezas en un móvil—, que es claramente un descuido suyo: aquí se
   prolonga el escalón de 576 hacia abajo. */
.cdx-carrusel { --cdx-carrusel-vista: 2.3; --cdx-carrusel-hueco: 40px; }
@media (max-width: 1199px) { .cdx-carrusel { --cdx-carrusel-vista: 2;   --cdx-carrusel-hueco: 30px; } }
@media (max-width: 991px)  { .cdx-carrusel { --cdx-carrusel-vista: 1.5; --cdx-carrusel-hueco: 25px; } }
@media (max-width: 767px)  { .cdx-carrusel { --cdx-carrusel-vista: 1.3; --cdx-carrusel-hueco: 20px; } }

.cdx-carrusel__pista {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--cdx-carrusel-hueco);
	list-style: none;
	margin: 0;
	padding: 0;
	transition: transform .8s cubic-bezier(.37, .08, .02, .93);
}
.cdx-carrusel__pieza {
	flex: 0 0 calc(
		(100% - (var(--cdx-carrusel-vista) - 1) * var(--cdx-carrusel-hueco)) / var(--cdx-carrusel-vista)
	);
}
/* Sin JS no se recorta: se ve la fila entera y no hay botones que no harían
   nada. El JS lo declara listo y entonces sí. */
.cdx-carrusel__ventana { overflow: visible; }
.cdx-carrusel[data-cdx-listo] .cdx-carrusel__ventana { overflow: hidden; }
/* Navegación, leída literal de su hoja:
     .quanto-project__slider-navigation → `d-flex justify-content-center
       align-items-center gap-3` (gap-3 de Bootstrap = 16px)
     .row-padding-top { padding-top: 60px }  · 45 por debajo de 1200
     .next-btn/.prev-btn { display: grid; place-content: center;
       width: 70px; height: 70px; border-radius: 100%;
       background: var(--color-2) }         · 50×50 por debajo de 992
   `--color-2` es #f5f5f5, o sea nuestro `--cdx-gris-fondo`. */
.cdx-carrusel__navegacion { display: none; }
.cdx-carrusel[data-cdx-listo] .cdx-carrusel__navegacion {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
	padding-top: 60px;
}
@media (max-width: 1199px) { .cdx-carrusel[data-cdx-listo] .cdx-carrusel__navegacion { padding-top: 45px; } }
.cdx-carrusel__boton {
	appearance: none;
	width: 70px; height: 70px;
	display: grid; place-content: center;
	padding: 0;
	/* SIN borde: el suyo no lleva ninguno. */
	border: 0;
	border-radius: 100%;
	background: var(--cdx-gris-fondo);
	color: var(--cdx-negro);
	cursor: pointer;
	transition: background-color .3s, color .3s;
}
/* Desviación deliberada: el suyo NO tiene estado al pasar. Se le deja el
   vuelco a negro porque un botón sin respuesta al ratón se siente roto, y el
   estado en reposo —que es lo que se ve— es idéntico al suyo. */
.cdx-carrusel__boton:hover { background: var(--cdx-negro); color: var(--cdx-blanco); }
@media (max-width: 991px) { .cdx-carrusel__boton { width: 50px; height: 50px; } }

/* Flecha recta, no chevron: el suyo usa `fa-arrow-left`/`fa-arrow-right` en
   este carrusel (el chevron es el del carrusel de TESTIMONIOS, que sí lleva
   `fa-angle-left`). Medida allí: 18×20. */
.cdx-flecha-recta { display: block; width: 20px; height: 20px; }
@media (max-width: 991px) { .cdx-flecha-recta { width: 17px; height: 17px; } }

/* ============================================== PÁGINA DE EQUIPO ====
   Plantilla `page-equipo.php`. Reutiliza casi todo —hero de página, marco de
   foto con parallax, patrón partido, rejilla de equipo, carrusel de
   testimonios y franja negra de cierre—; lo único propio es la galería de
   ambiente.                                                                */

/* La rejilla de equipo del original NO tiene hover, y el usuario descartó
   además el zoom que teníamos: aquí las fotos se quedan quietas. */
.cdx-rejilla-equipo--quieta .cdx-miembro__foto img { transition: none; }
.cdx-rejilla-equipo--quieta .cdx-miembro:hover .cdx-miembro__foto img { transform: none; }

/* ---------- Galería de ambiente ---------- */
/* El bloque de fotos de la plantilla de empleo, medido a 1600: CUATRO columnas
   a sangre de 381 con 24 de hueco (4×381 + 3×24 = 1596, el ancho de la
   ventana), las columnas PARES bajadas 160 px, y la sección recortando el
   desbordamiento, porque cada foto deriva en vertical con el desplazamiento.
   Las fotos van a su proporción (460×660 allí, 0,698). */
.cdx-ambiente { overflow: hidden; }
.cdx-ambiente__rejilla {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 24px;
	list-style: none;
	margin: 0;
	padding: 0;
}
/* ⚠️ **En móvil, rejilla EXACTA de 2×2: ni escalonado ni sangre.**
   El escalonado es de escritorio, donde hay cuatro columnas y las pares bajan
   160px. A dos columnas deja de ser un ritmo y pasa a ser un estorbo: como las
   filas de un grid se dimensionan por el elemento más alto, el margen superior
   de las celdas pares **engorda la fila entera**, así que a los 16 de hueco se
   les sumaban 40 y las dos filas quedaban muy separadas. Se pone a 0.
   Y el bloque deja de ir a sangre: se le da el **mismo margen lateral que el
   resto del sitio** (el gutter de .cdx-contenedor), con el hueco igualado a ese
   valor para que la separación sea la misma por los cuatro lados. */
@media (max-width: 767px) {
	.cdx-ambiente__rejilla {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--cdx-margen-lateral);
		padding-inline: var(--cdx-margen-lateral);
	}
}
/* Las columnas 2 y 4 bajan, que es lo que da el escalonado. */
.cdx-ambiente__celda:nth-child(even) { margin-top: 160px; }
@media (max-width: 991px) { .cdx-ambiente__celda:nth-child(even) { margin-top: 80px; } }
/* ⚠ Y el reinicio va AQUÍ, DESPUÉS del escalón de 991, no arriba con el resto
   de reglas de móvil: los tres selectores tienen la misma especificidad, así que
   manda el último del fichero. Puesto antes, el `80px` de ≤991 volvía a ganar a
   375 —comprobado midiendo: seguía dando 80— y el escalonado no se quitaba. */
@media (max-width: 767px) { .cdx-ambiente__celda:nth-child(even) { margin-top: 0; } }

.cdx-ambiente__marco {
	display: block;
	margin: 0;
	overflow: hidden;
	aspect-ratio: 460 / 660;
	background: var(--cdx-gris-suave);
	/* Sin `will-change` (§93): ver `.cdx-ruptura__img`. */
}
.cdx-ambiente__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* ================================================== BLOG: LISTADO ========
   Réplica de `/quanto/blog-grid/`, medida a 1600 (ancho útil 1594).
   La parrilla y la tarjeta NO se redefinen aquí: son `.cdx-rejilla-entradas` y
   `.cdx-tarjeta-entrada`, que ya estaban medidas contra esta misma demo para el
   bloque de blog de la ficha de servicio. Aquí solo va lo que falta. */
.cdx-blog-listado { padding-bottom: var(--cdx-sec-bottom); }

/* ---------- Paginación ---------- */
/* Su `.blog-pagination`, medida a 1600. ⚠️ Va **a la DERECHA**
   (`justify-content: end`), no centrada, y los números son **círculos de 70 con
   borde**, no botones planos:
     - número: 70×70, borde 1px #c5c5c5, radio 50 %, 18/600;
     - el actual: fondo negro y texto blanco, conservando el borde;
     - «Anterior»/«Siguiente» NO son círculos: son TEXTO con una flecha al lado,
       sin borde ni fondo, con 8 de hueco entre icono y palabra;
     - hueco de 12 entre piezas.
   El orden es Anterior · números · Siguiente, todo pegado a la derecha. */
.cdx-paginacion { margin-top: 80px; }
@media (max-width: 991px) { .cdx-paginacion { margin-top: 56px; } }

/* Texto SEO al pie de la categoría (§82.2): bajo el paginador, con el mismo
   hueco que lo separa a él de la parrilla, y a la medida de lectura del texto
   SEO de la portada (860, §71.3), centrado. */
.cdx-blog-listado__seo { max-width: 860px; margin: 80px auto 0; }
.cdx-blog-listado__seo > :first-child { margin-top: 0; }
@media (max-width: 991px) { .cdx-blog-listado__seo { margin-top: 56px; } }
.cdx-paginacion__lista {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 12px;
}
.cdx-paginacion__item a,
.cdx-paginacion__item span {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 70px;
	height: 70px;
	border: 1px solid var(--cdx-gris-borde);
	border-radius: 50%;
	font-size: var(--cdx-fs-small);
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1;
	color: var(--cdx-negro);
	text-decoration: none;
	/* Cifras de ancho fijo: Instrument Sans no las trae por defecto y una fila
	   de números de distinta anchura baila (§5.8). */
	font-variant-numeric: tabular-nums;
	transition: background var(--cdx-transicion), color var(--cdx-transicion);
}
.cdx-paginacion__item a:hover { background: var(--cdx-gris-fondo); }
.cdx-paginacion__item .current { background: var(--cdx-negro); color: var(--cdx-blanco); }

/* «Anterior»: texto con flecha, sin caja, como el original. */
.cdx-paginacion__item .prev {
	width: auto;
	height: 30px;
	gap: 8px;
	border: 0;
	border-radius: 0;
	background: none;
}
.cdx-paginacion__item .prev:hover { background: none; opacity: .6; }
.cdx-paginacion__item .cdx-flecha-recta { width: 20px; height: 20px; flex: none; }

/* ⚠️ «Siguiente» se aparta del original: allí es texto + flecha, pero la palabra
   entera no cabía bien al final de la fila. Se queda en el círculo de 70 con
   una flecha FINA dentro y nada de texto; el nombre sigue estando para el
   lector de pantalla, en `.visualmente-oculto`. */
.cdx-paginacion__item .next .cdx-flecha-recta { width: 26px; height: 26px; }

/* Los puntos suspensivos de `paginate_links()` no son un botón: ni caja ni
   borde, solo el hueco. */
.cdx-paginacion__item .dots { width: 24px; border: 0; }

@media (max-width: 575px) {
	.cdx-paginacion__lista { justify-content: center; gap: 8px; }
	.cdx-paginacion__item a,
	.cdx-paginacion__item span { width: 52px; height: 52px; }
	/* ⚠️ «Anterior» y «Siguiente» iban a 30 de alto: por debajo de los 44 que
	   pide WCAG 2.5.5, y son las dianas de navegación del listado. Se les da el
	   mínimo sin tocar el ancho, que es automático. */
	.cdx-paginacion__item .prev,
	.cdx-paginacion__item .next {
		width: auto;
		min-width: 44px;
		height: auto;
		min-height: 44px;
		justify-content: center;
	}
}

/* ================================================== BLOG: LA ENTRADA =====
   Réplica de su «blog details», medida a 1600. Dos columnas de texto distintas
   y las dos CENTRADAS dentro del contenedor de 1570:
     - el titular y los datos, a 1171,5 (74,6 %);
     - el cuerpo, a 1038,7 (66,2 %).
   Se declaran en % para que los dos escalones bajen solos. */
/* ⚠️ La COLUMNA va centrada, pero el TEXTO va a la IZQUIERDA. Medido en su
   plantilla: el titular arranca en 211,3 —o sea (1570 − 1171,5)/2 dentro del
   contenedor— y su `text-align` es `start`. Centrar también el texto, que es lo
   que había, no era su diseño. */
.cdx-entrada-cabecera__caja { width: 74.6%; margin-inline: auto; }
/* ⚠️ `max-width: none` es NECESARIO, no un descuido: la caja lleva también
   `.cdx-prosa`, que capa el texto largo a 75ch (unos 808 px a cuerpo 20). Sin
   anularlo la columna se quedaba en 808 en vez de los 1038,7 del original, o
   sea 230 px más estrecha. Se replica la medida suya; si algún día se prefiere
   la legibilidad del sistema, se quita esta línea y vuelve a 75ch. */
.cdx-entrada-cuerpo__caja { width: 66.2%; max-width: none; margin-inline: auto; }
@media (max-width: 1199px) {
	.cdx-entrada-cabecera__caja { width: 86%; }
	.cdx-entrada-cuerpo__caja { width: 82%; }
}
@media (max-width: 991px) {
	.cdx-entrada-cabecera__caja,
	.cdx-entrada-cuerpo__caja { width: 100%; }
}

/* ⚠️ El titular va a 100, NO a los 140 del H1 del sistema. Es el tamaño que usa
   su «blog details» (su H2 a 100/600), y además es lo que aguantan nuestros
   titulares, que son MUCHO más largos que los suyos: son frases completas con
   la ciudad dentro («Marketing online Alicante: …»). Misma desviación
   deliberada que el titular del CTA de la ficha de servicio (§26.3). */
/* Medido en su plantilla: 100/600, interlínea **110px** (1,1) e interletraje
   **normal** — no lleva el negativo de los titulares del sistema. */
.cdx-entrada__titulo {
	margin: 0;
	font-size: 100px;
	line-height: 1.1;
	letter-spacing: normal;
	text-wrap: balance;
}
@media (max-width: 1399px) { .cdx-entrada__titulo { font-size: 80px; } }
@media (max-width: 1199px) { .cdx-entrada__titulo { font-size: 64px; } }
@media (max-width: 991px)  { .cdx-entrada__titulo { font-size: 52px; line-height: 1.08; } }
@media (max-width: 767px)  { .cdx-entrada__titulo { font-size: 40px; } }

/* Subtítulo de la ficha de problema/solución (§74.5), campo `subtitulo` —
   opcional, solo esa ficha lo usa. Reutiliza `--cdx-fs-h3`, que ya escalona
   solo en cada corte de `tokens.css`, en vez de declarar sus propios pasos.
   ⚠️ **En `--cdx-negro`, el mismo que el h1** (corregido en §76.2: salía en
   `--cdx-gris-texto` y el usuario lo quería igualado a los títulos, no como
   texto secundario). */
.cdx-entrada__subtitulo {
	margin: 20px 0 0;
	font-size: var(--cdx-fs-h3);
	line-height: 1.4;
	color: var(--cdx-negro);
	font-weight: 400;
}

/* La línea de datos: fecha · categoría · autor. Medida en su `.meta-info`:
   20/400 en NEGRO —no en gris—, alineada a la izquierda como el titular, y las
   piezas separadas SOLO por 24 px de relleno a la derecha.
   ⚠️ **Sin separadores**: comprobado, su `::after` es `none`. El punto medio que
   había aquí antes no existe en el original. */
.cdx-entrada__datos {
	list-style: none;
	margin: 24px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	font-size: var(--cdx-fs-body);
	line-height: 1;
	color: var(--cdx-negro);
}
/* Los FILETES entre piezas, medidos en su `.meta-info`: cada `li` menos el
   último lleva `border-right: 1px solid #c5c5c5` y 24 de relleno a la derecha,
   y cada uno menos el primero lleva 24 de margen a la izquierda. O sea: la
   línea queda a 24 del texto por los dos lados. */
.cdx-entrada__datos li:not(:last-child) {
	padding-right: 24px;
	border-right: 1px solid var(--cdx-gris-borde);
}
.cdx-entrada__datos li + li { margin-left: 24px; }
/* Al envolver en móvil, el filete de la pieza que queda al final de una línea
   sobra: se queda colgando en el aire. */
@media (max-width: 767px) {
	.cdx-entrada__datos li:not(:last-child) { padding-right: 12px; }
	.cdx-entrada__datos li + li { margin-left: 12px; }
}
.cdx-entrada__datos a { color: inherit; text-decoration: none; }
.cdx-entrada__datos a:hover { text-decoration: underline; }
@media (max-width: 767px) { .cdx-entrada__datos { margin-top: 20px; font-size: var(--cdx-fs-small); row-gap: 8px; } }

/* ---------- Foto destacada ---------- */
/* A TODO el contenedor y a 2:1, la suya (1570 × 788 = 1,99), que es además la
   proporción de la miniatura `cdx-cabecera` (1600×800): al regenerar miniaturas
   entra sin recorte. Lleva el parallax de la pieza 2c, como el resto de marcos
   grandes del sitio. */
.cdx-entrada-foto { margin-top: 60px; }
.cdx-entrada-foto__marco { overflow: hidden; aspect-ratio: 1600 / 800; }
.cdx-entrada-foto__img {
	display: block;
	width: 100%;
	height: 130%;
	object-fit: cover;
	object-position: center;
	transform: translate(0, -11.5%);   /* 2D y sin `will-change` (§93): ver `.cdx-ruptura__img` */
}
@media (prefers-reduced-motion: reduce) {
	.cdx-entrada-foto__img { height: 100%; transform: none; }
}
@media (max-width: 767px) { .cdx-entrada-foto { margin-top: 36px; } }

/* ---------- Etiquetas ---------- */
/* Su lista del final de la entrada, en píldoras. Se acota al mismo ancho que el
   cuerpo para que no se salgan de la columna de lectura. */
.cdx-entrada__etiquetas {
	list-style: none;
	margin: 60px auto 0;
	padding: 0;
	width: 66.2%;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}
@media (max-width: 1199px) { .cdx-entrada__etiquetas { width: 82%; } }
@media (max-width: 991px)  { .cdx-entrada__etiquetas { width: 100%; margin-top: 40px; } }
/* Medido en su `.blog-tags`: píldora RELLENA de gris claro, **sin borde**,
   18px, relleno 14/24 y radio 40. No es la píldora de borde fino que llevaba
   antes: esa es la que el usuario ha elegido para el carril de categorías del
   listado, que es pieza nuestra. Aquí manda el original. */
.cdx-entrada__etiquetas a {
	display: block;
	padding: 14px 24px;
	border-radius: 40px;
	background: var(--cdx-gris-fondo);
	font-size: var(--cdx-fs-small);
	line-height: 1.44;
	color: var(--cdx-negro);
	text-decoration: none;
	transition: background var(--cdx-transicion), color var(--cdx-transicion);
}
.cdx-entrada__etiquetas a:hover {
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
}

/* ---------- «Seguir leyendo» ---------- */
/* Sobre la banda gris del sistema, como el bloque de blog de la ficha de
   servicio: son la misma pieza y conviene que se lean igual. */
.cdx-entrada-relacionadas { background: var(--cdx-gris-fondo); }

/* ============================ TEXTO SEO COLAPSADO DE LA PORTADA ==== */
/* El `collapse-container-banner.gradient-effect` de la home de upgrade: el
   texto recortado y desvanecido por abajo con un degradado, y un «Saber más»
   que lo despliega. Se replica el MECANISMO; la tipografía es la nuestra.

   ⚠️⚠️ **El recorte solo actúa cuando la pieza 15 pone `es-colapsable`.** El
   texto se sirve ENTERO en el HTML —es un texto de posicionamiento, es su razón
   de ser— y si el JS no llega se ve completo y sin botón. Capar con CSS a secas
   dejaría el texto cortado y sin forma de abrirlo en cuanto fallara el JS. */
.cdx-home-intro__caja {
	/* La medida de lectura del sistema: `.cdx-prosa` capa a 75ch, que a cuerpo
	   20 son unos 855 px. Se le da esa anchura a la caja ENTERA para que el
	   titular no se vaya a los 1580 del contenedor mientras el texto se queda
	   en su columna. */
	max-width: 860px;
	margin-inline: auto;
}
.cdx-home-intro__titulo { margin-bottom: var(--cdx-espacio-bloque); }
/* El tope de 75ch ya lo pone la caja: aquí se suelta para que use su columna
   completa, como en la ficha de servicio. */
.cdx-home-intro__texto { max-width: none; }
.cdx-home-intro__texto > :first-child { margin-top: 0; }

/* Recortado: alto fijo y degradado de desvanecido al blanco del bloque. */
.cdx-home-intro.es-colapsable .cdx-home-intro__texto {
	position: relative;
	max-height: var(--cdx-intro-alto);
	overflow: hidden;
}
/* El degradado NO puede comerse el clic: va con `pointer-events: none`, que si
   no tapa los enlaces del último trozo de texto visible.

   ⚠️ **Va en `:not(.es-abierto)`, no se apaga con `opacity`.** La primera
   versión lo dejaba puesto y lo ocultaba con una regla `.es-abierto …::after {
   opacity: 0 }`: misma especificidad y más abajo en la hoja, o sea que debería
   ganar… y medido **no se aplicaba**, ni quitando la transición. Como el
   degradado va anclado a `bottom: 0`, con el bloque abierto eso pintaba una
   franja blanca de 180 px sobre las últimas líneas del texto. Que el
   pseudoelemento **no exista** mientras está abierto no tiene ese problema y
   además no necesita transición ninguna. */
.cdx-home-intro.es-colapsable:not(.es-abierto) .cdx-home-intro__texto::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 180px;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--cdx-blanco));
	pointer-events: none;
}
.cdx-home-intro.es-abierto .cdx-home-intro__texto { max-height: none; }

/* Alto del trozo visible: unas diez líneas de cuerpo 20/32, que dejan ver el
   primer párrafo entero y el arranque de la lista. Cortar A MEDIAS es lo que
   hace que el degradado se lea como «hay más» y no como el final del texto. */
.cdx-home-intro { --cdx-intro-alto: 320px; }
@media (max-width: 991px) { .cdx-home-intro { --cdx-intro-alto: 280px; } }
@media (max-width: 575px) { .cdx-home-intro { --cdx-intro-alto: 240px; } }

/* El botón va separado del texto y, cuando está recortado, pisando un poco el
   degradado: así queda claro que es la continuación de ese texto y no un
   enlace suelto del bloque. */
.cdx-home-intro__pie { margin-top: 28px; }
.cdx-home-intro__mas {
	/* Es un `<button>`, no un enlace: hereda `.cdx-enlace` pero hay que
	   reponer lo que el navegador le pone de fábrica. */
	background: none;
	border: 0;
	border-bottom: 1px solid currentColor;
	padding-left: 0;
	padding-right: 0;
	cursor: pointer;
}
/* ⚠️⚠️ **`hidden` NO basta para esconderlo, y esto no es opcional.** El botón
   arranca con el atributo `hidden` y `.cdx-enlace` le pone
   `display: inline-flex`: **cualquier regla de autor gana al `[hidden]
   { display: none }` del navegador**, así que sin JS el «Saber más» se veía
   —comprobado con `checkVisibility()`— y no desplegaba nada, porque sin JS el
   texto ya está entero. Es el mismo arreglo que ya lleva
   `.cdx-tab[hidden]` en las pestañas de la ficha de servicio.
   ⚠️ Y por eso NO se pone una regla global `[hidden] { display: none }`: el
   velo del menú (`.cdx-menu-velo[hidden]`) anula ese comportamiento a
   propósito, porque su cierre lo gestiona una transición. */
.cdx-home-intro__mas[hidden] { display: none; }
/* ⚠️ **La flecha NO se gira al abrir.** Se probó darle media vuelta (↗ → ↙)
   como gesto de «recoger», y el usuario lo rechazó: la flecha tiene que ser
   **exactamente la misma que en todos los enlaces del sitio**. Lo que distingue
   los dos estados es el rótulo, que lo cambia la pieza 15. */

/* ---------- Caja de autor, al cierre del artículo ---------- */
/* Esqueleto del bloque de comentarios de Quanto (medido a 1600 en
   `/reveal-business-opportunities-with-our-five-point-brand-audit/`: flex con
   gap 28, avatar de 110 al 100 % de radio, nombre a 24/600/−0,24, «fecha» a
   18 y párrafo a 20/32 separado 16). ⚠️ **Todos esos valores resultaron ser ya
   nuestros tokens**, y su enlace «Reply» es `.cdx-enlace` exacto: no hay que
   inventar nada, solo componerlo.

   Lo que la convierte en caja de AUTOR y no en un comentario: el rótulo
   «Escrito por» con el **filete corto de 30×1** que ya llevan las fechas de las
   tarjetas de entrada, el CARGO donde Quanto pone la fecha (con el tratamiento
   de `.cdx-miembro__cargo`) y el fondo gris del sistema. Y sin enlace al final,
   como pidió el usuario. */
.cdx-entrada-cuerpo__caja--autor { margin-top: var(--cdx-espacio-bloque); }

.cdx-autor {
	display: flex;
	align-items: flex-start;
	gap: 28px;
	padding: 40px;
	background: var(--cdx-gris-fondo);
}

/* Avatar redondo de 110, el suyo. */
.cdx-autor__foto {
	flex: none;
	width: 110px;
	height: 110px;
	border-radius: 100%;
	overflow: hidden;
	background: var(--cdx-gris-suave);
}
/* ⚠️ `object-position: center top`, NO `center`. Las fotos de equipo son
   RETRATOS verticales (la de #2018 mide 450×626), y recortar un vertical a
   cuadrado por el centro corta por encima de la frente. Desde arriba, la cara
   queda dentro.
   ⚠️ Y la pedimos como `thumbnail` aunque hoy devuelva el fichero original:
   **los adjuntos de equipo no tienen miniaturas generadas** (§9.0 nº 5), así
   que de momento bajan 450px para verse a 110. Cuando se regeneren, esto
   empieza a aprovecharlas sin tocar nada. */
.cdx-autor__foto img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center top;
}

/* Rótulo con el filete corto: 30×1 centrado en la línea, a 42 de sangría, que
   es la misma medida que la fecha de la tarjeta de entrada. */
.cdx-autor__rotulo {
	position: relative;
	margin: 0 0 6px;
	padding-left: 42px;
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	color: var(--cdx-gris-texto);
}
.cdx-autor__rotulo::before {
	content: '';
	position: absolute;
	left: 0;
	top: 50%;
	width: 30px;
	height: 1px;
	background: var(--cdx-gris-texto);
}

/* Nombre: el `h6.name` suyo, que es nuestro `h4`. Va en `<p>`, no en
   encabezado, para no tocar el esquema que dejó §65.3. */
.cdx-autor__nombre {
	margin: 0;
	font-size: var(--cdx-fs-h4);
	line-height: 1.41;
	letter-spacing: -.01em;
	font-weight: var(--cdx-peso-fuerte);
	color: var(--cdx-negro-puro);
}
/* Cargo: el mismo tratamiento que en la tarjeta de equipo. */
.cdx-autor__cargo {
	margin: 2px 0 0;
	font-size: 18px;
	line-height: 1.444;
	color: var(--cdx-gris-texto);
}

.cdx-autor__bio { margin-top: 16px; }
.cdx-autor__bio p {
	margin: 0;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
}
.cdx-autor__bio p + p { margin-top: .8em; }

/* En móvil la fila no cabe: el avatar se encoge a 88 y la ficha pasa debajo.
   El filete del rótulo se mantiene, que es lo que la sigue identificando. */
@media (max-width: 767px) {
	.cdx-autor {
		flex-direction: column;
		gap: 20px;
		padding: 24px;
	}
	.cdx-autor__foto { width: 88px; height: 88px; }
}

/* ---------- Índice de contenidos: columna anclada ---------- */
/* Ocupa el hueco donde estaba la **columna de compartir**, que se quitó el
   2026-09-18 por decisión del usuario. Era un carril de 60 px con X, LinkedIn y
   Facebook, botones redondos con borde de 1px y hueco de 12; si hay que
   recuperarlo, el marcado está en el diario y el mecanismo de anclaje es
   exactamente el de aquí abajo.

   Referencia: el índice montado a mano en `upgrade.coodex.es` (widget «Table of
   Contents» de Elementor), medido a 1600: caja de 210 de ancho, rótulo a
   16/500, ítems a 13/22,1, rellenos de 20 y filete gris de 1px bajo el rótulo.
   Se replica su ESTRUCTURA con nuestros tokens.

   ⚠️ `position: sticky` muere si CUALQUIER ancestro lleva `overflow` distinto de
   `visible` (lección 19). Aquí funciona porque `main` lleva `overflow-x: clip`,
   que precisamente NO crea contenedor de desplazamiento — es la razón por la que
   se eligió `clip` y no `hidden` en §20.11. Si algún día eso cambia, esta
   columna deja de anclarse.

   ⚠️ **Y por eso NO se reproduce el error de z-index del de upgrade**: allí
   Elementor ancla con `position: fixed` por JS y sin `z-index`, así que al subir
   se monta sobre la cabecera. Aquí se para en `--cdx-cabecera-alto`, o sea justo
   DEBAJO, y la cabecera lleva además `z-index: 100`. No hay nada que ajustar. */
.cdx-entrada-cuerpo__caja-externa { position: relative; }

.cdx-indice {
	position: absolute;
	left: var(--cdx-margen-lateral);
	top: 0;
	bottom: 0;
	/* ⚠️ **Ancho FLUIDO, y no escalones a mano.** El hueco libre a la izquierda
	   del texto es la mitad de lo que le sobra a la columna del 66,2 %, o sea un
	   16,9 % del contenedor, y medido va de 208 px (a 1200) a 279 px (a 1920).
	   Con un ancho fijo, o se sale por abajo o deja un claro enorme por arriba.
	   Así el hueco contra el texto se queda en **26 px constantes** en todo el
	   rango, y la caja mide de 170 a 241. Medido en los seis anchos. */
	width: calc(16.9% - 30px);
	/* Holgura de la caja anclada: contra la cabecera por arriba y contra el
	   borde de la ventana por abajo. La consumen el `top` y el tope de altura
	   del cuerpo, y así los dos no se pueden descuadrar entre sí. */
	--cdx-indice-holgura: 24px;
}
.cdx-indice__caja {
	position: sticky;
	/* Debajo de la cabecera pegajosa, nunca por encima. */
	top: calc(var(--cdx-cabecera-alto) + var(--cdx-indice-holgura));
	border: 1px solid var(--cdx-gris-borde);
	background: var(--cdx-blanco);
}

/* Rótulo «Contenidos»: el `<summary>` del `<details>`. Mismo chevron dibujado
   que el acordeón de FAQ, para que el gesto de abrir y cerrar se lea igual en
   todo el sitio. */
.cdx-indice__rotulo {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 18px 20px;
	cursor: pointer;
	list-style: none;                 /* Firefox */
	font-size: var(--cdx-fs-nav);
	font-weight: var(--cdx-peso-fuerte);
	line-height: 1.4;
	color: var(--cdx-negro);
	flex: none;
}
.cdx-indice__rotulo::-webkit-details-marker { display: none; }
.cdx-indice__rotulo::marker { content: ''; }
.cdx-indice__rotulo::after {
	content: '';
	flex: none;
	width: 16px;
	height: 16px;
	background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230f0f0f' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");
	background-size: 16px;
	background-position: center;
	background-repeat: no-repeat;
	transition: transform .2s ease-in-out;
}
.cdx-indice__ficha[open] .cdx-indice__rotulo::after { transform: rotate(-180deg); }

/* El tope de altura va en el CUERPO, no en la caja, y el rótulo se queda
   siempre fuera de él: así el «Contenidos» no se va con el desplazamiento
   cuando la lista es larga (hay una entrada con 39 encabezados y ocho que pasan
   de 12).

   ⚠️⚠️ **Y NO se hace con flex, aunque sea lo primero que uno prueba.** Se
   intentó capar la caja y repartir con `flex: 1 1 auto; min-height: 0`, y
   falla DOS veces: entre la caja y el cuerpo está el `<details>`, que es el
   único hijo flex de verdad, así que la cadena se corta ahí y la lista medía
   **2893 px dentro de una caja de 762**, saliéndose por encima del texto. Y al
   arreglar la cadena poniéndole `display: flex` al propio `<details>`, **el
   cuerpo se queda renderizado al plegarlo**, que es el fallo conocido de
   maquetar un `<details>` con flex. Las dos cosas, medidas.

   Así que la caja crece sola, el cuerpo se capa contra la ventana y el
   `<details>` se queda con su comportamiento nativo. Los términos del `calc`
   son: la cabecera pegajosa, las dos holguras (arriba, la del `top`; abajo, la
   misma contra el borde de la ventana) y el alto del rótulo, que es fijo
   —18+18 de relleno y 22 de línea: 58 medidos, 60 de margen—. */
.cdx-indice__cuerpo {
	max-height: calc(100vh - var(--cdx-cabecera-alto) - var(--cdx-indice-holgura) * 2 - 60px);
	overflow-y: auto;
	overscroll-behavior: contain;
	border-top: 1px solid var(--cdx-gris-borde);
	padding: 14px 20px 18px;
}
.cdx-indice__lista,
.cdx-indice__sublista {
	list-style: none;
	margin: 0;
	padding: 0;
}
/* Los h3 van sangrados y con un filete a la izquierda que los agrupa bajo su
   h2, en vez de un topo: el topo competía con el número que muchos encabezados
   traen ya en el texto. */
.cdx-indice__sublista {
	margin: 6px 0 2px;
	padding-left: 12px;
	border-left: 1px solid var(--cdx-gris-borde);
}
.cdx-indice__item + .cdx-indice__item { margin-top: 10px; }
.cdx-indice__sublista .cdx-indice__item + .cdx-indice__item { margin-top: 8px; }

.cdx-indice__enlace {
	display: block;
	font-size: 15px;
	line-height: 1.45;
	color: var(--cdx-gris-texto);
	transition: color var(--cdx-transicion);
}
.cdx-indice__item--n3 > .cdx-indice__enlace { font-size: 14px; }
.cdx-indice__enlace:hover { color: var(--cdx-negro); }
/* El ítem de la sección que se está leyendo, que marca la pieza 14. En negro y
   en negrita: es lo único que distingue, porque el resto de la lista ya va en
   gris. */
.cdx-indice__enlace.es-actual {
	color: var(--cdx-negro);
	font-weight: var(--cdx-peso-fuerte);
}

/* Por debajo de 1200 el hueco lateral se va (el cuerpo pasa al 82 %), así que
   la caja sale del hueco y se pone ENCIMA del artículo, a todo el ancho de la
   columna de texto. Es lo que hace el de upgrade en tablet
   (`elementor-toc--minimized-on-tablet`), y allí además arranca cerrado: eso lo
   hace la pieza 14, porque `<details open>` no se puede condicionar por CSS. */
@media (max-width: 1199px) {
	.cdx-indice {
		position: static;
		width: auto;
		max-width: 520px;
		margin: 0 auto 40px;
	}
	.cdx-indice__caja { position: static; }
	/* Aquí ya no hay cabecera que descontar —la caja no se ancla—, así que el
	   tope se fija contra la ventana a secas. */
	.cdx-indice__cuerpo { max-height: 60vh; }
}
@media (max-width: 991px) {
	.cdx-indice { max-width: none; }
}

/* ⚠️ **Dianas táctiles del índice** (mismo criterio que §42). Medido a 375 con
   la entrada de 39 encabezados: los ítems que caben en UNA línea quedaban en
   **20 px de alto**, por debajo del mínimo AA (2.5.8, 24×24). Son anchos —266
   px— pero aquí no valen como enlaces de texto en línea: son la navegación
   principal del artículo en móvil, y 20 px se falla con el pulgar.

   Con 6 px arriba y abajo, una línea pasa a 32, que es lo que se les dio a los
   metadatos de la entrada en §42 por el mismo motivo. El hueco entre ítems baja
   a la vez, para que la lista no se estire el doble. */
@media (max-width: 1024px) {
	.cdx-indice__enlace { padding: 6px 0; }
	.cdx-indice__item + .cdx-indice__item { margin-top: 2px; }
	.cdx-indice__sublista .cdx-indice__item + .cdx-indice__item { margin-top: 0; }
}

/* ---------- Columna de COMPARTIR de la ficha de problema/solución (§76.1) ----------
   La llevaba el blog hasta que §70.2 la quitó a cambio del índice de arriba, y
   su CSS se borró en esa misma pasada — así que esto NO es una copia, es una
   reconstrucción desde la medida que dejó §30.2: carril de 60, botones
   REDONDOS de 60×60 con borde 1px, hueco 12, en el MISMO hueco lateral que
   ocupa el índice (mismo mecanismo `position: sticky` bajo la cabecera, sin
   el error de z-index de §70.3 porque para aquí en `--cdx-cabecera-alto`).
   ⚠️ Solo la usa `single-problema_solucion.php`; el blog sigue con el índice,
   eso no cambia. */
.cdx-ps-compartir {
	position: absolute;
	left: var(--cdx-margen-lateral);
	top: 0;
}
.cdx-ps-compartir__lista {
	position: sticky;
	top: calc(var(--cdx-cabecera-alto) + 24px);
	display: flex;
	flex-direction: column;
	gap: 12px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.cdx-ps-compartir__boton {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 60px;
	height: 60px;
	border: 1px solid var(--cdx-gris-borde);
	border-radius: 50%;
	color: var(--cdx-negro);
	transition: background var(--cdx-transicion), color var(--cdx-transicion), border-color var(--cdx-transicion);
}
.cdx-ps-compartir__boton:hover {
	background: var(--cdx-negro);
	border-color: var(--cdx-negro);
	color: var(--cdx-blanco);
}
/* Por debajo de 1200 el hueco lateral se va (mismo corte que el índice):
   la columna se pone en fila HORIZONTAL encima del artículo. */
@media (max-width: 1199px) {
	.cdx-ps-compartir { position: static; margin-bottom: 24px; }
	.cdx-ps-compartir__lista { position: static; flex-direction: row; }
}

/* ---------- Carril de categorías del blog ---------- */
/* ⚠️ Pieza NUESTRA: el blog de Quanto no filtra por categoría porque su demo
   tiene nueve entradas. Aquí son 208 en 8 categorías. La apariencia —píldora de
   borde fino sobre blanco— la eligió el usuario.

   Se desplaza en HORIZONTAL en vez de partir en varias líneas: con nombres como
   «Redes Sociales / Community Managers Alicante» una fila que envuelve ocupa
   tres líneas y empuja la parrilla. */
.cdx-cats-blog { margin-top: 48px; }
@media (max-width: 767px) { .cdx-cats-blog { margin-top: 32px; } }
.cdx-cats-blog__carril {
	list-style: none;
	margin: 0;
	padding: 4px 0;
	display: flex;
	gap: 12px;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x proximity;
	/* Sin barra a la vista: el arrastre y la rueda ya la mueven, y una barra
	   nativa bajo las píldoras ensucia el bloque. */
	scrollbar-width: none;
}
.cdx-cats-blog__carril::-webkit-scrollbar { display: none; }
/* Arrastre con el ratón (pieza 11 del JS). El cursor solo cambia cuando el JS
   ha montado, para no prometer un gesto que no existe si falla. */
.cdx-cats-blog__carril[data-cdx-listo] { cursor: grab; }
.cdx-cats-blog__carril[data-cdx-arrastrando] {
	cursor: grabbing;
	/* Mientras se arrastra no se selecciona texto ni se pelea el snap con el
	   dedo del usuario. */
	user-select: none;
	scroll-snap-type: none;
}
.cdx-cats-blog__pieza {
	display: block;
	flex: none;
	scroll-snap-align: start;
	padding: 14px 24px;
	border: 1px solid var(--cdx-gris-borde);
	border-radius: 40px;
	font-size: var(--cdx-fs-small);
	line-height: 1.44;
	white-space: nowrap;
	color: var(--cdx-negro);
	text-decoration: none;
	transition: background var(--cdx-transicion), color var(--cdx-transicion), border-color var(--cdx-transicion);
}
.cdx-cats-blog__pieza:hover,
.cdx-cats-blog__pieza.es-actual {
	background: var(--cdx-negro);
	border-color: var(--cdx-negro);
	color: var(--cdx-blanco);
}
/* ⚠️ **En móvil la píldora se encoge, y hasta aquí y no más.** El carril no
   tenía ningún escalón: a 375 salían píldoras de **55,9px de alto** con texto de
   18, que junto al hero se comían media pantalla. Se bajan **proporcionalmente**
   —cuerpo, relleno y hueco a la vez, que si solo se toca uno la píldora se
   deforma— a **45,0px**: un 19,5 % menos.
   El suelo no es estético, son dos normas del propio proyecto (§42.3): el cuerpo
   **no baja de 16px** en móvil, y la píldora es una diana táctil, así que **no
   baja de 44px** de alto (el AAA de WCAG 2.5.5). Con 16 + 10 de relleno quedan
   45,0: por debajo de eso ya se incumple. Afecta a los dos carriles, el del blog
   y el de problema/solución, que comparten esta clase. */
@media (max-width: 767px) {
	.cdx-cats-blog__carril { gap: 8px; }
	.cdx-cats-blog__pieza {
		padding: 10px 18px;
		font-size: 16px;
	}
}
/* El titular del hero deja de comerse el aire de abajo cuando lleva carril:
   el hueco lo pone ya el propio carril. */
.cdx-hero-pagina--con-cats .cdx-hero-pagina__titulo { margin-bottom: 0; }

/* ============================================================ CONTACTO ===
   Réplica de `/quanto/contact/`, medida sobre su demo a 1600 (útil 1594).

   Su bloque va en DOS COLUMNAS AL 50 % EXACTO y **sin canal entre ellas**:
   797 + 797 = 1594, con `gap: 0`. El formulario no ocupa los 797 completos
   sino 773, porque su retícula interna (un `row` de Bootstrap) mete 24 de
   gutter por la izquierda. Se replica igual: columnas a 50/50 y 24 de sangría
   solo en la columna del formulario.

   El titular de la columna izquierda es un H3 a 80/90/−2, o sea exactamente
   nuestro `.cdx-titulo-seccion`; y el del hero, 140/149,94/−4,2, que es
   `.cdx-hero-pagina__titulo`. No hace falta tipografía nueva. */

.cdx-contacto__rejilla {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0;
	align-items: start;
}
/* Su sangría del `row`: es lo que deja el formulario en 773 dentro de 797. */
.cdx-contacto__lado--form { padding-left: 24px; }

@media (max-width: 991px) {
	.cdx-contacto__rejilla { grid-template-columns: 1fr; gap: 60px; }
	.cdx-contacto__lado--form { padding-left: 0; }
}

.cdx-contacto__texto { margin-top: 24px; max-width: 46ch; }
.cdx-contacto__datos { margin-top: 48px; }
@media (max-width: 991px) { .cdx-contacto__datos { margin-top: 32px; } }

/* ---------- Los datos de contacto ----------
   Medido en su demo a 1600, pieza a pieza. Cada una tiene SU cuerpo, y no se
   parecen entre sí tanto como uno esperaría:

   | Pieza        | Cuerpo | Interlínea | Interletraje | Peso |
   |--------------|--------|-----------|--------------|------|
   | «Address:»   | 24     | 33,84     | −0,24        | 600  |
   | dirección    | 20     | 32        | normal       | 400  |
   | correo       | **28** | 37,996    | −0,28        | 600  | + subrayado
   | teléfono     | 20     | 32        | −0,24        | 400  |

   ⚠️ **El correo es la pieza MÁS GRANDE de la columna**, más que el rótulo que
   lo encabeza: en su diseño hace de reclamo, no de dato. Y va **subrayado** —en
   su HTML el subrayado lo pinta el `<h6>` que envuelve al enlace, porque su
   propio `.elementor a` lo quita del `<a>`; aquí se pone directamente donde
   toca, con el mismo `text-underline-offset: 6px`. */
.cdx-contacto__dato { margin-bottom: 32px; }

.cdx-contacto__etiqueta {
	display: block;
	margin-bottom: 0;
	font-size: var(--cdx-fs-h4, 24px);
	line-height: 1.41;
	letter-spacing: -.24px;
	font-weight: var(--cdx-peso-fuerte);
	color: var(--cdx-negro-puro);
}

.cdx-contacto__valor {
	margin: 0 0 8px;
	/* ⚠️ **NO al 100 % del ancho.** En su demo la dirección ocupa 286 de los 655
	   de la caja —un 44 %— y parte en dos líneas; a ancho completo se lee como
	   un párrafo y no como un dato. Se topa en `ch` para que el corte siga los
	   caracteres y no un ancho fijo, igual que hace el pie con su columna. */
	max-width: 24ch;
	font-size: var(--cdx-fs-body);
	line-height: 1.6;
	color: var(--cdx-negro);
	text-wrap: pretty;
}

/* El correo: el reclamo de la columna. */
.cdx-contacto__email {
	margin: 24px 0 0;
	font-size: var(--cdx-fs-h3);
	line-height: 1.357;
	letter-spacing: -.28px;
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-contacto__email a {
	color: var(--cdx-negro-puro);
	text-decoration: underline;
	text-underline-offset: 6px;
	text-decoration-thickness: 1px;
}
.cdx-contacto__email a:hover,
.cdx-contacto__email a:focus-visible { text-decoration-thickness: 2px; }

.cdx-contacto__tel {
	margin: 8px 0 0;
	font-size: var(--cdx-fs-body);
	line-height: 1.6;
	letter-spacing: -.24px;
	color: var(--cdx-negro-puro);
}
.cdx-contacto__tel a { color: inherit; text-decoration: none; }
.cdx-contacto__tel a:hover,
.cdx-contacto__tel a:focus-visible { text-decoration: underline; text-underline-offset: 4px; }

@media (max-width: 991px) {
	.cdx-contacto__etiqueta { font-size: 20px; }
	.cdx-contacto__email { font-size: 22px; }
}

/* ---------- Mapa ----------
   Su `quanto-map-area`, medida a 1600.

   ⚠️ **NO va a sangre.** Su iframe mide **1570×800** y arranca en x=12: vive
   DENTRO del contenedor (1594 de caja, 12 de margen a cada lado), no pegado a
   los bordes de la ventana. Aquí sale a 1561 porque nuestro contenedor útil es
   1585 en vez de 1594; la diferencia es del contenedor, no del bloque.

   El alto **sí es fijo, 800**, no un `clamp`: es un mapa, no una foto que haya
   que encajar, y a menos altura deja de verse el entorno de la oficina.

   El rótulo vertical de al lado NO tiene estilo propio: es `.cdx-ruptura__ir`,
   la misma pieza de la página de Servicios y de la ficha de proyecto. Por eso
   aquí solo hace falta que el marco le ceda su columna, exactamente igual que
   hace `.cdx-ruptura__caja`. */
.cdx-mapa { margin-top: var(--cdx-sec-top); }
.cdx-mapa__marco {
	height: 800px;
	background: var(--cdx-gris-suave);
	overflow: hidden;
}
.cdx-mapa__marco iframe { display: block; width: 100%; height: 100%; border: 0; }

/* El marco le cede al rótulo su columna (32 del rótulo + 12 de aire), igual que
   hace el marco de la ruptura. Sin esto el rótulo se pintaría ENCIMA del mapa.

   ⚠️ Y aquí el rótulo sale **desde 1200**, no desde 1600 como en la ruptura. En
   la ruptura ese tope viene de que el original lo esconde por debajo de 1600
   porque allí se le sale de la ventana; como aquí no cuelga fuera sino que el
   marco le hace sitio, no hay razón para esconderlo en portátiles normales.
   Se acota a `.cdx-mapa__caja` para no cambiar los otros dos bloques que usan
   la misma pieza y que ya están validados. */
@media (min-width: 1200px) {
	.cdx-mapa__caja .cdx-ruptura__ir { display: flex; }
	.cdx-mapa__caja .cdx-mapa__marco { margin-right: 44px; }
}

/* Su alto baja con la ventana; a 800 fijos en tablet se comería la pantalla. */
@media (max-width: 1199px) { .cdx-mapa__marco { height: 560px; } }
@media (max-width: 767px)  { .cdx-mapa__marco { height: 380px; } }

/* ---------- El formulario (Contact Form 7) ----------
   Medidas leídas en su demo, que monta el MISMO plugin:
     · campo: alto 70, relleno 22/24, radio 8, fondo #f5f5f5, texto 18;
     · área de texto: igual, alto 200;
     · botón: negro, radio 40, relleno 14/20/14/24 — o sea, EXACTAMENTE nuestro
       `.cdx-boton`, así que el botón no estrena nada: se le ponen las clases del
       sistema en la plantilla del formulario.

   ⚠️ Se estiliza por el nombre de las clases de CF7 (`wpcf7-*`), no por
   etiqueta: en la misma página puede haber otros campos (el buscador del
   tema) que no deben coger este aspecto. */
.cdx-formulario__titulo {
	margin: 0 0 16px;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
}
.cdx-formulario__texto {
	margin: 0 0 32px;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-texto);
}

/* Retícula interna: nombre y empresa a mitad, el resto a ancho completo. */
.cdx-form__rejilla {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
}
@media (max-width: 767px) { .cdx-form__rejilla { grid-template-columns: 1fr; gap: 16px; } }
.cdx-form__ancho { grid-column: 1 / -1; }

.cdx-formulario .wpcf7-form-control-wrap { display: block; }

.cdx-formulario input[type="text"],
.cdx-formulario input[type="email"],
.cdx-formulario input[type="tel"],
.cdx-formulario input[type="url"],
.cdx-formulario textarea,
.cdx-formulario select {
	width: 100%;
	padding: 22px 24px;
	/* ⚠️ SIN borde, y el trazo del foco como sombra interior. Con un borde real
	   —aunque fuese transparente— el campo medía 72 y no los **70** de su demo:
	   con `height: auto` el borde SUMA aunque haya `box-sizing: border-box`.
	   La sombra interior no ocupa caja, así que ni descuadra ni da salto. */
	border: 0;
	border-radius: 8px;
	background: var(--cdx-gris-fondo);
	font-family: inherit;
	font-size: var(--cdx-fs-small);
	line-height: 1.44;
	color: var(--cdx-negro);
	transition: box-shadow var(--cdx-transicion), background var(--cdx-transicion);
}
.cdx-formulario textarea { height: 200px; resize: vertical; }

/* ---------- El desplegable ----------
   Su demo no tiene ninguno, así que aquí no hay nada que medir: lo que se
   replica es **el propio campo de texto de al lado**, para que la fila no
   desentone. Sin esto el `<select>` se pinta con el control nativo del sistema
   —borde gris, esquinas rectas, tipografía del SO— en medio de campos de radio
   8 y fondo #f5f5f5.

   La punta va como imagen de fondo en SVG incrustado (nada que descargar) y se
   reserva sitio a la derecha para que el texto largo no se le meta debajo. */
.cdx-formulario select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 56px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M2 5 L8 11 L14 5' stroke='%230f0f0f' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 24px center;
	cursor: pointer;
}
/* Mientras sigue en la opción-rótulo se lee como un marcador de posición, igual
   que el resto de campos vacíos; en cuanto se elige algo, pasa a negro. */
.cdx-formulario select:has(option:first-child:checked) { color: #6b6b6b; }

.cdx-formulario input:focus-visible,
.cdx-formulario textarea:focus-visible,
.cdx-formulario select:focus-visible {
	outline: none;
	box-shadow: inset 0 0 0 1px var(--cdx-negro);
	background: var(--cdx-blanco);
}
.cdx-formulario ::placeholder { color: #6b6b6b; opacity: 1; }

.cdx-formulario .wpcf7-submit { margin-top: 8px; }

/* Avisos de CF7: el plugin trae su propia hoja con rojos y bordes de 2px que
   no son de este sistema. Se rehacen con la paleta del tema. */
.cdx-formulario .wpcf7-not-valid-tip {
	margin-top: 8px;
	font-size: var(--cdx-fs-legal, 16px);
	line-height: 1.4;
	color: #b3261e;
}
.cdx-formulario .wpcf7-not-valid { box-shadow: inset 0 0 0 1px #b3261e; }
.cdx-formulario .wpcf7-response-output {
	margin: 24px 0 0;
	padding: 16px 20px;
	border: 1px solid var(--cdx-gris-borde);
	border-radius: 8px;
	font-size: var(--cdx-fs-small);
	line-height: 1.44;
}
.cdx-formulario form.sent .wpcf7-response-output { border-color: var(--cdx-negro); }
.cdx-formulario form.invalid .wpcf7-response-output,
.cdx-formulario form.failed .wpcf7-response-output { border-color: #b3261e; color: #b3261e; }

/* La casilla de consentimiento va en línea con su texto, no como campo. */
.cdx-form__consentimiento {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	/* ⚠️ **16 px fijos, no el token legal.** `--cdx-fs-legal` baja con los
	   escalones y en móvil dejaba este texto en **13 px**: es el consentimiento
	   de privacidad, o sea justo lo que hay que poder leer ANTES de marcar la
	   casilla. Aquí no se encoge. */
	font-size: 16px;
	line-height: 1.5;
	color: var(--cdx-gris-texto);
}
.cdx-form__consentimiento input[type="checkbox"] {
	width: 18px;
	height: 18px;
	margin-top: 3px;
	flex: none;
	accent-color: var(--cdx-negro);
}
.cdx-form__consentimiento .wpcf7-list-item { margin: 0; }
.cdx-form__consentimiento a { color: var(--cdx-negro); }

/* Primera capa de protección de datos (§128, `inc/formularios.php`), detrás
   del botón. Letra de aviso legal: gris y más pequeña que el consentimiento,
   pero con el mismo suelo de 14 px en móvil para que se pueda leer. */
.cdx-form__rgpd {
	margin-top: 32px;
	padding-top: 24px;
	border-top: 1px solid var(--cdx-gris-borde);
	font-size: 14px;
	line-height: 1.5;
	color: var(--cdx-gris-texto);
}
.cdx-form__rgpd-titulo { margin: 0 0 8px; color: var(--cdx-negro); font-weight: 500; }
.cdx-form__rgpd ul { list-style: none; margin: 0; padding: 0; }
.cdx-form__rgpd li + li { margin-top: 4px; }
.cdx-form__rgpd strong { color: var(--cdx-negro); font-weight: 500; }
.cdx-form__rgpd a { color: var(--cdx-negro); }

/* ====================================== PÁGINAS DE AYUDA / SUBVENCIÓN ====
   Las usan «Kit Digital» y «Kit Consulting», que comparten plantilla.
   Casi todo reutiliza vocabulario ya hecho —`.cdx-seccion-partida`,
   `.cdx-faqs`, `.cdx-servicio-cta`, `.cdx-boton`—; aquí solo va lo que no
   existía: la banda de logos, las claves, la lista con marca de verificación y
   la TABLA DE PRECIOS. */

/* ---------- Hero ---------- */
.cdx-ayuda-hero .cdx-rotulo-logos { margin-bottom: 16px; }
/* El marco del programa («Fondos europeos Next Generation EU…») es una línea de
   contexto legal, no un subtítulo de venta: va a cuerpo de texto y en el gris
   secundario, y se topa para que no cruce toda la pantalla. */
.cdx-ayuda-marco {
	margin: 32px 0 0;
	max-width: 60ch;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-texto);
}

/* ---------- Banda de logos oficiales ---------- */
/* ⚠️ La imagen es larguísima y bajita (1536×178 la del Kit Digital): va entera
   y SIN recortar ni encajar en un marco, porque recortarla se comería las
   banderas y los logos institucionales. Solo se le pone un techo de altura para
   que en pantallas anchas no crezca de más.
   Va ALINEADA A LA IZQUIERDA (2026-09-01), a la sangría del contenedor y en la
   misma vertical que el titular del hero y el resto de los bloques; centrada
   quedaba descolgada. El `auto` de la derecha es lo que la empuja a la
   izquierda sin tocar el `width: auto`, que es quien conserva su proporción. */
.cdx-ayuda-logos { padding-top: 0; }
.cdx-ayuda-logos__img {
	display: block;
	margin: 0 auto 0 0;
	max-width: 100%;
	height: auto;
	max-height: 120px;
	width: auto;
}
@media (max-width: 767px) { .cdx-ayuda-logos__img { max-height: 70px; } }

/* ---------- Claves ---------- */
.cdx-ayuda-claves__rejilla {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 48px;
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (max-width: 991px) { .cdx-ayuda-claves__rejilla { grid-template-columns: 1fr; gap: 40px; } }

.cdx-clave__titulo {
	margin: 24px 0 12px;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
}
.cdx-clave__texto { color: var(--cdx-gris-texto); }

/* ⚠️ **Los iconos del sitio antiguo vienen EN COLOR** (azules y naranjas) y esta
   familia es monocroma. Se apagan a negro con un filtro en vez de rehacer 12
   PNG: `grayscale` quita el color y `brightness(0)` lo lleva a negro puro
   conservando la transparencia. Y van **pequeños**, que era lo pedido: en el
   original ocupaban 200 px y dominaban el bloque.

   💡 Si algún día se rehacen como SVG, basta con quitar el filtro. */
.cdx-clave__icono img {
	display: block;
	width: auto;
	height: 56px;
	filter: grayscale(1) brightness(0);
}
@media (max-width: 991px) { .cdx-clave__icono img { height: 48px; } }

/* En el acordeón el icono va EN LÍNEA con el título, aún más pequeño. */
.cdx-clave__icono--linea { display: inline-flex; flex: none; margin-right: 14px; }
.cdx-clave__icono--linea img { height: 28px; }

/* ---------- Lista con marca de verificación ---------- */
/* La marca es la del diseño de referencia (ver `cdx_check()`), a su tamaño
   real de 24×20. */
.cdx-lista-check, .cdx-precio__lista {
	list-style: none;
	margin: 0;
	padding: 0;
}
.cdx-lista-check li, .cdx-precio__lista li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin-bottom: 10px;
	font-size: var(--cdx-fs-body);
	line-height: 1.6;
	color: var(--cdx-negro);
}
.cdx-lista-check li:last-child, .cdx-precio__lista li:last-child { margin-bottom: 0; }
/* La marca se alinea con la PRIMERA línea del texto, no con el centro del
   bloque: con dos y tres líneas de texto, centrada se veía descolgada. */
.cdx-check { flex: none; margin-top: .45em; }

/* ---------- TABLA DE PRECIOS ----------
   Réplica de `.quanto-pricing-box` de `/quanto/pricing/`, medida a 1600:
   caja 507×635, relleno **54 48 48 60**, fondo **#f5f5f5** y **esquinas vivas**
   (radio 0), que es lo que la distingue de nuestras tarjetas redondeadas. */
.cdx-precios {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
	list-style: none;
	margin: 48px 0 0;
	padding: 0;
}
@media (max-width: 1199px) { .cdx-precios { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .cdx-precios { grid-template-columns: 1fr; } }

.cdx-precio {
	display: flex;
	flex-direction: column;
	height: 100%;
	/* ⚠️ Relleno VERTICAL más generoso que el de su demo (54 arriba y 48 abajo).
	   Sus tarjetas llevan un listado de cinco puntos que rellena la caja; las
	   nuestras solo tienen rótulo, detalle e importe, así que con su relleno la
	   caja quedaba corta y el contenido apretado contra los bordes. Los laterales
	   SÍ se dejan en sus 48/60. */
	padding: 72px 48px 64px 60px;
	background: var(--cdx-gris-fondo);
	border-radius: 0;
}
@media (max-width: 1199px) { .cdx-precio { padding: 52px 32px 48px 40px; } }

.cdx-precio__rotulo {
	margin: 0 0 6px;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	color: var(--cdx-negro-puro);
}
.cdx-precio__detalle {
	margin: 0 0 32px;
	font-size: var(--cdx-fs-body);
	line-height: 1.6;
	color: var(--cdx-negro);
}
/* El importe es la pieza grande, pero YA NO va con el cuerpo de un titular de
   sección: a 80px pesaba demasiado dentro de la tarjeta y se comía al rótulo.
   ⚠ Se sale a propósito de `--cdx-fs-h2`/`--cdx-ls-h2` con valores FIJOS —
   60 en escritorio y 45 en móvil, sin interletraje— y **solo aquí**: esos dos
   tokens los comparten los h2 de todo el sitio y el resto de textos de la
   tarjeta (rótulo, detalle, listado) se quedan como estaban. */
.cdx-precio__cifra {
	margin: 0 0 32px;
	font-size: 60px;
	line-height: 1.12;
	letter-spacing: 0;
	font-weight: var(--cdx-peso-fuerte);
	color: var(--cdx-negro-puro);
}
@media (max-width: 767px) { .cdx-precio__cifra { font-size: 45px; } }
.cdx-precio__lista { margin-bottom: 32px; }

/* `margin-top: auto` empuja el botón al fondo, así que en una fila de tarjetas
   de texto desigual todos los botones quedan a la misma altura. */
.cdx-precio__boton { margin-top: auto; justify-content: center; width: 100%; }

/* ---------- Categorías ---------- */
/* ⚠️ **Separación entre las dos columnas del arranque.** La retícula que se
   reutiliza es la del bloque de contacto, que va a 50/50 **sin canal** porque
   allí la columna izquierda es texto corto y datos. Aquí la izquierda lleva dos
   párrafos largos y la derecha un formulario con sus campos: pegadas, el texto
   parecía continuar dentro del primer campo. Se les abre un canal de verdad, y
   la sangría de 24 de la columna del formulario se retira para que el hueco no
   se sume dos veces. */
.cdx-ayuda-arranque .cdx-contacto__rejilla { column-gap: 80px; }
.cdx-ayuda-arranque .cdx-contacto__lado--form { padding-left: 0; }
@media (max-width: 1399px) { .cdx-ayuda-arranque .cdx-contacto__rejilla { column-gap: 56px; } }

/* ⚠️ 80ch daba **107 caracteres reales** de línea, por encima del máximo
   recomendado. La unidad `ch` mide el ancho del «0», que en Instrument Sans es
   más ancho que el carácter medio, así que 80ch NO son 80 caracteres: hay que
   contarlos midiendo, no fiarse de la unidad. A 68ch salen ~90. */
.cdx-ayuda-cats__texto { margin-top: 24px; max-width: 68ch; }
.cdx-ayuda-cats__acordeon { margin-top: 48px; }
.cdx-ayuda-cats__nota {
	margin: 32px 0 0;
	/* ⚠️ El token legal baja a 13 px en móvil y esta nota explica de qué depende
	   el importe de la ayuda: es información que decide, no letra pequeña
	   decorativa. Se topa en 16 con `max()`, que deja el 16 del escritorio
	   intacto y solo levanta el suelo en móvil. */
	font-size: max(16px, var(--cdx-fs-legal));
	line-height: 1.5;
	color: var(--cdx-gris-texto);
}
/* ⚠️ **El rótulo del acordeón, PEGADO A LA IZQUIERDA.** El `<summary>` reparte
   con `justify-content: space-between`, así que icono y texto sueltos dejaban el
   texto flotando en medio de la fila: se leía como centrado, que es justo lo que
   no se quería. Van agrupados en `.cdx-ayuda-cats__rotulo`, que pasa a ser un
   solo hijo flex: el grupo a la izquierda y el chevron a la derecha.
   `min-width: 0` deja que el grupo se encoja en vez de empujar al chevron
   fuera de la caja cuando el título es largo. */
.cdx-ayuda-cats__rotulo {
	display: flex;
	align-items: center;
	min-width: 0;
	text-align: left;
}

/* ⚠️ **Más aire alrededor del contenido desplegado.** El `<summary>` abierto baja
   su relleno inferior a 16 para acercarse a su respuesta, y con la respuesta sin
   relleno superior el texto quedaba pegado al título. Aquí se le dan 16 arriba
   —24 efectivos con los 16 del summary— y 56 abajo, que separa una categoría de
   la siguiente.
   Solo en este acordeón: las FAQs de la ficha de servicio y de la portada están
   medidas contra la demo y no se tocan. */
.cdx-ayuda-cats__acordeon .cdx-faq__respuesta { padding: 16px 0 56px; }
@media (max-width: 991px) {
	.cdx-ayuda-cats__acordeon .cdx-faq__respuesta { padding: 12px 0 36px; }
}

/* ⚠️ **El cuerpo del acordeón NO va a ancho completo en escritorio.** A 1585 de
   contenedor, un párrafo de texto corrido da líneas larguísimas y se lee mal.
   Se topa al **90 %** y se centra, que es lo pedido; en móvil vuelve al 100 %,
   donde el ancho ya lo pone la pantalla y recortarlo solo quitaría sitio. */
@media (min-width: 992px) {
	.cdx-ayuda-cats__acordeon .cdx-faq__respuesta {
		max-width: 90%;
		margin-inline: auto;
	}
}

/* ============================================================== 404 ======
   El Space Invaders de coder.com/404 (§81), en blanco y con nuestra letra.
   El juego está en `assets/js/juego-404.js`; aquí solo el escenario.

   · El escenario ocupa la VENTANA menos la cabecera (en la suya, la ventana
     entera: allí la cabecera flota encima). No es `.cdx-bloque`, a propósito:
     no lleva el hueco de 130 arriba ni el aire contra el pie (§34.1), porque
     la nave vive pegada al borde de abajo.
   · Capas: el lienzo tapa el texto y la cifra —los bichos pasan por encima,
     como en la suya— pero NO el botón, las instrucciones ni el cartel final,
     que tienen que poder pulsarse.
   · La cifra: en la suya, monoespaciada 150→480, interlínea .95, interletraje
     −.05em y peso ligero. Aquí Instrument Sans a 400 (la más fina que hay) y
     con cifras TABULARES, para que no baile de ancho al ir sumando. */
.cdx-404 {
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	justify-content: center;
	height: calc(100dvh - var(--cdx-cabecera-alto));
	min-height: 560px;
	overflow: hidden;
	background: var(--cdx-blanco);
	color: var(--cdx-negro);
}
.cdx-404__lienzo {
	position: absolute;
	inset: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
	display: block;
}
.cdx-404__interior {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
	text-align: center;
}
.cdx-404__titulo {
	margin: 0;
	/* Un pelín más grande que el cuerpo (§81.8): cuerpo de h4, 24 → 22 → 20. */
	font-size: var(--cdx-fs-h4);
	line-height: var(--cdx-lh-body);
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: 0;
}
.cdx-404__cifra {
	margin: 0;
	font-size: clamp(150px, min(33vw, 52dvh), 480px);
	line-height: .95;
	font-weight: var(--cdx-peso-normal);
	letter-spacing: -.05em;
	font-variant-numeric: tabular-nums;
	color: var(--cdx-negro);
}
/* La flecha apunta hacia atrás y va delante del texto: el gesto es volver. */
.cdx-404__boton { position: relative; z-index: 2; margin-top: 40px; }
.cdx-404 .cdx-flecha-recta { width: 20px; height: 20px; }

/* Al terminar la partida, la cifra y el texto se van y queda el cartel. */
.cdx-404.terminado .cdx-404__interior { visibility: hidden; }

/* Lo que solo tiene sentido con el juego en marcha: sin JS no se enseña. */
.cdx-404:not(.con-juego) .cdx-404__hud,
.cdx-404:not(.con-juego) .cdx-404__ayuda { display: none; }

/* ⚠️ EL LIENZO PINTA EN BLANCO Y SE MEZCLA POR DIFERENCIA (§81.4). Sobre el
   fondo blanco, blanco − blanco = negro, así que los bichos se ven negros
   como siempre; pero al cruzar el marcador NEGRO salen en blanco, invertidos,
   en vez de desaparecer contra él. El `isolation: isolate` del escenario
   limita la mezcla a lo que hay dentro. */
.cdx-404__lienzo { mix-blend-mode: difference; }

/* MARCADOR de recreativa, arriba a la izquierda: caja negra con esquinas
   escalonadas en píxel (el `clip-path`), filete blanco por dentro (la
   segunda sombra) y tres casillas separadas a trazos, como el
   «1UP / HI-SCORE» de las máquinas. Va POR DEBAJO del lienzo, para que los
   bichos pasen por encima (invertidos). */
.cdx-404__hud {
	position: absolute;
	top: 24px;
	left: 0;
	right: 0;
	z-index: 0;
	pointer-events: none;
}
.cdx-404__marcador {
	--cdx-pixel: 6px;
	display: inline-flex;
	margin: 0;
	padding: 12px 8px;
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
	box-shadow: inset 0 0 0 4px var(--cdx-negro), inset 0 0 0 6px var(--cdx-blanco);
	clip-path: polygon(
		0 var(--cdx-pixel), var(--cdx-pixel) var(--cdx-pixel), var(--cdx-pixel) 0,
		calc(100% - var(--cdx-pixel)) 0, calc(100% - var(--cdx-pixel)) var(--cdx-pixel), 100% var(--cdx-pixel),
		100% calc(100% - var(--cdx-pixel)), calc(100% - var(--cdx-pixel)) calc(100% - var(--cdx-pixel)), calc(100% - var(--cdx-pixel)) 100%,
		var(--cdx-pixel) 100%, var(--cdx-pixel) calc(100% - var(--cdx-pixel)), 0 calc(100% - var(--cdx-pixel))
	);
}
.cdx-404__casilla { padding: 6px 20px; }
.cdx-404__casilla[hidden] { display: none; }
.cdx-404__casilla + .cdx-404__casilla { border-left: 2px dashed var(--cdx-blanco-60); }
.cdx-404__casilla dt {
	font-size: 13px;
	line-height: 1.4;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--cdx-blanco-60);
}
.cdx-404__casilla dd {
	margin: 4px 0 0;
	font-size: clamp(24px, 1rem + 1.6vw, 40px);
	line-height: 1;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: .06em;
	font-variant-numeric: tabular-nums;
}
@media (max-width: 575px) {
	.cdx-404__marcador { padding: 10px 4px; }
	.cdx-404__casilla { padding: 4px 12px; }
	.cdx-404__casilla dt { font-size: 11px; letter-spacing: .12em; }
}

/* INSTRUCCIONES: caja blanca con borde negro de 3 y sombra dura desplazada
   (sin difuminar, como un sprite), teclas dibujadas como teclas y un «▶»
   que parpadea a golpes, en dos tiempos, delante de «para empezar». */
.cdx-404__ayuda {
	position: absolute;
	right: 20px;
	bottom: 50px;
	z-index: 2;
	max-width: calc(100% - 40px);
	padding: 16px 44px 18px 20px;
	border: 3px solid var(--cdx-negro);
	background: var(--cdx-blanco);
	box-shadow: 6px 6px 0 var(--cdx-negro);
	color: var(--cdx-negro);
}
@media (min-width: 992px) { .cdx-404__ayuda { right: 48px; } }
.cdx-404__ayuda[hidden] { display: none; }
.cdx-404__ayuda-titulo {
	margin: 0 0 12px;
	font-size: 13px;
	line-height: 1.4;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: .16em;
	text-transform: uppercase;
}
.cdx-404__ayuda-lista {
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--cdx-fs-nav);
	line-height: 1.4;
}
.cdx-404__ayuda-lista li + li { margin-top: 10px; }
.cdx-404__ayuda-empieza { font-weight: var(--cdx-peso-fuerte); }
.cdx-404__ayuda-empieza::before {
	content: "▶";
	display: inline-block;
	width: 1.1em;
	font-size: .75em;
	animation: cdx-404-parpadeo 1s steps(1) infinite;
}
@keyframes cdx-404-parpadeo { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .cdx-404__ayuda-empieza::before { animation: none; } }
.cdx-404__ayuda kbd {
	display: inline-block;
	min-width: 30px;
	margin-right: 4px;
	padding: 1px 8px;
	border: 2px solid var(--cdx-negro);
	background: var(--cdx-blanco);
	box-shadow: 0 3px 0 var(--cdx-negro);
	font-family: inherit;
	font-size: 13px;
	line-height: 1.5;
	font-weight: var(--cdx-peso-fuerte);
	letter-spacing: .06em;
	text-align: center;
	text-transform: uppercase;
}
.cdx-404__ayuda kbd + kbd { margin-left: -2px; }
.cdx-404__cerrar {
	position: absolute;
	top: 8px;
	right: 8px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 2px solid var(--cdx-negro);
	background: var(--cdx-blanco);
	color: var(--cdx-negro);
	cursor: pointer;
	transition: background var(--cdx-transicion), color var(--cdx-transicion);
}
.cdx-404__cerrar:hover, .cdx-404__cerrar:focus-visible { background: var(--cdx-negro); color: var(--cdx-blanco); }
.cdx-404__solo-tactil { display: none; }
@media (hover: none) and (pointer: coarse) {
	.cdx-404__solo-teclado { display: none; }
	.cdx-404__solo-tactil { display: block; }
}

/* MÓVIL (§81.5): marcador compacto e instrucciones a todo el ancho. */
@media (max-width: 767px) {
	/* Marcador en UNA línea: rótulo y cifra lado a lado. De ~80 px a ~36. */
	.cdx-404__hud { top: 16px; text-align: center; }   /* centrado (§81.7) */
	.cdx-404__marcador {
		--cdx-pixel: 4px;
		padding: 4px 2px;
		box-shadow: inset 0 0 0 3px var(--cdx-negro), inset 0 0 0 4px var(--cdx-blanco);
	}
	.cdx-404__casilla { display: flex; align-items: baseline; gap: 6px; padding: 6px 10px; }
	.cdx-404__casilla dt { font-size: 10px; letter-spacing: .1em; }
	.cdx-404__casilla dd { margin: 0; font-size: 18px; letter-spacing: .04em; }

	/* Instrucciones: a todo el ancho y centradas. */
	.cdx-404__ayuda {
		left: var(--cdx-margen-lateral);
		right: calc(var(--cdx-margen-lateral) + 6px);   /* los 6 de la sombra */
		max-width: none;
		padding: 14px 40px 16px;
		text-align: center;
	}
	.cdx-404__ayuda-titulo { margin-bottom: 10px; }

	/* El texto, la cifra y el botón suben para dejar sitio abajo a las
	   instrucciones: si no, la caja tapaba «Volver al inicio». */
	.cdx-404__interior { margin-bottom: 200px; }

	/* El «Ooops» baja hacia el 404 (§81.8): con interlínea de .95 la cifra
	   deja aire por encima del trazo. Con `top` y no con margen, para no mover
	   la cifra ni el botón; y no con `transform`, que es del `.cdx-fade`. */
	.cdx-404__titulo { position: relative; top: 14px; }
}

.cdx-404__fin {
	position: absolute;
	inset: 0;
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding-inline: var(--cdx-margen-lateral);
	text-align: center;
}
.cdx-404__fin[hidden] { display: none; }
.cdx-404__fin-titulo {
	margin: 0 0 24px;
	font-size: 36px;
	line-height: 1.2;
	font-weight: var(--cdx-peso-fuerte);
}
/* Los dos botones, del MISMO ancho y alto (§81.7): dos columnas iguales,
   que se apilan en móvil. «Siguiente nivel» es el de contorno pero sobre
   BLANCO (el suyo es transparente y aquí los bichos pasan por detrás). */
.cdx-404__fin-botones {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
}
/* Mismo borde y relleno en los dos: el de contorno resta el borde al relleno
   y bajo 992 el normal cambia de relleno y el de contorno no, así que
   apilados en móvil no medirían lo mismo. */
.cdx-404__fin-botones .cdx-boton {
	justify-content: center;
	padding: 13px 23px;
	border: 1px solid var(--cdx-negro);
}
@media (max-width: 991px) { .cdx-404__fin-botones .cdx-boton { padding: 9px 19px; } }
.cdx-404__fin-botones .cdx-boton--contorno { background: var(--cdx-blanco); }
.cdx-404__fin-botones .cdx-boton--contorno:hover,
.cdx-404__fin-botones .cdx-boton--contorno:focus-visible { background: var(--cdx-negro); }
@media (max-width: 575px) {
	.cdx-404__fin-botones { grid-template-columns: minmax(0, 300px); }
}

/* ================================== PÁGINAS DE TEXTO (legales y fichas) ==
   Las cuatro legales y las 19 fichas hijas de las ayudas. No estrenan nada de
   tipografía: el aspecto lo pone `.cdx-prosa`, que ya está medida. Aquí solo va
   el ancho de lectura y el ritmo entre apartados. */

/* ⚠️ **Ancho de LECTURA, no de contenedor.** A 1585 una línea de texto corrido
   pasa de 200 caracteres y se pierde el renglón al volver. Se topa a 78ch, que
   deja unas 90 columnas con nuestro cuerpo de 20. No se centra: arranca donde
   arranca el titular, para que la página se lea como una sola columna. */
.cdx-contenido__prosa { max-width: 78ch; }

/* Los títulos internos necesitan aire por arriba para que se lean como cortes,
   sobre todo en documentos largos de 40 apartados como el aviso legal. */
.cdx-contenido__prosa h2 { margin-top: 72px; }
.cdx-contenido__prosa h3 { margin-top: 56px; }
.cdx-contenido__prosa h4 { margin-top: 40px; }
.cdx-contenido__prosa > :first-child { margin-top: 0; }
@media (max-width: 991px) {
	.cdx-contenido__prosa h2 { margin-top: 48px; }
	.cdx-contenido__prosa h3 { margin-top: 36px; }
	.cdx-contenido__prosa h4 { margin-top: 28px; }
}

/* Las fichas de las ayudas abren con la banda de logos oficiales dentro del
   propio contenido: se le da el mismo trato que en la página madre —entera,
   sin recortar y con techo de altura— en vez de dejarla a 1536 de ancho. */
.cdx-contenido__prosa img { max-width: 100%; height: auto; }
.cdx-contenido__prosa figure { margin: 40px 0; }
.cdx-contenido__prosa figure img[src*="Logo-digitalizadores"],
.cdx-contenido__prosa figure img[src*="KC_conClaim"] { max-height: 90px; width: auto; }

/* Listas: las fichas traen listados largos de funcionalidades. */
.cdx-contenido__prosa ul, .cdx-contenido__prosa ol { padding-left: 1.25em; }
.cdx-contenido__prosa li { margin-bottom: 10px; }

/* ---------- Filtrado sin recarga (pieza 13) ----------
   Mientras llega el listado nuevo, el que hay se apaga un poco. Es lo justo
   para que se note que algo está pasando sin que la página dé un salto: el
   bloque conserva su alto hasta que llega el relevo. */
[data-cdx-filtro-zona][aria-busy="true"] {
	opacity: .45;
	transition: opacity .2s ease;
	pointer-events: none;
}

/* ============================== DIANAS TÁCTILES (WCAG 2.5.5) =============
   Auditado a 1920 / 1440 / 1366 / 1280 / 1024 / 932 / 768 / 667 / 430 / 375 /
   320. En escritorio no había nada que tocar; en táctil, varias dianas se
   quedaban por debajo de los **44×44** que piden WCAG 2.5.5 y la guía de Apple:

     .cdx-menu-boton      40×32   ← la más usada en móvil
     .cdx-boton (CTA)    144×39
     .cdx-cabecera__logo  66×40
     .cdx-enlace         119×27   (×12 en la portada)
     enlaces del pie      42×42

   ⚠️ Todo va acotado a **≤1024**: en escritorio el ratón apunta fino y las
   medidas de estos componentes están tomadas de la demo a 1600. Agrandarlas
   allí desharía el ajuste sin ganar nada.

   💡 Se usa `min-height` y NO `padding` donde el componente ya es flex
   centrado: así crece la caja de clic sin mover el texto ni cambiar el ancho. */
@media (max-width: 1024px) {

	/* El botón del menú es la diana crítica: en móvil es la única forma de
	   navegar. Pasa de 40×32 a 44×44 justos. */
	.cdx-menu-boton {
		min-width: 44px;
		min-height: 44px;
	}

	/* Botones de píldora: el relleno baja a 10/20 en esta banda y se quedaban
	   en 39 de alto. */
	.cdx-boton {
		min-height: 44px;
		box-sizing: border-box;
	}

	/* El logo de la cabecera es un enlace a la portada. */
	.cdx-cabecera__logo {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/* `.cdx-enlace` ya es `inline-flex` con `align-items: center`, así que el
	   mínimo de altura NO mueve el texto ni ensancha la caja: solo agranda la
	   zona pulsable. */
	.cdx-enlace {
		min-height: 44px;
	}

	/* Enlaces de las listas del pie: se quedaban en 42×42. */
	.cdx-pie__lista a,
	.cdx-pie__legal a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/* ⚠️ **Los titulares que hacen de enlace** (el de la tarjeta de servicio y el
	   de cada fila de problema/solución) se quedaban en **27-32 px de alto**. Son
	   anchos —de 130 a 450 px— así que cumplen el nivel AA (2.5.8, 24×24), pero
	   no los 44 del AAA. Se les da el mínimo de altura y se centra el texto: en
	   táctil un titular es la diana principal de su tarjeta, y 27 px de alto se
	   falla con el pulgar.
	   💡 `align-items: center` es lo que evita que el texto se pegue arriba
	   cuando el titular ocupa UNA sola línea y la caja crece a 44. */
	.cdx-enlace-titulo,
	.cdx-ps__titulo a,
	.cdx-tarjeta-entrada__titulo a,
	.cdx-tarjeta-caso__titulo a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/* ⚠️ La línea de datos de la entrada (fecha, categoría, autor) tenía enlaces
	   de **22 px de alto**: por debajo incluso del mínimo AA (2.5.8, 24×24). Son
	   metadatos en línea, así que no se les puede dar 44 sin descuadrar la fila
	   —van separados por filetes de 1 px, §31.4—; se les da **32**, que cumple
	   el AA con holgura y no rompe la línea. */
	.cdx-entrada__datos a {
		display: inline-flex;
		align-items: center;
		min-height: 32px;
	}

	/* ⚠️ Los iconos de redes necesitan ANCHO además de alto: son cuadrados de
	   42 y con solo `min-height` se quedaban en 42×44. */
	.cdx-pie__redes a {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 44px;
		min-height: 44px;
	}
}

/* ====================================================== MIGAS DE PAN =======
   El rastro lo monta Yoast (ver `inc/migas.php`: el mismo generador alimenta lo
   visible y el `BreadcrumbList` del grafo, así que no hay dos versiones). Aquí
   solo se le da forma.

   El marcado que llega, de fuera adentro:

     nav.cdx-migas > span > span > a          ← «Inicio»
                            span.cdx-migas__sep  ← « / », con espacio a cada lado
                            span > a          ← nivel intermedio
                            span.breadcrumb_last[aria-current] > strong

   ⚠️ **El separador YA ES un elemento** (2026-10-07): hasta entonces era el
   signo del panel de Yoast como nodo de texto suelto, sin forma de darle color.
   Ahora lo pone el filtro `cdx_migas_separador()` de `inc/migas.php`, que
   MANDA sobre el panel. El espaciado sigue siendo el de Yoast (un espacio a
   cada lado) y no se monta una fila flex: el recorte a una línea con puntos
   suspensivos de más abajo necesita que todo vaya en línea.               */

/* Cuerpo: `--cdx-fs-legal`, que es la letra pequeña del tema y **ya trae su
   escalón**: 16 en escritorio y **13 de 767 para abajo**. Es lo que se pidió —
   en móvil tenían que bajar bastante— y evita inventar un número nuevo.

   ⚠️ **El rastro tiene que COSTAR POCO ALTO**, que es la otra mitad del
   encargo: se metió como algo sutil y estaba empujando el resto de la página.
   Lo que añadía al hero, medido antes de tocar:

     escritorio  24 de margen + 22,4 de alto = 46,4 px
     móvil       20 de margen + 32 de alto   = 52 px

   ⚠️ En MÓVIL ocupaba MÁS que en escritorio, y no por la letra: por la diana
   táctil de 32 px del enlace, que mandaba sobre el texto. Por eso bajar solo el
   cuerpo no habría servido de nada. */
.cdx-migas {
	margin-top: 16px;
	/* ⚠️ Margen NEGATIVO, a propósito: el rastro **devuelve parte del alto que
	   ocupa**. Hace dos cosas distintas según la plantilla, y las dos se
	   querían:
	     · donde el rastro es el ÚLTIMO hijo del hero (Servicios, Casos,
	       Portfolio, Equipo, legales…), el hero no tiene relleno inferior, así
	       que el margen **colapsa hacia fuera** y sube la sección siguiente;
	     · donde va algo detrás dentro del propio hero —la entradilla de la
	       ficha de servicio, el carril de categorías del blog—, sube ese
	       elemento.
	   Sin esto, meter las migas empujaba 46 px hacia abajo todo lo que va
	   detrás de un hero. */
	margin-bottom: -10px;
	font-size: var(--cdx-fs-legal);
	line-height: 1.4;
	color: var(--cdx-gris-texto);
}

/* ---------- Encima del titular, en la zona de blog ---------- */
/* La ENTRADA tiene debajo del h1 la fila de fecha·categoría·autor, que es texto
   del mismo peso y se confundían: ahí el rastro va ARRIBA, y el aire se le da
   por debajo en vez de por encima.
   ⚠️ Y aquí el margen inferior **no puede ser negativo**: el rastro no es el
   último hijo, así que un negativo se comería el hueco contra el titular. */
.cdx-migas--encima {
	margin-top: 0;
	margin-bottom: 12px;
}

/* ---------- UNA SOLA LÍNEA, y lo que sobra se corta ---------- */
/* Es la limitación de largo que se pidió, y es la mitad VISIBLE de las dos: el
   rótulo ya viene acortado a 60 caracteres desde PHP (para que el marcado salga
   corto también, no solo la pantalla), y esto remata lo que aun así no quepa.

   ⚠️ El recorte va en el envoltorio ENTERO y no solo en la última miga, a
   propósito: así se corta por el final de la línea, o sea por la página en
   curso, y los niveles de navegación —que son los que sirven para moverse— se
   quedan siempre enteros.

   ⚠️ `text-overflow` NO funciona sobre un elemento en línea: necesita una caja
   de bloque con `overflow` distinto de `visible`. De ahí el `display: block`,
   que además hace que la caja mida lo que mide el contenedor y no lo que mide
   el texto. */
.cdx-migas > span {
	display: block;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ---------- Separador ---------- */
/* Encargo del usuario (2026-10-07): barras diagonales y una ruta que se lea por
   NIVELES. Por eso la barra va UN ESCALÓN MÁS CLARA que los enlaces: tres tonos
   en orden —barra `--cdx-gris-borde`, enlace `--cdx-gris-texto`, página en
   curso `--cdx-negro`— y el ojo agrupa cada rótulo sin leer los signos.
   El contraste bajo de la barra (1,7:1) es aceptable porque es decorativa y va
   con `aria-hidden`; los ENLACES sí cumplen AA (4,8:1). */
.cdx-migas__sep {
	color: var(--cdx-gris-borde);
	/* Aire a cada lado (2026-10-07, segunda vuelta): el espacio de Yoast solo
	   daba ~.25em y la barra se pegaba a los rótulos. Con este margen el hueco
	   total por lado es ~.65em, el de la referencia que pasó el usuario (Attio,
	   medido sobre su captura: ~14 px de hueco con letra de ~20). En `em` para
	   que escale con el escalón de 16 → 13 px de móvil. */
	margin-inline: .4em;
}

/* ---------- Enlaces ---------- */
/* Sin subrayado en reposo, como los demás enlaces del sitio (§52). Al pasar por
   encima suben a negro y el subrayado APARECE —se funde desde transparente—
   en vez de saltar: es el toque moderno que se pidió, con la transición del
   sistema (`--cdx-transicion`) para que vaya al ritmo del resto del sitio.
   El subrayado es fino y separado del texto para que no toque los
   descendentes. */
.cdx-migas a {
	color: inherit;
	text-decoration: underline;
	text-decoration-color: transparent;
	text-decoration-thickness: 1px;
	text-underline-offset: .25em;
	transition: color var(--cdx-transicion), text-decoration-color var(--cdx-transicion);
}
.cdx-migas a:hover,
.cdx-migas a:focus-visible {
	color: var(--cdx-negro);
	text-decoration-color: currentColor;
}

/* ---------- La página en curso ---------- */
/* Yoast la envuelve en `<strong>` porque su opción `breadcrumbs-boldlast` está
   activada. La opción NO se toca —es suya, y se cambia desde el panel—.

   ⚠️ **Peso 500, ni 400 ni negrita** (2026-10-07). Hasta entonces iba a peso
   normal y se distinguía solo por color: el usuario pidió MÁS contraste. Los
   enlaces no pueden aclararse más sin bajar de AA (el gris de ahora ya está en
   4,8:1), así que el contraste se gana por PESO. Y no negrita (600-700): el
   titular grande está justo al lado y dos negritas seguidas se pelean. La
   fuente es variable (400-700, `fuentes.css`), así que el 500 es real y no
   una negrita sintética. */
.cdx-migas .breadcrumb_last {
	color: var(--cdx-negro);
}
.cdx-migas .breadcrumb_last strong {
	font-weight: 500;
}

/* ---------- Diana táctil ---------- */
/* ⚠️ **24 y no 32**, al contrario que el resto de enlaces en línea del tema
   (§42, §48.3). 24×24 es el mínimo del nivel AA (2.5.8) y se cumple; los 32 que
   se les dan a los metadatos de la entrada eran holgura, y aquí esa holgura
   costaba 8 px de alto en la zona donde menos sitio hay. **Era el verdadero
   responsable de que el rastro ocupara más en móvil que en escritorio**, porque
   mandaba sobre el alto del texto. */
@media (max-width: 1024px) {
	.cdx-migas a {
		display: inline-flex;
		align-items: center;
		min-height: 24px;
	}
}

/* ---------- Escalón de móvil ---------- */
/* Selector completo repetido, no uno más corto (lección 21): si no, la regla
   base gana por especificidad y el escalón no entra. */
@media (max-width: 767px) {
	.cdx-migas {
		margin-top: 10px;
		margin-bottom: -12px;
	}
	.cdx-migas--encima {
		margin-top: 0;
		margin-bottom: 8px;
	}
}

/* ============================================================ BUSCADOR ====
   §104 (2026-10-08). La lupa de la cabecera y su panel replican los de
   liljewall.se, la referencia que eligió el usuario; la página de resultados
   es propuesta nuestra (ver el encabezado de `search.php`). */

/* ---------- La lupa ---------- */
/* Su botón mide 28,8 × 40 y la lupa llena el ancho (`background-size: 100%`):
   aquí lo mismo, con el SVG en línea para que tome `currentColor`. El trazo
   sale de menos de 1 px a este tamaño, que es lo que la hace tan ligera. */
.cdx-buscar-boton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 28px;
	height: 40px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--cdx-negro);
	cursor: pointer;
}
.cdx-buscar-boton svg { display: block; width: 28px; height: auto; overflow: visible; transition: opacity var(--cdx-transicion); }
.cdx-buscar-boton:hover svg { opacity: .6; }
/* En táctil, la diana a 44 (§42) sin agrandar el dibujo. */
@media (max-width: 1024px) {
	.cdx-buscar-boton { width: 44px; height: 44px; }
	.cdx-buscar-boton svg { width: 24px; }
}
/* ⚠️ MÓVIL (§104.4, 2026-10-08): la lupa NO va en la cabecera. Se probó
   pegada al «¿Hablamos?» (§104.3) y al usuario no le convenció; el buscador va
   DENTRO DEL MENÚ, encima de la fila de email y teléfono (`.cdx-menu-buscar`,
   más abajo). Al quitarla, la cabecera vuelve a ser la de siempre (logo, botón
   y menú) y deja de desbordar a 320. */
@media (max-width: 767px) {
	.cdx-buscar-boton { display: none; }
}

/* ---------- Buscador dentro del menú (solo móvil) ---------- */
.cdx-menu-buscar { display: none; }
@media (max-width: 767px) {
	/* Ocupa todo el ancho de la franja de abajo (que alinea a la izquierda) y
	   cierra con un filete tenue que se enciende en blanco al enfocarlo. */
	.cdx-menu-buscar {
		display: flex;
		align-items: center;
		gap: 12px;
		align-self: stretch;
		margin: 0 0 8px;
		border-bottom: 1px solid color-mix(in srgb, var(--cdx-blanco) 30%, transparent);
		transition: border-color var(--cdx-transicion);
	}
	.cdx-menu-buscar:focus-within { border-bottom-color: var(--cdx-blanco); }
	.cdx-menu-buscar__caja {
		position: relative;
		flex: 1;
		min-width: 0;
		display: flex;
		align-items: center;
	}
	.cdx-menu-buscar__campo {
		width: 100%;
		min-height: 52px;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 0;
		outline: 0;
		background: transparent;
		color: var(--cdx-blanco);
		caret-color: var(--cdx-blanco);
		font: inherit;
		font-size: 22px;
		line-height: 1.2;
		-webkit-appearance: none;
		appearance: none;
	}
	.cdx-menu-buscar__campo::placeholder { color: color-mix(in srgb, var(--cdx-blanco) 70%, transparent); opacity: 1; }
	.cdx-menu-buscar__campo::-webkit-search-cancel-button,
	.cdx-menu-buscar__campo::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }

	/* La rayita que parpadea delante del placeholder (pedida: «queda bien»).
	   Es FINGIDA, ver `header.php`: mismo sitio y mismo ritmo que el cursor
	   real (≈1,06 s, encendida-apagada sin fundido), y se retira en cuanto el
	   campo se enfoca o tiene texto, que es cuando aparece el de verdad. */
	.cdx-menu-buscar__cursor {
		position: absolute;
		top: 50%;
		left: 0;
		width: 1.5px;
		height: 26px;
		background: var(--cdx-blanco);
		transform: translateY(-50%);
		pointer-events: none;
		animation: cdx-parpadeo 1.06s steps(1) infinite;
	}
	.cdx-menu-buscar:has(.cdx-menu-buscar__campo:focus) .cdx-menu-buscar__cursor,
	.cdx-menu-buscar:has(.cdx-menu-buscar__campo:not(:placeholder-shown)) .cdx-menu-buscar__cursor { display: none; }

	/* La lupa: el BOTÓN de buscar, a la derecha, con su diana de 44. */
	.cdx-menu-buscar__enviar {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: none;
		width: 44px;
		height: 44px;
		margin-right: -10px;
		padding: 0;
		border: 0;
		background: none;
		color: var(--cdx-blanco);
		cursor: pointer;
	}
	.cdx-menu-buscar__enviar svg { display: block; width: 24px; height: auto; overflow: visible; }
}
@keyframes cdx-parpadeo {
	0%   { opacity: 1; }
	50%  { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.cdx-menu-buscar__cursor { animation: none; }
}

/* ---------- El panel ---------- */
/* Cubre la barra ENTERA de la cabecera (su `inset: 0` contra `.cdx-cabecera`,
   que es `sticky` y por tanto contenedor de lo absoluto).
   ⚠️ EN NEGATIVO (usuario, 2026-10-08): franja NEGRA con texto e iconos en
   blanco. La referencia lo hace en blanco; aquí se invierte para que el panel
   se lea al instante como un estado distinto de la cabecera. */
.cdx-buscador {
	position: absolute;
	inset: 0;
	z-index: 2;
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
	/* SE DESPLIEGA HACIA ABAJO (usuario, 2026-10-08): una cortina que baja desde
	   el borde superior. Se recorta con `clip-path` y no se desplaza con
	   `transform`, para que el negro CREZCA en su sitio en vez de entrar
	   deslizándose desde fuera de la pantalla. Curva de entrada y salida muy
	   marcada (`.76,0,.24,1`): arranca lenta, corre en medio y frena al final.
	   Al cerrar hace el camino inverso; la pieza 16 espera a que termine antes
	   de volver a poner `hidden`. */
	clip-path: inset(0 0 100% 0);
	transition: clip-path .6s cubic-bezier(.76, 0, .24, 1);
}
.cdx-buscador.es-abierto { clip-path: inset(0 0 0 0); }
/* Mientras la cortina sube al cerrar, que no se trague los clics de la página. */
.cdx-buscador:not(.es-abierto) { pointer-events: none; }
.cdx-buscador[hidden] { display: none; }

/* Todo lo que queda DEBAJO de la cabecera: pincharlo cierra. Transparente, como
   su `HeaderSearch-closeArea`. */
.cdx-buscador__fuera {
	position: fixed;
	top: var(--cdx-cabecera-alto);
	right: 0;
	bottom: 0;
	left: 0;
}

.cdx-buscador__form {
	position: relative;
	display: flex;
	align-items: center;
	gap: 24px;
	height: 100%;
}

/* Texto grande y SIN caja: 44 px, su cuerpo medido a 1024. Por escalones, no
   con `clamp()` (lección 1 del proyecto). */
.cdx-buscador__campo {
	flex: 1;
	min-width: 0;
	height: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	outline: 0;
	background: transparent;
	color: var(--cdx-blanco);
	caret-color: var(--cdx-blanco);
	font: inherit;
	font-size: 44px;
	line-height: 1.1;
	letter-spacing: -.02em;
	-webkit-appearance: none;
	appearance: none;
	/* Entra subiendo un poco, con la curva de las entradas del sitio. */
	opacity: 0;
	transform: translateY(12px);
	transition: opacity .4s var(--cdx-anim-ease), transform .5s var(--cdx-anim-ease);
}
.cdx-buscador.es-abierto .cdx-buscador__campo { opacity: 1; transform: none; transition-delay: .3s; }
/* Placeholder MÁS PEQUEÑO que lo que se escribe y más claro (usuario,
   2026-10-08): 32 px contra los 44 del texto, y blanco al 70 %. Que lo escrito
   se lea más grande que la pista es lo que hace que la pista se lea como pista. */
.cdx-buscador__campo::placeholder { color: color-mix(in srgb, var(--cdx-blanco) 70%, transparent); opacity: 1; font-size: 32px; }
.cdx-buscador__campo::-webkit-search-cancel-button,
.cdx-buscador__campo::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
@media (max-width: 991px) {
	.cdx-buscador__campo { font-size: 32px; }
	.cdx-buscador__campo::placeholder { font-size: 24px; }
}
@media (max-width: 575px) {
	.cdx-buscador__campo { font-size: 22px; }
	.cdx-buscador__campo::placeholder { font-size: 18px; }
}

/* La X: dos trazos finos, del mismo grosor visual que la lupa. Al pasar, un
   cuarto de vuelta. */
.cdx-buscador__cerrar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--cdx-blanco);
	cursor: pointer;
}
.cdx-buscador__cerrar { opacity: 0; transition: opacity .3s ease; }
.cdx-buscador.es-abierto .cdx-buscador__cerrar { opacity: 1; transition-delay: .35s; }
.cdx-buscador__cerrar svg { display: block; width: 26px; height: 26px; transition: transform var(--cdx-transicion); }
.cdx-buscador__cerrar:hover svg,
.cdx-buscador__cerrar:focus-visible svg { transform: rotate(90deg); }

@media (prefers-reduced-motion: reduce) {
	.cdx-buscador { transition: none; }
	.cdx-buscador__campo { transition: none; transform: none; }
	.cdx-buscador__cerrar,
	.cdx-buscador__cerrar svg { transition: none; }
}

/* ======================================================= RESULTADOS ======== */

/* ---------- Cabecera de la página ---------- */
/* ⚠️ CABECERA COMPRIMIDA (usuario, 2026-10-08): que se vean más resultados.
   «Has buscado» pegado al término, el término a cuerpo de h2 (80, con sus
   escalones) en vez del h1 de 140, y el recuento más pequeño y más cerca. */
.cdx-busqueda-hero__ante {
	margin: 0 0 2px;
	font-size: var(--cdx-fs-small);
	line-height: 1.44;
	color: var(--cdx-gris-texto);
}
/* Lo buscado va a cuerpo de h1: una palabra larga no puede salirse por el lado
   (§53.2, se recorta EN SILENCIO por el `overflow-x: clip` de `main`). */
.cdx-busqueda-hero__titulo {
	overflow-wrap: anywhere;
	font-size: var(--cdx-fs-h2);
	line-height: var(--cdx-lh-titulo-2);
	letter-spacing: -.025em;
}
.cdx-busqueda-hero__cuenta {
	margin: 8px 0 0;
	font-size: var(--cdx-fs-legal);
	line-height: 1.4;
	color: var(--cdx-gris-texto);
}

/* Número de resultados dentro de cada píldora: más tenue que el rótulo. */
.cdx-busqueda-filtros__n {
	margin-left: 6px;
	opacity: .5;
	font-variant-numeric: tabular-nums;
}

/* ---------- El listado ---------- */
/* Pariente del de Problema/Solución (filete arriba, titular y texto en
   columnas), pero con identidad propia: índice y tipo a la izquierda,
   miniatura a la derecha y NADA de círculo con flecha. La retícula es SIEMPRE
   de tres columnas, haya foto o no: así los títulos de todas las filas
   arrancan en la misma vertical. */
.cdx-resultados {
	list-style: none;
	margin: 0;
	padding: 0;
	border-bottom: 1px solid var(--cdx-gris-borde);
}
.cdx-resultado {
	position: relative;
	display: grid;
	grid-template-columns: 200px minmax(0, 1fr) 220px;
	gap: 40px;
	align-items: start;
	padding: 44px 0;
	border-top: 1px solid var(--cdx-gris-borde);
}
/* El gesto de la fila: un filete NEGRO que recorre la línea de arriba de
   izquierda a derecha, encima de la gris. */
.cdx-resultado::before {
	content: "";
	position: absolute;
	top: -1px;
	left: 0;
	width: 100%;
	height: 1px;
	background: var(--cdx-negro);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform .7s var(--cdx-anim-ease);
}
.cdx-resultado:hover::before,
.cdx-resultado:focus-within::before { transform: scaleX(1); }

.cdx-resultado__meta {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding-top: 6px;
}
.cdx-resultado__indice {
	font-size: var(--cdx-fs-small);
	line-height: 1.444;
	font-weight: var(--cdx-peso-fuerte);
	color: var(--cdx-gris-borde);
	font-variant-numeric: tabular-nums;
	transition: color .4s ease;
}
.cdx-resultado:hover .cdx-resultado__indice,
.cdx-resultado:focus-within .cdx-resultado__indice { color: var(--cdx-negro); }
.cdx-resultado__tipo {
	font-size: var(--cdx-fs-legal);
	line-height: 1.4;
	color: var(--cdx-gris-texto);
}

.cdx-resultado__titulo {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	letter-spacing: var(--cdx-ls-tarjeta);
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-resultado__enlace { color: inherit; text-decoration: none; }
/* Un solo enlace por fila, ESTIRADO a toda ella: se pincha en cualquier punto,
   pero el teclado y el lector encuentran un único destino por resultado. */
.cdx-resultado__enlace::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.cdx-resultado__texto {
	max-width: 760px;
	margin: 14px 0 0;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
}
.cdx-resultado__ruta {
	margin: 14px 0 0;
	overflow: hidden;
	font-size: var(--cdx-fs-legal);
	line-height: 1.4;
	color: var(--cdx-gris-texto);
	white-space: nowrap;
	text-overflow: ellipsis;
}

/* Lo buscado, MARCADO: trazo de rotulador gris por debajo de la línea media, en
   vez del amarillo por defecto de `<mark>` (§31.5). */
.cdx-resultado__marca {
	padding: 0 .04em;
	background: linear-gradient(transparent 58%, color-mix(in srgb, var(--cdx-gris-borde) 65%, transparent) 58%);
	color: inherit;
}

/* Miniatura: zoom al pasar, el de los listados de proyectos (1,04 con la
   transición lenta). */
.cdx-resultado__marco {
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--cdx-gris-fondo);
}
.cdx-resultado__imagen {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--cdx-transicion-lenta);
}
.cdx-resultado:hover .cdx-resultado__imagen { transform: scale(1.04); }

@media (max-width: 1199px) {
	.cdx-resultado { grid-template-columns: 150px minmax(0, 1fr) 180px; gap: 30px; }
}
/* Móvil: índice y tipo en una línea arriba; debajo el texto y, si hay foto,
   una miniatura pequeña a su derecha. El extracto se corta a tres líneas. */
@media (max-width: 767px) {
	.cdx-resultado {
		grid-template-columns: minmax(0, 1fr) 96px;
		gap: 14px 20px;
		padding: 32px 0;
	}
	.cdx-resultado__meta { grid-column: 1 / -1; flex-direction: row; align-items: baseline; gap: 12px; padding-top: 0; }
	.cdx-resultado__cuerpo { grid-column: 1; }
	.cdx-resultado:not(.cdx-resultado--foto) .cdx-resultado__cuerpo { grid-column: 1 / -1; }
	.cdx-resultado__marco { grid-column: 2; grid-row: 2; }
	.cdx-resultado__texto {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 3;
		overflow: hidden;
	}
}
@media (prefers-reduced-motion: reduce) {
	.cdx-resultado::before,
	.cdx-resultado__imagen { transition: none; }
	.cdx-resultado:hover .cdx-resultado__imagen { transform: none; }
}

/* ---------- Sin resultados, o sin término ---------- */
.cdx-busqueda-vacia__titulo {
	margin: 0;
	font-size: var(--cdx-fs-h3);
	line-height: var(--cdx-lh-tarjeta);
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-busqueda-vacia__texto {
	margin: 14px 0 0;
	font-size: var(--cdx-fs-body);
	line-height: var(--cdx-lh-body);
	color: var(--cdx-gris-texto);
}
.cdx-busqueda-vacia__atajos {
	display: flex;
	flex-wrap: wrap;
	gap: 16px 40px;
	margin: 40px 0 0;
	padding: 0;
	list-style: none;
}

/* ---------- Subtítulo grande de la ficha de servicio (§119-§120) ---------- */
/* Más aire por arriba y por abajo (usuario, 2026-10-16). Medido antes a 1600 sin
   imagen destacada: 70 px desde las migas y 110 hasta el bloque siguiente; en
   móvil casi tocaba las migas (su margen inferior es negativo, §62). Se suma al
   ritmo del sistema (`--cdx-sec-top`) en vez de fijar un número, para que siga
   sus escalones. */
/* ⚠️ 2026-10-20 (§122): el usuario lo vio con DEMASIADO aire y pidió volver a
   como estaba. Vuelve el ritmo normal del sistema; solo se queda el arreglo de
   MÓVIL, donde sin él el subtítulo casi tocaba las migas (su margen inferior es
   negativo, §62). */
@media (max-width: 767px) {
	.cdx-servicio-subtitulo { padding-top: calc(var(--cdx-sec-top) + 24px); }
}

/* ---------- Llamada a la acción dentro de un texto (§121) ---------- */
/* La pinta `cdx_sc_llamada_accion()` para los `[vc_cta_button]` y
   `[call_to_action_1]` heredados de entradas y proyectos. Sobria, con el
   vocabulario del sitio: dos filetes que la separan del texto, la frase en
   titular pequeño, el texto en gris y el enlace con flecha. */
.cdx-prosa .cdx-cta-entrada,
.cdx-cta-entrada {
	margin: 48px 0;
	padding: 32px 0;
	border-top: 1px solid var(--cdx-gris-borde);
	border-bottom: 1px solid var(--cdx-gris-borde);
}
.cdx-cta-entrada__frase {
	margin: 0;
	font-size: var(--cdx-fs-h4);
	line-height: 1.3;
	font-weight: var(--cdx-peso-fuerte);
	color: var(--cdx-negro);
}
.cdx-prosa .cdx-cta-entrada__texto,
.cdx-cta-entrada__texto {
	margin: 8px 0 0;
	color: var(--cdx-gris-texto);
}
.cdx-cta-entrada .cdx-enlace { margin-top: 20px; }

/* ============================================================ TABLAS ======
   §122 (2026-10-20). Las tablas de los contenidos (servicios, entradas,
   proyectos) llevaban su formato en línea —cabecera azul, bordes, sombra—; ahora
   se lo quita `cdx_tablas_limpias()` y el diseño es este, minimalista y del
   sistema: SIN BORDES, cabecera NEGRA con texto blanco y filas alternas blanca y
   gris claro (`--cdx-gris-fondo`, el de los fondos de sección). */
.cdx-tabla {
	margin: 32px 0;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}
.cdx-prosa table,
.cdx-tabla table {
	width: 100%;
	margin: 0;
	border: 0;
	border-collapse: collapse;
	font-size: var(--cdx-fs-small);
	line-height: 1.5;
}
.cdx-tabla th,
.cdx-tabla td {
	padding: 16px 20px;
	border: 0;
	text-align: left;
	vertical-align: top;
}
.cdx-tabla th {
	background: var(--cdx-negro);
	color: var(--cdx-blanco);
	font-weight: var(--cdx-peso-fuerte);
}
.cdx-tabla tr { background: var(--cdx-blanco); }
.cdx-tabla tbody tr:nth-child(even) { background: var(--cdx-gris-fondo); }
/* Las celdas en negrita (la primera columna de Software a medida) conservan su peso. */
.cdx-tabla td strong { font-weight: var(--cdx-peso-fuerte); }
@media (max-width: 767px) {
	.cdx-tabla table { min-width: 560px; }
	.cdx-tabla th,
	.cdx-tabla td { padding: 12px 14px; }
}

/* ======================== PROBLEMA / SOLUCIÓN A DOS COLUMNAS (§124) ========
   Solo en la FICHA DE SERVICIO (`lista-ps.php` con `dos_columnas`): en vez de
   filas a todo el ancho, dos ítems por fila. Cada ítem es una tarjeta con el
   filete arriba (el mismo de las filas), el TÍTULO arriba, el texto debajo y
   «Saber más» al pie si hay enlace, alineado con el de su vecino. SIN el círculo
   con flecha (lo quita la plantilla) y sin el ensanche al pasar. La portada y
   /problema-solucion/ no cambian. */
.cdx-lista-ps--dos {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 60px;
}
.cdx-lista-ps--dos .cdx-ps__fila,
.cdx-lista-ps--dos .cdx-ps__fila:last-child {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	gap: 16px;
	height: auto;
	padding: 40px 0;
}
.cdx-lista-ps--dos .cdx-ps__titulo,
.cdx-lista-ps--dos .cdx-ps__info { max-width: none; }
.cdx-lista-ps--dos .cdx-ps__info {
	display: flex;
	flex: 1;
	flex-direction: column;
	align-items: flex-start;
}
.cdx-lista-ps--dos .cdx-ps__texto { margin-bottom: 20px; }
.cdx-lista-ps--dos .cdx-ps__info .cdx-enlace { margin-top: auto; }
@media (min-width: 992px) {
	.cdx-lista-ps--dos .cdx-ps__fila { height: auto; }
	.cdx-lista-ps--dos .cdx-ps__fila:hover { padding-inline: 0; }
	.cdx-lista-ps--dos .cdx-ps__fila--sin-enlace::after { content: none; }
}
@media (max-width: 1199px) {
	.cdx-lista-ps--dos { column-gap: 40px; }
}
@media (max-width: 767px) {
	.cdx-lista-ps--dos { grid-template-columns: minmax(0, 1fr); }
	.cdx-lista-ps--dos .cdx-ps__fila,
	.cdx-lista-ps--dos .cdx-ps__fila:last-child { padding: 32px 0; }
}
