/* ============================================================
   Canal Sostenible — primitivas de marca para el block theme.
   theme.json define tokens, paleta, tipografía y estilos de elemento.
   Aquí solo lo que theme.json no expresa: eyebrow (corrección AA),
   migas de pan, banda inset y las variaciones de tarjeta/botón.
   Regla de marca: CAJAS SIN SOMBRA NI BORDE — contraste por masa de color.
   ============================================================ */

/* ---- Eyebrow / rótulo ----
   Corrección AA: el azul decorativo #62bfee falla como texto; el eyebrow
   usa --text-strong (blue-700, 7,17:1 sobre blanco). */
.cs-eyebrow {
	display: inline-block;
	font-family: var(--wp--preset--font-family--jakarta);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 600;
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
	text-transform: uppercase;
	color: var(--wp--custom--text--strong);
	margin: 0 0 var(--wp--preset--spacing--3);
}

/* Sobre fondo oscuro, el eyebrow va en el azul decorativo (tratamiento del
   export para rótulos on-dark): #62bfee sobre blue-900 da 6,7:1 (AA ≥4,5).
   Sigue PROHIBIDO como texto sobre fondos claros. */
.has-blue-900-background-color .cs-eyebrow,
.cs-on-dark .cs-eyebrow {
	color: var(--wp--preset--color--blue-400);
}

/* En cabeceras de página (constrained), el eyebrow debe alinearse con el H1/migas.
   Como .cs-eyebrow es inline-block, el margin-inline:auto del layout constrained de
   WP no lo alinea y se pega al padding raíz; en bloque hereda el mismo margen que el
   resto de hijos del contenedor de 1200. */
.cs-page-head .cs-eyebrow, .obs-intro .cs-eyebrow { display: block; }

/* ---- Migas de pan (cabeceras de página interiores) ---- */
.cs-crumbs {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--custom--text--muted);
}
.cs-crumbs a {
	color: var(--wp--custom--text--body);
	font-weight: 500;
}
.cs-crumbs a:hover { color: var(--wp--preset--color--blue-700); }

/* ---- Banda a sangre (inset) ----
   Regla web: una banda full-bleed nunca toca el borde de la ventana;
   queda inset 16px (24px ≥768px) para que su radio sea siempre visible. */
.cs-row {
	margin-inline: var(--wp--custom--row-inset);
	border-radius: var(--wp--custom--radius--xl);
	overflow: hidden;
}
@media (min-width: 768px) {
	.cs-row { margin-inline: var(--wp--preset--spacing--6); }
}
/* Dos masas de color a todo ancho NUNCA se tocan (regla de marca, design system 2026-07-02):
   48px (spacing 12 = 3rem = --mass-gap del sistema) entre bandas .cs-row consecutivas. */
.cs-row + .cs-row { margin-top: var(--wp--preset--spacing--12); }

/* ============================================================
   Bandas del home (§export home.html, medido 2026-07-06).
   El export mantiene el inset de 16px también en escritorio (igual
   que el pie .cs-footer__box; la .cs-row genérica sube a 24px ≥768
   y por eso el home no la reutiliza). Radio xl 28 (cifras) /
   xxl 36 (hero, CTA). La foto y el velo azul van en capas CSS
   sobre el mismo elemento — la misma técnica que usa el export.
   ============================================================ */
.cs-band {
	margin-inline: var(--wp--custom--row-inset);
	border-radius: var(--wp--custom--radius--xl);
	overflow: hidden;
}

/* REGLA DE MARCA: una caja a todo el ancho nunca toca el borde del viewport; queda inset
   --row-inset (16px). Excepción explícita .cs-bleed = sangrado real (fondos/chrome, o
   wrapper transparente cuyo hijo ya hace su propio inset). WordPress (root-padding-aware)
   estira los .alignfull a -24px; esto los devuelve a 16px del borde. */
.has-global-padding > .alignfull:not(.cs-bleed) {
	margin-inline: calc(var(--wp--custom--row-inset) - var(--wp--style--root--padding-left));
}

/* Hero: foto del azud + velo azul-900 en degradado 100deg (§export:
   0,86→0,72→0,30; aquí 0,88/0,79/0,34 con margen de seguridad).
   AA recalculado con la GEOMETRÍA REAL (revisión HP3, 2026-07-06): el borde
   derecho del texto no está fijo en "~48-54%" — al ser .cs-hero-copy un max-width
   de 660px FIJOS dentro de una banda cuyo ancho SÍ varía con el viewport (banda =
   100vw − 2×16px de inset; sin bajada de max-width en tablets), el borde real
   se mueve entre ~54% (≥1280px, donde 660px ya no toca el 58% del área de
   contenido) y hasta ~92% a 782px (donde 660px es case casi todo el ancho de la
   banda). Con el degradado anterior (0,74 en 45%) el contraste en ese peor caso
   caía a 2,3:1 (782px) / 3,4:1 (1024px) — muy por debajo de AA. Corrección:
   además de extender la meseta alta del velo (0,79 hasta 58%), el ancho del
   texto pasa a ser relativo (ver .cs-hero-copy más abajo) para que el borde real
   quede siempre en ~54–58% en TODO el rango 782–1440px. Con eso, la opacidad en
   el borde es ≥0,79 en todo el rango y blanco sobre rgba(24,51,95,0,79) compuesto
   sobre un píxel BLANCO PURO da ≥6,59:1 (objetivo ≥5:1 con margen; ≥4,5:1 AA).
   El degradado solo baja de esa opacidad a la derecha del texto (100% ⇒ 0,34,
   igual que antes: la foto se ve igual de nítida a la derecha). */
.cs-hero-band {
	border-radius: var(--wp--custom--radius--xxl);
	background:
		linear-gradient(100deg, rgba(24, 51, 95, 0.88) 0%, rgba(24, 51, 95, 0.79) 58%, rgba(24, 51, 95, 0.34) 100%),
		url("../img/canal-azud-galeria.jpg") center / cover no-repeat;
	padding: 7.5rem var(--wp--preset--spacing--6) 6.75rem;
}
@media (max-width: 781px) {
	.cs-hero-band {
		padding-top: var(--wp--preset--spacing--16);
		padding-bottom: var(--wp--preset--spacing--16);
	}
}
/* El bloque de texto del hero: 660px es la medida del export, pero como
   max-width FIJO no basta (ver comentario de arriba) — se acota también a un
   58% relativo al área de contenido de la banda (.cs-hero-copy, sin padding
   propio) para que el borde derecho del texto no rebase nunca la meseta alta
   del velo, sea cual sea el viewport. min(660px, 58%) da el mismo resultado
   visual que el export en desktop ancho (gana 660px) y protege AA en el rango
   782–1280px (gana el 58%). Queda a la izquierda del contenedor de 1200 (grupo
   flow: sus hijos no llevan margin auto). El H1 balancea sus dos líneas como
   el export (text-wrap: balance ⇒ "Canal Sostenible / Herrera Horizonte 2030"). */
.cs-hero-copy > * { max-width: min(660px, 58%); }
.cs-hero-copy h1 { text-wrap: balance; }
/* En MOVIL ese 58% dejaba los textos en poco mas de la mitad de la caja (171 de 295px) y
   partia el titular en cinco lineas: aqui ocupan el ancho completo. Va DESPUES de la regla
   de arriba a proposito — misma especificidad, manda la ultima declarada.
   Solo por debajo de 600px, no en tablet: a 780px de ancho completo las lineas se irian por
   encima de los ~75 caracteres comodos de leer, mientras que a 343px quedan en unos 45.
   El velo pasa a UNIFORME en el mismo tramo, que es lo que hace posible soltar el 58%: ese
   limite existia para que el blanco no cayera sobre la zona clara del degradado y perdiera
   contraste. Con la opacidad en >=0,80 de lado a lado, el blanco mantiene 6,79:1 incluso
   sobre un pixel blanco de la foto (AA pide 4,5). En una caja estrecha y alta la foto
   aporta poco, asi que el coste visual es minimo. */
@media (max-width: 599.98px) {
	.cs-hero-band {
		background:
			linear-gradient(100deg, rgba(24, 51, 95, 0.88) 0%, rgba(24, 51, 95, 0.80) 100%),
			url("../img/canal-azud-galeria.jpg") center / cover no-repeat;
	}
	.cs-hero-copy > * { max-width: none; }
}

/* CTA "Suma tu mirada": caja con foto DENTRO del contenedor de 1200 (no
   full-bleed): 1152px centrados en escritorio, 16px de aire en móvil.
   Velo §export: blue-900 0,93 → blue-800 0,80 → blue-800 0,42 en 118deg.
   AA recalculado con la GEOMETRÍA REAL (revisión HP3, 2026-07-06): la columna
   de texto (wp:column width:"58%") termina en el 58% de la caja, no en el 50%
   asumido antes. Con el segundo stop en 46% la opacidad en ese borde real caía
   a ≈0,716 → blanco sobre rgba(33,68,128,0,716) compuesto sobre un píxel BLANCO
   PURO da solo 4,39:1 (< 4,5:1 AA). Corrección: se alarga la meseta alta del
   velo (0,80 hasta el 60% en vez del 46%) para que el 58% real quede dentro de
   ella con margen: la opacidad en el borde pasa a ≥0,804 → contraste ≥5,60:1
   (objetivo ≥5:1 cumplido; también ≥4,5:1 AA). Los valores de opacidad (0,93 /
   0,80 / 0,42) no cambian, solo la posición del stop intermedio — la foto se ve
   igual de nítida en el 100% (columna de botón). */
.cs-cta-band {
	max-width: min(1200px, calc(100% - 2 * var(--wp--custom--row-inset)));
	margin-inline: auto;
	border-radius: var(--wp--custom--radius--xxl);
	overflow: hidden;
	background:
		linear-gradient(118deg, rgba(24, 51, 95, 0.93) 0%, rgba(33, 68, 128, 0.8) 60%, rgba(33, 68, 128, 0.42) 100%),
		url("../img/exaltacion-cangrejo.jpg") 50% 38% / cover no-repeat;
	padding: 5.5rem 4.5rem 4rem;
}
@media (max-width: 781px) {
	.cs-cta-band { padding: var(--wp--preset--spacing--12) var(--wp--preset--spacing--6); }
}

/* ============================================================
   Variaciones de tarjeta (Group) — sin sombra ni borde.
   ============================================================ */
.wp-block-group.is-style-card,
.wp-block-group.is-style-card-tint,
.wp-block-group.is-style-card-solid,
.wp-block-group.is-style-card-dark {
	border-radius: var(--wp--custom--radius--lg);
	border: 0;
	box-shadow: none;
}

.wp-block-group.is-style-card {
	background: var(--wp--custom--mass--neutral);
	color: var(--wp--custom--text--body);
}
.wp-block-group.is-style-card-tint {
	background: var(--wp--custom--mass--tint);
	color: var(--wp--custom--text--body);
}
.wp-block-group.is-style-card-solid {
	background: var(--wp--custom--mass--solid);
	color: var(--wp--preset--color--white);
}
.wp-block-group.is-style-card-dark {
	background: var(--wp--custom--mass--dark);
	color: var(--wp--preset--color--white);
}

/* En tarjetas sólidas/oscuras, los titulares y enlaces heredan claro. */
.wp-block-group.is-style-card-solid :where(h1, h2, h3, h4, h5, h6),
.wp-block-group.is-style-card-dark :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--white);
}
.wp-block-group.is-style-card-solid a,
.wp-block-group.is-style-card-dark a {
	color: var(--wp--preset--color--white);
}

/* ============================================================
   Botón: badge circular con flecha diagonal (Button.jsx del design system).
   Píldora con un círculo a la derecha que sostiene la flecha ArrowUpRight
   CENTRADA (SVG, no glifo). Padding derecho pequeño e IGUAL a arriba/abajo: el
   círculo queda ~7px de esos 3 bordes (min-height 46 − badge 32 = 14 → 7 por
   lado; padding-right 7). Hover: el botón INVIERTE (fondo↔texto) y el badge
   invierte su color, con transición. Solo azules; sin sombra ni borde. Se aplica
   a los core `is-style-pill-arrow` (portada/404) y a los .cs-btn (CTA de Red).
   ============================================================ */
/* Flechas ArrowUpRight por color de trazo (SVG → centrado perfecto + cambio en hover). */
:root {
	--cs-arrow-blue: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232a569f' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='7' y1='17' x2='17' y2='7'/%3E%3Cpolyline points='7 7 17 7 17 17'/%3E%3C/svg%3E");
	--cs-arrow-white: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='7' y1='17' x2='17' y2='7'/%3E%3Cpolyline points='7 7 17 7 17 17'/%3E%3C/svg%3E");
}
/* Badge circular común (::after): 32px, flecha 14px centrada, transición de color. */
.is-style-pill-arrow .wp-block-button__link::after,
.cs-btn::after {
	content: ""; flex: 0 0 auto;
	width: 32px; height: 32px; border-radius: 50%;
	background-repeat: no-repeat; background-position: center; background-size: 14px 14px;
	transition: background-color .16s ease;
}
/* Core is-style-pill-arrow: layout de píldora + padding (izq 18, der 7) + min-height 46. */
.wp-block-button.is-style-pill-arrow .wp-block-button__link {
	display: inline-flex; align-items: center; justify-content: center; gap: 12px;
	min-height: 46px; padding: 0 7px 0 18px;
	border-radius: var(--wp--custom--radius--pill); line-height: 1;
	transition: background-color .16s ease, color .16s ease;
}
/* PRIMARIA (sin has-background): azul sólido + badge blanco/flecha azul; hover invierte a
   blanco/texto azul + badge azul/flecha blanca. Azul explícito (no depende del default). */
.is-style-pill-arrow .wp-block-button__link:not(.has-background) {
	background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white);
}
.is-style-pill-arrow .wp-block-button__link:not(.has-background)::after {
	background-color: var(--wp--preset--color--white); background-image: var(--cs-arrow-blue);
}
.is-style-pill-arrow .wp-block-button__link:not(.has-background):hover,
.is-style-pill-arrow .wp-block-button__link:not(.has-background):focus-visible {
	background: var(--wp--preset--color--white); color: var(--wp--preset--color--blue-700);
}
.is-style-pill-arrow .wp-block-button__link:not(.has-background):hover::after,
.is-style-pill-arrow .wp-block-button__link:not(.has-background):focus-visible::after {
	background-color: var(--wp--preset--color--blue-700); background-image: var(--cs-arrow-white);
}
/* SECUNDARIA (has-slate-100-background-color): badge azul/flecha blanca; hover invierte a
   blue-700/texto blanco + badge blanco/flecha azul. */
.is-style-pill-arrow .wp-block-button__link.has-slate-100-background-color::after {
	background-color: var(--wp--preset--color--blue-600); background-image: var(--cs-arrow-white);
}
.is-style-pill-arrow .wp-block-button__link.has-slate-100-background-color:hover,
.is-style-pill-arrow .wp-block-button__link.has-slate-100-background-color:focus-visible {
	/* !important para pisar las clases de color de WP (has-*-color/-background-color), que WP
	   emite con !important; si no, el fondo/texto del botón no invertiría en hover. */
	background-color: var(--wp--preset--color--blue-700) !important;
	color: var(--wp--preset--color--white) !important;
}
.is-style-pill-arrow .wp-block-button__link.has-slate-100-background-color:hover::after,
.is-style-pill-arrow .wp-block-button__link.has-slate-100-background-color:focus-visible::after {
	background-color: var(--wp--preset--color--white); background-image: var(--cs-arrow-blue);
}

/* Botón contorno (ghost) — sobre fondos claros. */
.wp-block-button.is-style-ghost .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--blue-700);
	border: 1.5px solid var(--wp--preset--color--blue-200);
	border-radius: var(--wp--custom--radius--pill);
}
.wp-block-button.is-style-ghost .wp-block-button__link:hover,
.wp-block-button.is-style-ghost .wp-block-button__link:focus {
	background: var(--wp--preset--color--blue-50);
	border-color: var(--wp--preset--color--blue-600);
	color: var(--wp--preset--color--blue-700);
}

/* ---- Foco visible global (criterio AA) ---- */
:where(a, button, .wp-block-button__link, input, select, textarea, summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-600);
	outline-offset: 2px;
	border-radius: 2px;
}

/* ============================================================
   Header institucional (sticky, translúcido).
   ============================================================ */
.cs-header {
	position: sticky;
	top: 0;
	z-index: 50;
}
.cs-gov-strip {
	border-bottom: 1px solid var(--wp--preset--color--slate-200);
}
.cs-gov-strip > .wp-block-group__inner-container,
.cs-gov-strip {
	padding-top: 6px;
	padding-bottom: 6px;
}
.cs-header-bar {
	background: rgba(255, 255, 255, 0.85);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--wp--preset--color--slate-200);
	min-height: 72px;
	display: flex;
	align-items: center;
}
/* Menú móvil: el desplegable de WordPress es un overlay `position: fixed` que debe cubrir la
   pantalla. Un ancestro con `backdrop-filter` pasa a ser su bloque contenedor (spec CSS), así que
   el overlay se anclaba a esta barra de 72px y los enlaces se dibujaban recortados fuera de ella:
   solo asomaba "Inicio". Por debajo de 600px —donde el nav se convierte en overlay— la barra
   renuncia al desenfoque; el fondo sube a casi opaco para que el contenido no se transparente al
   pasar por debajo. Si algún día el nav se configura como overlay TAMBIÉN en escritorio, hay que
   subir aquí el breakpoint o el fallo reaparece. */
@media (max-width: 599.98px) {
	.cs-header-bar {
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
		background: rgba(255, 255, 255, 0.97);
	}
	/* Ya a pantalla completa, el overlay se quedaba con padding 0 y los enlaces morian pegados
	   al borde derecho. El culpable es de WordPress: su regla para el overlay abierto pide
	   `clamp(1rem, var(--wp--style--root--padding-*), 20rem)`, pero este tema no define esas
	   variables de padding raiz, asi que el valor es invalido y la propiedad cae a 0. Hay que
	   ganarle en especificidad (la suya es 0,3,0 por el :not), de ahi el `.cs-header` delante y
	   el mismo :not: asi son 0,4,0 y no dependemos del orden de carga de las hojas. */
	.cs-header .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay-styles) {
		padding: var(--wp--preset--spacing--6) 16px;
	}
	/* A pantalla completa el menu pide otra escala: los 14px de la barra se quedaban
	   pequenos y apretados. Se sube a 18px y se separan los enlaces, con area tactil
	   holgada (~46px de alto, por encima del minimo recomendado de 44). */
	.cs-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
		gap: var(--wp--preset--spacing--1);
	}
	.cs-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
		/* 18px FIJOS, no el token h4: la tipografia del tema es fluida (theme.json
		   typography.fluid) y ese token encoge con el viewport, asi que en movil se
		   quedaba en 14,3px — justo donde queriamos que creciera. */
		font-size: 1.125rem;
		padding: 10px 12px;
	}
	/* Seccion activa: el chip azul del escritorio, aqui en negrita de verdad (el 600 de la
	   barra se diluye a este tamano). El marcado lo pone canal_sostenible_nav_marcar_actual. */
	.cs-header .wp-block-navigation__responsive-container.is-menu-open .current-menu-item .wp-block-navigation-item__content,
	.cs-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content[aria-current="page"] {
		font-weight: 700;
	}
}
/* Fundido al abrir y cerrar. El overlay alterna display:none/flex y display no es animable,
   de ahi `allow-discrete`, que retrasa el none hasta que termina el fundido. El estado de
   partida va con `@starting-style` ANIDADO dentro de la regla: como bloque suelto dentro del
   @media, el navegador lo aplicaba como regla permanente y dejaba el menu siempre invisible.
   Donde no haya soporte, la regla anidada se ignora y el menu aparece sin fundido. */
@media (max-width: 599.98px) {
	.cs-header .wp-block-navigation__responsive-container {
		opacity: 0;
		transition: opacity 200ms ease, display 200ms allow-discrete;
	}
	.cs-header .wp-block-navigation__responsive-container.is-menu-open {
		/* WordPress trae su propio fade-in de 0,1s con `forwards`, que al fijar el valor final
		   gana a las transiciones y solo cubre la entrada: al cerrar, corte seco. Se anula para
		   que el fundido de aqui gobierne los dos sentidos por igual. */
		animation: none;
		opacity: 1;

		@starting-style {
			opacity: 0;
		}
	}
}
@media (prefers-reduced-motion: reduce) {
	.cs-header .wp-block-navigation__responsive-container {
		transition: none;
	}
}
/* La barra es flex (centrado vertical) y eso encoge a su hijo a fit-content:
   se le devuelve el crecimiento para que ocupe el contenedor de 1200
   (el max-width del constrained lo capa; los margin auto lo centran). */
.cs-header-bar > .wp-block-group { flex-grow: 1; }
/* Navegación principal: chip activo y hover suaves. */
.cs-header .wp-block-navigation .wp-block-navigation-item__content {
	padding: 8px 12px;
	border-radius: var(--wp--custom--radius--sm);
	font-weight: 500;
	color: var(--wp--custom--text--body);
}
.cs-header .wp-block-navigation .current-menu-item .wp-block-navigation-item__content,
.cs-header .wp-block-navigation .wp-block-navigation-item__content[aria-current="page"] {
	background: var(--wp--preset--color--blue-100);
	color: var(--wp--preset--color--blue-700);
	font-weight: 600;
}
.cs-header .wp-block-navigation .wp-block-navigation-item__content:hover {
	background: var(--wp--preset--color--blue-50);
	color: var(--wp--preset--color--blue-700);
}
/* Marca de la cabecera (patrón canal-sostenible/marca): SVG del tema a 56px (2026-09-11; antes
   38px). Cabe dentro de la barra sin empujarla: .cs-header-bar mantiene su min-height de 72px y
   el logo queda centrado. Si algún día crece más, la barra crecerá con él. */
.cs-brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
.cs-brand img { height: 56px; width: auto; display: block; }

/* ============================================================
   Pie §export: caja oscura inset + logos fuera, sobre blanco.
   ============================================================ */
/* Caja oscura del pie: inset 16px del borde de la ventana a TODOS los anchos
   (el export mantiene 16px también en escritorio; .cs-row genérica sube a 24px
   en ≥768 y por eso el pie no la reutiliza). Radio xl = 28px (§export). */
.cs-footer__box {
	margin-inline: var(--wp--custom--row-inset);
	border-radius: var(--wp--custom--radius--xl);
	overflow: hidden;
}

/* Enlaces dentro de la caja oscura del pie (p. ej. el teléfono de "Contacto"):
   tono claro legible sobre blue-900 (blue-100 ≈ 10:1, AA) + subrayado. El color
   de enlace por defecto (blue-600) daría solo 2,4:1 sobre el fondo oscuro. */
.cs-footer__box p a,
.cs-fcontact__value a {
	color: var(--wp--preset--color--blue-100);
	text-decoration: underline;
}
.cs-footer__box p a:hover,
.cs-footer__box p a:focus-visible,
.cs-fcontact__value a:hover,
.cs-fcontact__value a:focus-visible {
	color: var(--wp--preset--color--white);
}

/* Lista de datos de contacto del pie con iconos: versión oscura del patrón
   .cs-contact__list de la ficha /contacto/. Chip blue-800 con icono blue-100
   sobre el fondo blue-900 del pie (≈8:1). El icono identifica cada bloque
   (dirección · teléfono · horario); sin etiqueta de texto para no recargar. */
.cs-fcontact { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--3); }
.cs-fcontact__item { display: flex; gap: 10px; align-items: flex-start; }
.cs-fcontact__ic {
	flex: 0 0 auto; width: 30px; height: 30px; margin-top: 1px; border-radius: 8px;
	background: var(--wp--preset--color--blue-800); color: var(--wp--preset--color--blue-100);
	display: inline-flex; align-items: center; justify-content: center;
}
.cs-fcontact__value { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--blue-200); line-height: 1.5; }

/* Tira de socios: fila centrada sobre el fondo blanco de la página. */
.cs-partner-strip { gap: var(--wp--preset--spacing--8) var(--wp--preset--spacing--12); }
/* Logos institucionales reales: normalizados por altura. */
.cs-partner-logo { margin: 0; flex: 0 1 auto; }
.cs-partner-logo img { height: 46px; width: auto; max-width: 280px; object-fit: contain; }
@media (max-width: 600px) { .cs-partner-logo img { height: 38px; } }

/* Chip de icono de las "Áreas del Canal". */
.cs-area-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 10px;
	background: var(--wp--preset--color--blue-100);
	color: var(--wp--preset--color--blue-600);
}
/* AreaCard §export: radio xl (28px), como las tarjetas de listado; el
   is-style-card global sigue en lg para el resto de páginas. El título es un
   enlace pero hereda el color de titular (slate-900), como en el kit. */
.wp-block-group.cs-area-card { border-radius: var(--wp--custom--radius--xl); }
.cs-area-card h3 a { color: inherit; }

/* Cabecera de sección del home (eyebrow + H2 + sub): el sub se limita a ~38em
   (532px medidos en el export) para que no corra a todo el ancho. */
.cs-sec-head p:not(.cs-eyebrow) { max-width: 38em; }

/* Variante con enlace "Ver todos" a la derecha (§export .cs-head, medido
   2026-07-06: flex space-between alineado al pie, gap 24, 32px bajo la
   cabecera). Con wrap, en móvil el enlace baja bajo el texto (igual que el
   export a 390). margin-block:0 en los hijos directos neutraliza el blockGap
   del layout flow de WP (mismo patrón que .cs-stats-grid); el eyebrow pasa a
   block (mismo mecanismo que .cs-page-head) para alinear con su H2. */
.cs-sec-head--row {
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: var(--wp--preset--spacing--6);
	flex-wrap: wrap;
}
.wp-block-group.cs-sec-head--row > * { margin-block: 0; }
.cs-sec-head--row .cs-eyebrow { display: block; }

/* Enlace "Ver todos los proyectos / todas las noticias" (§export .cs-seeall:
   14/600 con flecha 16). blue-600 #346bc8: 5,13:1 sobre blanco y 4,82:1 sobre
   blue-50 (AA ≥4,5:1); hover/focus en blue-700 + subrayado. El anillo de foco
   lo da la regla global :focus-visible. */
.cs-seeall {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	color: var(--wp--preset--color--blue-600);
	text-decoration: none;
}
.cs-seeall:hover,
.cs-seeall:focus {
	color: var(--wp--preset--color--blue-700);
	text-decoration: underline;
}
.cs-seeall svg { flex: 0 0 auto; }

/* ============================================================
   "El Canal en cifras" — rejilla de contadores (§export).
   Rejilla propia (patrón cs-filters): la rejilla manual de WP no
   colapsa en móvil. 5 → 3 (≤1024) → 2 (≤600) columnas.

   OJO CON EL SELECTOR: esta rejilla ya NO es un wp:group del patrón,
   la emite inc/portada.php como <div class="cs-stats-grid"> con las
   tarjetas dentro (recuentos en vivo). Los selectores iban prefijados
   con .wp-block-group y por eso el fondo blanco y el radio no llegaban
   a pintarse: mismo patrón que las tarjetas del Observatorio, el
   marcado server-side no lleva clases de bloque.
   ============================================================ */
.cs-stats-grid {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--4);
}
@media (max-width: 1024px) { .cs-stats-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px) { .cs-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Sin márgenes (ni del layout flow de WP ni del user-agent en los <p>)
   dentro de la rejilla ni de la tarjeta: el espaciado lo dan gap/padding. */
.cs-stats-grid > *,
.cs-stat-card > * { margin-block: 0; }

/* Tarjeta de contador (StatCard tone plain §export): blanca sobre la banda
   blue-50, radio xl — sin sombra ni borde, como manda el manual.
   Número h1/40 en blue-600 (§export; texto grande: 4,66:1 sobre blanco,
   AA ≥3:1).
   TEXTO A LA IZQUIERDA por regla del manual (§Dirección de diseño): las cifras se
   leen en columna y el borde izquierdo comun hace de guia. El export las centraba y
   asi estuvieron hasta el 2026-08-27; los contadores del Observatorio (.obs-counter)
   ya iban alineados a la izquierda, de modo que el cambio ademas iguala las dos
   paginas que muestran las mismas cifras. */
.cs-stat-card {
	background: var(--wp--custom--surface--card);
	border: 0;
	box-shadow: none;
	border-radius: var(--wp--custom--radius--xl);
	padding: var(--wp--preset--spacing--5);
	text-align: left;
}
.cs-stat-card .cs-stat-value {
	font-size: var(--wp--preset--font-size--h-1);
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--blue-600);
}
.cs-stat-card .cs-stat-label {
	margin-top: var(--wp--preset--spacing--2);
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--custom--text--muted);
}

/* Tarjeta de eje (Compromiso local). */
.cs-eje-card .cs-eje-num {
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--custom--text--muted);
}

/* ============================================================
   Tarjetas de listado (Listing Items) — reproducen ProjectCard
   y NewsCard. Las reglas comunes van con ambos selectores; lo
   que difiere (fila fecha · categoría de la noticia) va en el
   bloque .cs-news-card de más abajo.
   ============================================================ */
/* Radio xl (28px, §export) SOLO en las tarjetas de listado: el is-style-card
   global sigue en lg para el resto de páginas (empate 0,2,0 con la regla de
   is-style-card: gana esta por orden — va después en el archivo). */
.wp-block-group.cs-project-card,
.wp-block-group.cs-news-card { border-radius: var(--wp--custom--radius--xl); }
.cs-project-card,
.cs-news-card { display: flex; flex-direction: column; padding: 0; height: 100%; }
.cs-project-card__media,
.cs-news-card__media {
	aspect-ratio: 16 / 9; margin: var(--wp--preset--spacing--3) var(--wp--preset--spacing--3) 0;
	border-radius: var(--wp--custom--radius--md); overflow: hidden;
	background: var(--wp--custom--surface--tint);
}
.cs-project-card__media img,
.cs-news-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-project-card__media--empty,
.cs-news-card__media--empty {
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	/* QA a11y: blue-600 sobre el tinte del media daba 4,38:1, bajo el 4,5 de AA. */
	gap: 8px; height: 100%; color: var(--wp--preset--color--blue-700);
	font-size: var(--wp--preset--font-size--xs); font-weight: 600; text-transform: uppercase;
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
}
.cs-project-card__body,
.cs-news-card__body { padding: var(--wp--preset--spacing--5); display: flex; flex-direction: column; gap: 10px; flex: 1; }
.cs-project-card__meta { display: flex; align-items: center; gap: 10px; }
.cs-project-card__year { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-project-card__eje {
	font-size: var(--wp--preset--font-size--xs); font-weight: 600; color: var(--wp--custom--text--muted);
	text-transform: uppercase; letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
}
/* OJO: WordPress emite los presets con slug letra+dígito en kebab-case: la var
   real es …--h-3 (…--h3 no existe en el CSS compilado). Igual en theme.json. */
.cs-project-card__title,
.cs-news-card__title { margin: 0; font-size: var(--wp--preset--font-size--h-3); color: var(--wp--custom--text--heading); }
.cs-project-card__summary,
.cs-news-card__summary { margin: 0; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.55; }
.cs-project-card__ods,
.cs-news-card__ods { display: flex; flex-wrap: wrap; gap: 6px; }
.cs-project-card__ods { margin-top: 2px; } /* NewsCard.jsx no lleva ese margen */
.cs-project-card__more,
.cs-news-card__more { margin-top: auto; }
.cs-project-card__more { padding-top: 12px; }
.cs-news-card__more { padding-top: 8px; } /* §NewsCard.jsx (paddingTop 8 vs 12) */
.cs-project-card__more a,
.cs-news-card__more a { font-size: var(--wp--preset--font-size--sm); font-weight: 600; }

/* NewsCard: fila "fecha · categoría" en lugar de StatePill + año. La fila
   entera va en sm/muted (fecha y separador la heredan); la categoría destaca
   en text-strong (blue-700) seminegrita, como el componente del kit. */
.cs-news-card__meta {
	display: flex; align-items: center; gap: 8px;
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted);
}
.cs-news-card__date { white-space: nowrap; } /* la fecha no se parte ("12 marzo / 2026") */
.cs-news-card__cat { color: var(--wp--custom--text--strong); font-weight: 600; }
.cs-news-card__title { line-height: 1.25; }

/* StatePill (píldora de estado) — familia azul + neutro, sin verde. */
.cs-statepill { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px;
	border-radius: var(--wp--custom--radius--pill); font-size: var(--wp--preset--font-size--xs);
	font-weight: 600; line-height: 1; white-space: nowrap; }
.cs-statepill--en-curso  { background: var(--wp--custom--state--active-bg);  color: var(--wp--custom--state--active-ink); }
.cs-statepill--previsto  { background: var(--wp--custom--state--planned-bg); color: var(--wp--custom--state--planned-ink); }
.cs-statepill--realizado { background: var(--wp--custom--state--done-bg);    color: var(--wp--custom--state--done-ink); }
/* Archivado: variante neutra propia (spec §6) — distinguible de Previsto; slate-600 sobre slate-100 ~7:1 AA. */
.cs-statepill--archivado { background: var(--wp--preset--color--slate-100); color: var(--wp--preset--color--slate-600); }

/* Etiquetas ODS — color oficial + tinta AA por luminancia (texto xs/700 =
   "texto normal": exige 4,5:1). Contraste calculado color a color (Tarea 6):
   el blanco solo llega a 4,5 sobre 1/4/8/10/13/16/17 (ODS 1 justo: 4,52);
   el resto lleva tinta oscura #1a1a1a (todas ≥4,87 con ella). */
/* align-self:center centra la pastilla en su línea flex (defensivo). OJO: el descuadre real
   de las tarjetas (1ª pastilla estirada ~44px, o luego 12px por encima del resto) NO nace aquí,
   sino del block-gap de WP: los contenedores .cs-*__ods son grupos is-layout-flow y WP inyecta
   margin-block-start: spacing--6 (24px) en los hijos 2º+; bajo el display:flex del contenedor ese
   margen pasa a eje cruzado. Se neutraliza con el reset .cs-*__ods > * { margin-block: 0 } de abajo. */
.cs-ods { display: inline-flex; align-items: center; align-self: center; padding: 4px 9px; border-radius: var(--wp--custom--radius--pill);
	font-size: var(--wp--preset--font-size--xs); font-weight: 700; line-height: 1; white-space: nowrap; color: var(--wp--preset--color--white); }
.cs-ods--2, .cs-ods--3, .cs-ods--5, .cs-ods--6, .cs-ods--7, .cs-ods--9,
.cs-ods--11, .cs-ods--12, .cs-ods--14, .cs-ods--15 { color: #1a1a1a; }
.cs-ods--1 { background: var(--wp--preset--color--ods-1); }
.cs-ods--2 { background: var(--wp--preset--color--ods-2); }
.cs-ods--3 { background: var(--wp--preset--color--ods-3); }
.cs-ods--4 { background: var(--wp--preset--color--ods-4); }
.cs-ods--5 { background: var(--wp--preset--color--ods-5); }
.cs-ods--6 { background: var(--wp--preset--color--ods-6); }
.cs-ods--7 { background: var(--wp--preset--color--ods-7); }
.cs-ods--8 { background: var(--wp--preset--color--ods-8); }
.cs-ods--9 { background: var(--wp--preset--color--ods-9); }
.cs-ods--10 { background: var(--wp--preset--color--ods-10); }
.cs-ods--11 { background: var(--wp--preset--color--ods-11); }
.cs-ods--12 { background: var(--wp--preset--color--ods-12); }
.cs-ods--13 { background: var(--wp--preset--color--ods-13); }
.cs-ods--14 { background: var(--wp--preset--color--ods-14); }
.cs-ods--15 { background: var(--wp--preset--color--ods-15); }
.cs-ods--16 { background: var(--wp--preset--color--ods-16); }
.cs-ods--17 { background: var(--wp--preset--color--ods-17); }

/* Alineación de la fila de ODS en las tarjetas de relación (indicador/entidad/actividad).
   Sus contenedores .cs-*__ods son grupos is-layout-flow de WP → WP inyecta
   margin-block-start: var(--wp--preset--spacing--6) (24px) a cada pastilla 2ª en adelante
   (block-gap). Bajo el display:flex del contenedor ese margen se vuelve de eje cruzado: infla la
   línea y deja la 1ª pastilla descuadrada respecto al resto (escalón de 12px). Se neutraliza igual
   que ya se hace en project-card/news-card más abajo (línea ~538). Alturas iguales + margen 0 =
   alineadas por arriba, como el export. */
.cs-ind__ods > *,
.cs-entity__ods > *,
.cs-act__ods > * { margin-block: 0; }

/* --- Integración de la tarjeta con los bloques reales (JetEngine/Gutenberg) ---
   1) blocks-views envuelve cada bloque jet-engine en un div extra (data-is-block)
      que DUPLICA el className: se hace transparente al layout (display: contents)
      para que cada estilo pinte una sola vez, en el elemento interno del render.
   2) El layout "flow" de Gutenberg añade margin-block a los hijos de los grupos:
      dentro de la tarjeta el espaciado lo dan los gap/padding del diseño.
   3) El título es un dynamic-link con wrapper h3: el <a> hereda el color de
      titular (no el azul de enlace).
   4) El frontend.css de JetEngine fija width:auto en el img
      (.jet-listing-dynamic-image__img.wp-post-image, especificidad 0,2,0):
      dentro de la caja de media manda el encuadre 16:9 del diseño. */
.cs-project-card [data-is-block],
.cs-news-card [data-is-block] { display: contents; }
.cs-project-card__media img.jet-listing-dynamic-image__img,
.cs-news-card__media img.jet-listing-dynamic-image__img { width: 100%; }
.cs-project-card > *,
.cs-project-card__body > *,
.cs-project-card__meta > *,
.cs-project-card__ods > *,
.cs-news-card > *,
.cs-news-card__body > *,
.cs-news-card__meta > *,
.cs-news-card__ods > *,
.cs-project-card :where(p, h3),
.cs-news-card :where(p, h3) { margin-block: 0; }
.cs-project-card__title a,
.cs-news-card__title a { color: inherit; }
/* El reset de margin-block de arriba tambien alcanzaba al placeholder "Imagen
   pendiente", y solo a el: el render de JetEngine pinta en un div interno
   (dentro del wrapper [data-is-block]), mientras que el placeholder es HTML
   crudo y queda como HIJO DIRECTO de la tarjeta. Resultado: la caja se pegaba
   al borde superior (margin-top 0 en vez de 12px) y, con la tarjeta en radio xl
   (28px) y la caja en md (16px), sus esquinas asomaban FUERA de la tarjeta.
   Le devolvemos el margen del diseno; (0,2,0) gana al reset (0,1,0) sin
   depender del orden del archivo. margin-bottom sigue en 0, como toca. */
.cs-project-card > .cs-project-card__media,
.cs-news-card > .cs-news-card__media { margin-block-start: var(--wp--preset--spacing--3); }


/* ============================================================
   RedEntityCard (Listing Item `entidad-red-card`) — tarjeta del
   directorio /red/: VERTICAL, imagen 16:9 arriba (como news-card),
   tintada (is-style-card-tint), radio xl. Distinta de la entidad-card
   (#172) horizontal de la banda del single-proyecto. Sin resumen ni ODS.
   ============================================================ */
.wp-block-group.cs-redcard-card { border-radius: var(--wp--custom--radius--xl); }
.cs-redcard-card { display: flex; flex-direction: column; padding: 0; height: 100%; }
.cs-redcard-card [data-is-block] { display: contents; }
.cs-redcard { display: flex; flex-direction: column; gap: 10px; padding: var(--wp--preset--spacing--5); flex: 1; }
.cs-redcard > * { margin-block: 0; }
.cs-redcard__media, .cs-redcard__ph { border-radius: var(--wp--custom--radius--md); overflow: hidden; aspect-ratio: 16 / 9; }
.cs-redcard__media img.jet-listing-dynamic-image__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-redcard__ph { display: flex; align-items: center; justify-content: center; background: var(--wp--preset--color--blue-100); color: var(--wp--custom--text--muted); font-size: var(--wp--preset--font-size--sm); font-weight: 600; }
.cs-redcard__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.cs-redcard__tags > * { margin-block: 0; } /* reset block-gap WP en la fila de pastillas */
.cs-redcard__type { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: var(--wp--custom--radius--pill); background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-700); font-size: var(--wp--preset--font-size--xs); font-weight: 500; line-height: 1; }
.cs-redcard__type .jet-listing-dynamic-terms, .cs-redcard__type .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
.cs-redcard__title { margin: 0; font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); line-height: 1.25; }
.cs-redcard__title a { color: inherit; }
.cs-redcard__loc { display: flex; align-items: center; gap: 5px; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-redcard__loc > * { margin-block: 0; }
.cs-redcard__loc .jet-listing-dynamic-terms, .cs-redcard__loc .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
.cs-redcard__pin { display: inline-flex; flex: 0 0 auto; }
.cs-redcard__more { margin-top: auto; padding-top: 6px; }
.cs-redcard__more a { display: inline-flex; align-items: center; gap: 6px; color: var(--wp--preset--color--blue-700); font-weight: 600; font-size: var(--wp--preset--font-size--sm); text-decoration: none; }
.cs-redcard__more a::after { content: "\2192"; }

/* ============================================================
   Tarjeta de recurso (Listing Item) — reproduce ResourceCard.
   Tintada (is-style-card-tint), SIN imagen; radio xl como el
   resto de tarjetas de listado.
   ============================================================ */
.wp-block-group.cs-resource-card { border-radius: var(--wp--custom--radius--xl); }
.cs-resource-card { display: flex; flex-direction: column; padding: 0; height: 100%; }
.cs-resource-card__body { padding: var(--wp--preset--spacing--5); display: flex; flex-direction: column; gap: 10px; flex: 1; }
/* Tipo: etiqueta sutil (no pill), azul corporativo. */
.cs-resource-card__type { font-size: var(--wp--preset--font-size--sm); font-weight: 600; color: var(--wp--preset--color--blue-700); }
.cs-resource-card__title { margin: 0; font-size: var(--wp--preset--font-size--h-3); color: var(--wp--custom--text--heading); line-height: 1.25; }
.cs-resource-card__meta { margin: 0; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-resource-card__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 2px; }
/* Eje: pastilla neutra (slate), tras las pills ODS. */
.cs-resource-card__eje { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--slate-100); color: var(--wp--preset--color--slate-700);
	font-size: var(--wp--preset--font-size--xs); font-weight: 600; line-height: 1; }
.cs-resource-card__actions { margin-top: auto; padding-top: 12px; }
/* Botón "Ver": píldora azul sólida con flecha (fiel al export), ≥44px. */
.cs-resource-card__actions a { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 var(--wp--preset--spacing--5);
	background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white);
	border-radius: var(--wp--custom--radius--pill);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--sm); font-weight: 600; text-decoration: none; }
.cs-resource-card__actions a::after { content: "\2197"; font-size: 1.05em; line-height: 1; } /* ↗ */
.cs-resource-card__actions a:hover,
.cs-resource-card__actions a:focus-visible { background: var(--wp--preset--color--blue-700); }
/* "PDF pendiente de subir": estado no disponible, neutro. */
.cs-resource-card__pending { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--wp--preset--spacing--4);
	color: var(--wp--custom--text--muted); font-size: var(--wp--preset--font-size--sm); font-weight: 600; }
/* Integración con los bloques reales (mismo patrón que project/news card). */
.cs-resource-card [data-is-block] { display: contents; }
.cs-resource-card > *,
.cs-resource-card__body > *,
.cs-resource-card__tags > *,
.cs-resource-card__actions > *,
.cs-resource-card :where(p, h3) { margin-block: 0; }
.cs-resource-card__title a { color: inherit; }
/* Buscador dentro de la barra plana (Recursos): relleno blue-50, coherente con los selects plana. */
.cs-filters--plana .cs-filters__search { background: var(--wp--preset--color--blue-50); }

/* ============================================================
   Barra de filtros de listados (§5bis + panel tintado §export).
   ============================================================ */
/* Panel: masa blue-50, radio xxl (36px) y padding 24 — sin sombra ni borde. */
.cs-filters {
	display: flex; flex-direction: column; gap: var(--wp--preset--spacing--5);
	background: var(--wp--preset--color--blue-50);
	border-radius: var(--wp--custom--radius--xxl);
	padding: var(--wp--preset--spacing--6);
	margin-bottom: var(--wp--preset--spacing--8);
}
.cs-filters__row { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--wp--preset--spacing--4); }

/* Búsqueda: píldora blanca con lupa (§export) — el input JSF va dentro,
   transparente y sin borde; el foco visible lo lleva la píldora entera. */
.cs-filters__search {
	display: flex; align-items: center; gap: 10px;
	height: 48px; padding: 0 var(--wp--preset--spacing--5);
	background: var(--wp--preset--color--white);
	border-radius: var(--wp--custom--radius--pill);
}
.cs-filters__search > svg { flex: 0 0 auto; color: var(--wp--preset--color--blue-600); }
.cs-filters__search .jet-filter,
.cs-filters__search .jet-search-filter,
.cs-filters__search .jet-search-filter__input-wrapper { flex: 1 1 auto; min-width: 0; }
.cs-filters__search:focus-within {
	outline: 2px solid var(--wp--preset--color--blue-600);
	outline-offset: 2px;
}
.cs-filters .jet-search-filter__input {
	width: 100%; height: 46px; border: 0; background: transparent;
	color: var(--wp--custom--text--body);
	font-family: var(--wp--preset--font-family--jakarta);
	font-size: var(--wp--preset--font-size--body);
	padding: 0;
}
.cs-filters .jet-search-filter__input:focus,
.cs-filters .jet-search-filter__input:focus-visible { outline: none; } /* el anillo lo pinta la píldora (focus-within) */

/* Selects: blancos, radio md (16px), sin borde, ≥44px táctil. El tercer
   selector (0,2,1) es necesario: el public.css de JSF declara
   `.jet-smart-filters-select .jet-select__control { min-height: auto }` (0,2,0)
   y pisaría el objetivo táctil con solo `.cs-filters select` (0,1,1).
   appearance none + chevron SVG azul (como el export). */
.cs-filters select,
.cs-filters select.jet-select__control {
	width: 100%; min-height: 46px; border: 0;
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--custom--text--body);
	padding: 0 40px 0 14px;
	font-family: var(--wp--preset--font-family--jakarta);
	font-size: var(--wp--preset--font-size--body);
	appearance: none; -webkit-appearance: none;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23346bc8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
	background-repeat: no-repeat;
	background-position: right 14px center;
}
/* Recuento: 16px cuerpo, número en negrita (§export). */
.cs-filters__count { font-size: var(--wp--preset--font-size--body); color: var(--wp--custom--text--body); }
.cs-filters__count strong { font-weight: 700; }
@media (max-width: 1024px) { .cs-filters__row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) {
	.cs-filters { padding: var(--wp--preset--spacing--4); border-radius: var(--wp--custom--radius--lg); }
	.cs-filters__row { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------
   Variante PLANA de la barra (archivo de Actualidad).
   El export de Actualidad NO usa el panel tintado de Proyectos:
   3 selects con etiqueta encima sobre el fondo blanco de página,
   sin buscador. Reutiliza .cs-filters y solo anula el panel,
   pasa la rejilla a 3 y da a los selects el relleno blue-50
   (en Proyectos van blancos porque el panel hace de fondo). */
.cs-filters--plana {
	background: transparent;
	border-radius: 0;
	padding: 0;
}
.cs-filters--plana .cs-filters__row { grid-template-columns: repeat(3, 1fr); }
.cs-filters--plana select,
.cs-filters--plana select.jet-select__control {
	background-color: var(--wp--preset--color--blue-50);
}
@media (max-width: 1024px) { .cs-filters--plana .cs-filters__row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) {
	.cs-filters--plana { padding: 0; border-radius: 0; }
	.cs-filters--plana .cs-filters__row { grid-template-columns: 1fr; }
}

/* Añadidos justificados a la CSS del brief: */
/* 1) Los grupos de la barra van sin layout de WP; se neutraliza el margin-block
      del layout "flow" (mismo patrón que la tarjeta) — el espaciado lo dan los gap.
      Con .wp-block-group delante (0,2,0): la regla de Gutenberg
      `.wp-block-group-is-layout-flow > * + *` (0,1,0) se imprime DESPUÉS del
      theme.css y ganaría el empate a `.cs-filters__row > *`. */
.wp-block-group.cs-filters > *, .wp-block-group.cs-filters__row > *,
.wp-block-group.cs-filters__search > * { margin-block: 0; }
/* …y el `.jet-filter + .jet-filter { margin-top: 10px }` del public.css de JSF
      (0,2,0, cargado después): dentro de la barra manda el gap de la rejilla. */
.cs-filters .jet-filter + .jet-filter { margin-top: 0; }
/* 2) Etiqueta visible de cada filtro (show_label del bloque JSF pinta
      .jet-filter-label con el _filter_label; el mismo texto va en el aria-label
      del control: nombre visible = nombre accesible). */
.cs-filters .jet-filter-label {
	display: block; margin-bottom: 6px;
	font-size: var(--wp--preset--font-size--sm); font-weight: 600;
	color: var(--wp--custom--text--body); /* slate-700, como la etiqueta del export */
}
/* 3) El recuento lo pinta functions.php DENTRO del wrapper del listing grid
      (la zona que JSF reemplaza en cada AJAX): margen propio al no vivir ya
      en .cs-filters. */
.jet-listing-grid > .cs-filters__count { margin: 0 0 var(--wp--preset--spacing--5); }
/* 4) "Quitar filtros": fantasma discreto (réplica del is-style-ghost del tema);
      JSF lo oculta (clase hide) hasta que hay filtros activos. */
.cs-filters .jet-remove-all-filters__button {
	min-height: 44px; padding: 0 var(--wp--preset--spacing--6);
	background: transparent; color: var(--wp--preset--color--blue-700);
	border: 1.5px solid var(--wp--preset--color--blue-200); border-radius: var(--wp--custom--radius--pill);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--sm);
	font-weight: 600; cursor: pointer;
}
.cs-filters .jet-remove-all-filters__button:hover,
.cs-filters .jet-remove-all-filters__button:focus {
	background: var(--wp--preset--color--blue-50); border-color: var(--wp--preset--color--blue-600);
}
/* 5) Paginación JSF (bloque jet-smart-filters/pagination bajo la rejilla):
      objetivos táctiles >=44px, tokens del tema, actual en azul corporativo. */
.jet-filters-pagination {
	display: flex; flex-wrap: wrap; justify-content: center;
	gap: var(--wp--preset--spacing--2); margin-top: var(--wp--preset--spacing--8);
}
.jet-filters-pagination__link {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 44px; min-height: 44px; padding: 0 var(--wp--preset--spacing--3);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--slate-50); color: var(--wp--custom--text--body);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--sm);
	font-weight: 600; cursor: pointer;
}
.jet-filters-pagination__link:hover { background: var(--wp--preset--color--blue-50); }
.jet-filters-pagination__current .jet-filters-pagination__link {
	background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white); cursor: default;
}

/* 6) Región aria-live persistente del recuento (cs-filters-live.js): vive FUERA
      del wrapper que JSF reemplaza y va oculta visualmente (el recuento visible
      lo pinta functions.php dentro del wrapper). Regla propia para no depender
      del .screen-reader-text que imprime el core. */
.screen-reader-text,
.cs-filters__live {
	position: absolute !important;
	width: 1px; height: 1px;
	margin: -1px; border: 0; padding: 0;
	clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* ============================================================
   Fichas de detalle (single-noticia / single-recurso) §export 27/28.
   Cabecera de artículo, chips grandes (OdsTag/Tag), imagen destacada,
   columna de lectura y prosa. El CSS del layout 2-col + DocumentCard
   del recurso va en su propio bloque (Tarea 3).
   Contraste ODS: MISMO tinte por luminancia AA que .cs-ods.
   ============================================================ */

/* Migas: separador y nivel actual (pulido común; también mejora los archivos).
   Migas renderizadas por el shortcode [cs_crumbs] (E1): nav válida, un solo <span>
   para el nivel actual — sin regla-parche del <div> del dynamic-field. */
.cs-crumbs__sep { color: var(--wp--preset--color--blue-300); }
.cs-crumbs [aria-current] { color: var(--wp--custom--text--body); }
.cs-crumbs__current { font-weight: 500; }

/* Cabecera de artículo (columna de lectura 760). */
.cs-article-head { padding-top: var(--wp--preset--spacing--10); }
.cs-article-head .cs-eyebrow { display: block; margin: var(--wp--preset--spacing--3) 0 0; }
.cs-article-head__title {
	margin: var(--wp--preset--spacing--3) 0 0;
	font-size: var(--wp--preset--font-size--display);
	line-height: var(--wp--custom--typography--lh-tight);
	color: var(--wp--custom--text--heading);
}

/* Fila de metadatos (fecha · categoría / tipo · año). */
.cs-meta {
	display: flex; flex-wrap: wrap; align-items: center; gap: var(--wp--preset--spacing--2);
	margin-top: var(--wp--preset--spacing--5);
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted);
}
.cs-meta > * { margin-block: 0; }
.cs-meta [data-is-block] { display: contents; }
.cs-meta .cs-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--wp--preset--color--blue-300); }
/* dynamic-terms de la meta hereda color/peso (no el azul de enlace). */
.cs-meta .jet-listing-dynamic-terms,
.cs-meta .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }

/* Fila de chips (OdsTag grande + Tag de eje). Todos son spans gateados por Dynamic Visibility
   (post-has-terms), así que se pintan directamente como pastillas: no queda wrapper de bloque
   (data-is-block) que colapsar dentro de .cs-chips (E2). */
.cs-chips { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--2); margin-top: var(--wp--preset--spacing--5); }
.cs-chips > * { margin-block: 0; }
/* El bloque wp:shortcode [cs_ods_pills] puede envolver sus <a> inline en <p> (wpautop): lo hacemos
   transparente al flex para que cada pastilla sea un item directo de .cs-chips (gap 8px intacto). */
.cs-chips :where(.wp-block-shortcode, p) { display: contents; }

/* OdsTag GRANDE: variante mayor que la pill de tarjeta (.cs-ods), MISMO color oficial +
   MISMO tinte por luminancia AA (subconjunto de tinta oscura idéntico). Tamaño md del
   componente OdsTag del design system (fs-sm / 6px 12px). */
.cs-odstag {
	display: inline-flex; align-items: center; align-self: center; gap: 6px; padding: 6px 12px;
	border-radius: var(--wp--custom--radius--pill); font-size: var(--wp--preset--font-size--sm);
	font-weight: 700; line-height: 1; white-space: nowrap;
	color: var(--cs-odstag-ink, var(--wp--preset--color--white));
}
.cs-odstag--2, .cs-odstag--3, .cs-odstag--5, .cs-odstag--6, .cs-odstag--7, .cs-odstag--9,
.cs-odstag--11, .cs-odstag--12, .cs-odstag--14, .cs-odstag--15 { --cs-odstag-ink: #1a1a1a; }
/* Estado enlace (solo en las fichas: [cs_ods_pills] pinta <a> a /ods/{slug}/). Conserva la MISMA
   tinta AA (blanco / #1a1a1a por luminancia, ya en --cs-odstag-ink) y neutraliza el color/subrayado
   de enlace de theme.json (elements.link: blue-600 + underline en hover). a.cs-odstag (0,1,1) gana a
   :root :where(a) (0,1,0) en todos los estados. */
a.cs-odstag,
a.cs-odstag:hover,
a.cs-odstag:focus {
	color: var(--cs-odstag-ink, var(--wp--preset--color--white));
	text-decoration: none;
}
.cs-odstag--1  { background: var(--wp--preset--color--ods-1); }
.cs-odstag--2  { background: var(--wp--preset--color--ods-2); }
.cs-odstag--3  { background: var(--wp--preset--color--ods-3); }
.cs-odstag--4  { background: var(--wp--preset--color--ods-4); }
.cs-odstag--5  { background: var(--wp--preset--color--ods-5); }
.cs-odstag--6  { background: var(--wp--preset--color--ods-6); }
.cs-odstag--7  { background: var(--wp--preset--color--ods-7); }
.cs-odstag--8  { background: var(--wp--preset--color--ods-8); }
.cs-odstag--9  { background: var(--wp--preset--color--ods-9); }
.cs-odstag--10 { background: var(--wp--preset--color--ods-10); }
.cs-odstag--11 { background: var(--wp--preset--color--ods-11); }
.cs-odstag--12 { background: var(--wp--preset--color--ods-12); }
.cs-odstag--13 { background: var(--wp--preset--color--ods-13); }
.cs-odstag--14 { background: var(--wp--preset--color--ods-14); }
.cs-odstag--15 { background: var(--wp--preset--color--ods-15); }
.cs-odstag--16 { background: var(--wp--preset--color--ods-16); }
.cs-odstag--17 { background: var(--wp--preset--color--ods-17); }

/* Tag de eje (tono "blue" del componente Tag): pastilla blue-100 / blue-700 (E2). Ahora es un
   <span> gateado por Dynamic Visibility (post-has-terms sobre `eje`), igual que los OdsTag —
   se pinta directamente como pastilla, sin wrapper de dynamic-terms. Formato "EJE 0X · Nombre"
   fiel al PNG 28. Sin white-space:nowrap: el rótulo del eje es largo y en móvil (390) debe poder
   envolver dentro de la pastilla en vez de desbordar (requisito overflow horizontal = 0). */
.cs-tag {
	display: inline-flex; align-items: center; padding: 6px 12px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-700);
	font-size: var(--wp--preset--font-size--sm); font-weight: 500; line-height: 1;
}

/* Eyebrow/chip de eje ENLAZADO a /eje/{slug}/ ([cs_eje_eyebrow]): conserva el color exacto de cada
   contexto (muted en la tarjeta de proyecto; blue-700 en la ficha de proyecto y en el chip de
   recurso/noticia) y neutraliza el azul + subrayado de enlace de theme.json (elements.link); el
   subrayado aparece solo en hover/focus como afordancia. a.CLASS (0,1,1) gana a :root :where(a)
   (0,1,0), igual que a.cs-odstag. */
a.cs-project-card__eje { color: var(--wp--custom--text--muted); text-decoration: none; }
a.cs-phead__eyebrow    { color: var(--wp--preset--color--blue-700); text-decoration: none; }
a.cs-tag               { color: var(--wp--preset--color--blue-700); text-decoration: none; }
a.cs-project-card__eje:hover, a.cs-project-card__eje:focus-visible,
a.cs-phead__eyebrow:hover,    a.cs-phead__eyebrow:focus-visible,
a.cs-tag:hover,               a.cs-tag:focus-visible { text-decoration: underline; }

/* Imagen destacada (alignfull; radio 2xl=36). El inset lateral de 16px lo da la REGLA DE MARCA
   global (.has-global-padding > .alignfull:not(.cs-bleed)) — antes el margin-inline:16px propio
   lo pisaba la regla root-padding-aware de WP (.alignfull a -24px) y la foto tocaba el borde.
   El frontend.css de JetEngine fija width:auto en la imagen (0,2,0): se le devuelve el 100%. */
.cs-feat {
	margin-top: var(--wp--preset--spacing--10);
	border-radius: var(--wp--custom--radius--xxl); overflow: hidden;
}
.cs-feat [data-is-block] { display: contents; }
.cs-feat img { width: 100%; height: clamp(280px, 46vw, 560px); object-fit: cover; display: block; }
.cs-feat img.jet-listing-dynamic-image__img.wp-post-image { width: 100%; }
.cs-feat__empty {
	display: flex; align-items: center; justify-content: center; min-height: clamp(280px, 40vw, 480px);
	background: var(--wp--custom--surface--tint); color: var(--wp--preset--color--blue-700);
	font-size: var(--wp--preset--font-size--eyebrow); letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
	text-transform: uppercase; font-weight: 600;
}

/* Columna de lectura / cuerpo (prosa del post-content). Compartida con .cs-desc (recurso). */
.cs-read { padding-top: var(--wp--preset--spacing--10); }
.cs-read .wp-block-post-content > p,
.cs-desc .wp-block-post-content > p {
	font-size: var(--wp--preset--font-size--body); line-height: 1.7;
	color: var(--wp--custom--text--body); margin: 0 0 var(--wp--preset--spacing--5);
}
.cs-read .wp-block-post-content > h2,
.cs-desc .wp-block-post-content > h2 {
	font-size: var(--wp--preset--font-size--h-3); color: var(--wp--custom--text--heading);
	margin: var(--wp--preset--spacing--8) 0 var(--wp--preset--spacing--3);
}
/* Entradilla: el primer párrafo del cuerpo va en lead (19). Si el redactor abre con un h2 no
   aplica (correcto). */
.cs-read .wp-block-post-content > p:first-child,
.cs-desc .wp-block-post-content > p:first-child {
	font-size: var(--wp--preset--font-size--lead); line-height: 1.5;
	margin-bottom: var(--wp--preset--spacing--6);
}

/* ============================================================
   Ficha de recurso: layout 2-col + DocumentCard oscuro §export 28.
   ============================================================ */

/* Detalle: principal + aside 360 (colapsa a 1 col ≤900). Rejilla por CSS (grupo con clase,
   sin layout de WP); se neutraliza el margin-block del flow. */
.cs-detail {
	display: grid; grid-template-columns: minmax(0, 1fr) 360px;
	gap: var(--wp--preset--spacing--10); align-items: start;
	padding-top: var(--wp--preset--spacing--10);
}
.cs-detail > * { margin-block: 0; }

.cs-doc-head__title {
	margin: var(--wp--preset--spacing--3) 0 0;
	font-size: var(--wp--preset--font-size--h-1);
	line-height: var(--wp--custom--typography--lh-tight);
	color: var(--wp--custom--text--heading);
}
.cs-desc { max-width: var(--wp--custom--container-text, 760px); margin-top: var(--wp--preset--spacing--8); }

/* DocumentCard (masa azul-900, texto claro). */
.cs-doc {
	position: sticky; top: 96px;
	background: var(--wp--custom--mass--dark); color: var(--wp--preset--color--blue-100);
	border-radius: var(--wp--custom--radius--xxl); padding: var(--wp--preset--spacing--8);
}
.cs-doc > * { margin-block: 0; }
.cs-doc [data-is-block] { display: contents; }
/* Eyebrow "Documento": azul decorativo sobre fondo oscuro (excepción tolerada). */
.cs-doc__eyebrow {
	font-size: var(--wp--preset--font-size--eyebrow); text-transform: uppercase;
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow); font-weight: 600;
	color: var(--wp--preset--color--blue-400); margin: 0 0 var(--wp--preset--spacing--5);
}
/* Fila formato·tamaño. */
.cs-doc__file { display: flex; align-items: center; gap: var(--wp--preset--spacing--4); }
.cs-doc__icon {
	flex: 0 0 auto; width: 52px; height: 52px; border-radius: var(--wp--custom--radius--md);
	background: rgba(98, 191, 238, 0.16); color: var(--wp--preset--color--blue-200);
	display: flex; align-items: center; justify-content: center;
}
.cs-doc__filemeta { display: block; }
.cs-doc__fmt {
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600;
	letter-spacing: var(--wp--custom--typography--tracking-tight); color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--h-4); margin: 0; line-height: 1.1;
}
.cs-doc__size { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--blue-200); margin: 2px 0 0; }
/* Divisor. */
.cs-doc__rule { height: 1px; background: rgba(255, 255, 255, 0.12); margin: var(--wp--preset--spacing--6) 0; border: 0; }
/* Metadatos: filas etiqueta→valor (equivalente robusto al <dl> del export). */
.cs-doc__rows { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--3); margin: 0 0 var(--wp--preset--spacing--6); }
.cs-doc__rows > * { margin-block: 0; }
.cs-doc__row { display: flex; justify-content: space-between; gap: var(--wp--preset--spacing--4); font-size: var(--wp--preset--font-size--sm); }
.cs-doc__row > * { margin-block: 0; }
.cs-doc__dt { color: var(--wp--preset--color--blue-200); }
.cs-doc__dd, .cs-doc__dd a { color: var(--wp--preset--color--white); font-weight: 500; text-align: right; }
.cs-doc__pub { text-transform: capitalize; } /* "Diciembre 2024" (fiel al export). */
/* Acciones: "Ver" y "PDF pendiente" = píldoras a ANCHO COMPLETO del DocumentCard, ≥44px (fiel al PNG 28).
   JetEngine aplica la className del dynamic-link a sus DOS divs wrapper (bloque + .jet-listing), NO al
   <a>: se estiliza el <a> (.jet-listing-dynamic-link__link) para que la píldora sea un único elemento
   clicable a ancho completo y con UNA sola flecha (el ::after sobre .cs-doc__btn--view se pintaba
   duplicado — una vez en el wrapper display:contents y otra en el interno). El wrapper interno pasa a
   bloque de ancho completo; el externo queda display:contents (regla .cs-doc [data-is-block]). */
.cs-doc__actions { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--3); }
.cs-doc__btn--view.jet-listing-dynamic-link { display: block; }
.cs-doc__btn--view .jet-listing-dynamic-link__link {
	display: flex; align-items: center; justify-content: center; gap: 8px;
	min-height: 44px; padding: 0 var(--wp--preset--spacing--5);
	background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white);
	border-radius: var(--wp--custom--radius--pill);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--sm);
	font-weight: 600; text-decoration: none;
}
.cs-doc__btn--view .jet-listing-dynamic-link__link::after { content: "\2197"; font-size: 1.05em; line-height: 1; }
.cs-doc__btn--view .jet-listing-dynamic-link__link:hover,
.cs-doc__btn--view .jet-listing-dynamic-link__link:focus-visible { background: var(--wp--preset--color--blue-700); }
/* "PDF pendiente de subir": estado no disponible (cream), misma píldora a ancho completo. */
.cs-doc__pending {
	display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 16px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--custom--state--review-bg); color: var(--wp--custom--state--review-ink);
	font-size: var(--wp--preset--font-size--sm); font-weight: 600;
}

@media (max-width: 900px) {
	.cs-detail { grid-template-columns: 1fr; }
	.cs-doc { position: static; }
}

/* ============================================================
   Ficha de proyecto — tarjetas de relación (rebanada 6).
   AvanceCard (indicador) · EntityCard (entidad) · ActivityCard (actividad).
   Traducidas de los componentes del design system + export decodificado.
   Cajas sin sombra/borde; ODS con tinte AA reusado.
   ============================================================ */

/* Radio xl (28) como el resto de tarjetas de listado. */
.wp-block-group.cs-ind-card,
.wp-block-group.cs-entity-card,
.wp-block-group.cs-act-card { border-radius: var(--wp--custom--radius--xl); }
.cs-ind-card, .cs-entity-card, .cs-act-card { height: 100%; }
.cs-ind-card [data-is-block],
.cs-entity-card [data-is-block],
.cs-act-card [data-is-block] { display: contents; }
.cs-ind-card :where(p, h3, div),
.cs-entity-card :where(p, h3),
.cs-act-card :where(p, h3) { margin-block: 0; }

/* --- AvanceCard (indicador) --- */
.cs-ind { display: flex; flex-direction: column; gap: 10px; padding: var(--wp--preset--spacing--5); height: 100%; }
.cs-ind > * { margin-block: 0; }
.cs-ind__ods { display: flex; flex-wrap: wrap; gap: 6px; }
.cs-ind__title {
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600;
	font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading);
	line-height: 1.25; letter-spacing: var(--wp--custom--typography--tracking-tight);
}
.cs-ind__metric { display: flex; align-items: baseline; gap: 8px; }
.cs-ind__metric > * { margin-block: 0; }
.cs-ind__metric .v {
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600; font-size: 2rem;
	line-height: 1; color: var(--wp--preset--color--blue-600); letter-spacing: var(--wp--custom--typography--tracking-tight);
}
.cs-ind__metric .u { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); font-weight: 500; }
/* ProgressMeter ([cs_progress]) — pista blanca + borde inset blue-100, relleno degradado. */
.cs-ind__meter { display: block; margin-top: 2px; }
.cs-ind__meter-top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.cs-ind__meter-label { font-size: var(--wp--preset--font-size--sm); font-weight: 500; color: var(--wp--custom--text--body); }
.cs-ind__meter-val { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); white-space: nowrap; }
.cs-ind__meter-val strong { font-family: var(--wp--preset--font-family--jakarta); font-weight: 600; color: var(--wp--preset--color--blue-700); }
.cs-ind__bar {
	position: relative; height: 12px; border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--white); box-shadow: inset 0 0 0 1px var(--wp--preset--color--blue-100);
	overflow: hidden;
}
.cs-ind__fill {
	display: block; height: 100%; border-radius: var(--wp--custom--radius--pill);
	background: linear-gradient(90deg, var(--wp--preset--color--blue-600), var(--wp--preset--color--blue-400));
}
.cs-ind__pct { margin-top: 6px; text-align: right; font-size: var(--wp--preset--font-size--xs); font-weight: 600; color: var(--wp--custom--text--strong); }

/* --- EntityCard (entidad) --- */
.cs-entity { display: flex; flex-direction: column; gap: 11px; padding: var(--wp--preset--spacing--5); height: 100%; }
.cs-entity > * { margin-block: 0; }
/* Cabecera: logo/monograma (izq) + StatePill (der) en la MISMA fila, alineados arriba
   (decisión propietario 2026-07-13; el export los apilaba). El reset margin-block de los
   hijos evita que el block-gap de WP (grupo is-layout-flow) baje la pastilla, como pasaba
   en las filas de ODS. */
.cs-entity__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.cs-entity__head > * { margin-block: 0; }
.cs-entity__logowrap { display: flex; }
/* Reset del block-gap también DENTRO del logowrap: con hide_if_empty el logo deja un nodo
   vacío como :first-child, así que el monograma es el 2º hijo y WP le mete margin-block-start
   (24px) que lo bajaba respecto a la pastilla. */
.cs-entity__logowrap > * { margin-block: 0; }
.cs-entity__statewrap { display: flex; justify-content: flex-end; }
.cs-entity__id { display: flex; flex-direction: column; gap: 8px; }
.cs-entity__id > * { margin-block: 0; }
.cs-entity__logo img,
.cs-entity__mono { align-self: flex-start; }
.cs-entity__logo img { height: 96px; width: auto; max-width: 100%; object-fit: contain; }
.cs-entity__mono {
	width: 96px; height: 96px; border-radius: var(--wp--custom--radius--md); flex: 0 0 auto;
	display: inline-flex; align-items: center; justify-content: center;
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-700);
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600; font-size: 44px;
}
.cs-entity__cat {
	font-size: var(--wp--preset--font-size--xs); font-weight: 600; color: var(--wp--custom--text--muted);
	text-transform: uppercase; letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
}
.cs-entity__name {
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600;
	font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); line-height: 1.2;
}
.cs-entity__name a { color: inherit; text-decoration: none; } /* nombre enlazado al single /red/{slug}/: hereda color de titular */
.cs-entity__loc { display: flex; align-items: center; gap: 5px; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-entity__loc > * { margin-block: 0; }
.cs-entity__loc .jet-listing-dynamic-terms,
.cs-entity__loc .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
.cs-entity__pin { display: inline-flex; flex: 0 0 auto; }
.cs-entity__summary { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.55; }
.cs-entity__ods { display: flex; flex-wrap: wrap; gap: 6px; }

/* --- ActivityCard (actividad) --- */
.cs-act { display: flex; flex-direction: column; gap: 10px; padding: var(--wp--preset--spacing--5); height: 100%; }
.cs-act > * { margin-block: 0; }
.cs-act__date { display: flex; align-items: center; gap: 6px; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-act__date > * { margin-block: 0; }
.cs-act__cal { display: inline-flex; flex: 0 0 auto; }
/* Mes abreviado en minúscula, fiel al export ("10 feb 2026", no "10 Feb 2026"):
   jet_engine_date "j M Y" emite el mes capitalizado en es_ES; solo el valor. */
.cs-act__datev { text-transform: lowercase; }
/* Colectivo como Tag azul: el dynamic-terms colapsa su wrapper; se pinta el nodo interno. */
.cs-act__coltag { display: flex; }
.cs-act__coltag .jet-listing-dynamic-terms {
	display: inline-flex; align-items: center; padding: 6px 12px; border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-700);
	font-size: var(--wp--preset--font-size--sm); font-weight: 500; line-height: 1;
}
.cs-act__coltag .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
.cs-act__title { margin: 0; font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); line-height: 1.3; }
.cs-act__ods { display: flex; flex-wrap: wrap; gap: 6px; }

/* --- StatePill: variantes de adhesión (entidad) --- */
/* Adherida = tono "done" (azul); Interesada = tono "active" (blue-100), como StatePill.jsx. */
.cs-statepill--adherida   { background: var(--wp--custom--state--done-bg);   color: var(--wp--custom--state--done-ink); }
.cs-statepill--interesada { background: var(--wp--custom--state--active-bg); color: var(--wp--custom--state--active-ink); }

/* ============================================================
   Ficha de proyecto — cabecera, imagen 21:9, layout, sidebar, goals,
   secciones de relación (rebanada 6). Traducido del export decodificado.
   ============================================================ */

/* Cabecera: bloque alignwide normal → su borde izquierdo coincide EXACTO con el del cuerpo
   (.cs-layout/.cs-body) y con las migas (envueltas en un grupo alignwide en la plantilla).
   Antes fijaba max-width:900 + margin-inline-start:0, pero el margin:auto !important del layout
   constrained de WP lo CENTRABA (no lo alineaba a la izquierda), dejándolo a ~182px mientras el
   cuerpo quedaba a ~32px. El ancho de lectura ~900 se limita ahora en el título. */
.wp-block-group.cs-phead { padding-top: var(--wp--preset--spacing--5); }
.cs-phead__eyebrow {
	font-size: var(--wp--preset--font-size--eyebrow); text-transform: uppercase;
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow); font-weight: 600;
	color: var(--wp--preset--color--blue-700); margin: 0;
}
.cs-phead__title {
	margin: 14px 0 0; max-width: 900px; font-size: var(--wp--preset--font-size--display);
	line-height: var(--wp--custom--typography--lh-tight); color: var(--wp--custom--text--heading);
}
.cs-phead__row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: var(--wp--preset--spacing--5); }
.cs-phead__row > * { margin-block: 0; }
.cs-phead__row [data-is-block] { display: contents; }
.cs-phead .cs-meta { display: inline-flex; align-items: center; gap: 6px; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-phead__year, .cs-phead__loc { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }
.cs-phead__year .jet-listing-dynamic-terms,
.cs-phead__loc .jet-listing-dynamic-terms,
.cs-phead__year .jet-listing-dynamic-terms a,
.cs-phead__loc .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
.cs-meta__ic { display: inline-flex; }
.cs-phead__ods { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--wp--preset--spacing--5); }
.cs-phead__ods > * { margin-block: 0; }
.cs-phead__ods :where(.wp-block-shortcode, p) { display: contents; }

/* Imagen destacada 21:9 (alignfull inset 16 por la regla de gutter global). Radio 36.
   La img va en position:absolute + inset:0 para LLENAR el marco: con height:100% en flujo el
   porcentaje NO resuelve contra un contenedor dimensionado solo por aspect-ratio (altura
   indefinida) y ganaba la ratio intrínseca de los atributos width/height (dejaba franja). El
   posicionamiento absoluto neutraliza esa ratio → cover + center siempre, sea cual sea la fuente. */
.cs-feature { position: relative; margin-top: var(--wp--preset--spacing--8); border-radius: var(--wp--custom--radius--xxl); overflow: hidden; aspect-ratio: 21 / 9; background: var(--wp--custom--surface--tint); }
.cs-feature [data-is-block] { display: contents; }
.cs-feature img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.cs-feature img.jet-listing-dynamic-image__img.wp-post-image { width: 100%; }
.cs-feature__pending { display: flex; align-items: center; justify-content: center; height: 100%; }
.cs-feature__pending span { color: var(--wp--preset--color--blue-700); font-size: var(--wp--preset--font-size--eyebrow); letter-spacing: var(--wp--custom--typography--tracking-eyebrow); text-transform: uppercase; font-weight: 600; }

/* Layout cuerpo + sidebar. */
.cs-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--wp--preset--spacing--10); align-items: start; padding-top: var(--wp--preset--spacing--10); }
.cs-layout > * { margin-block: 0; }
.cs-body { max-width: var(--wp--custom--container-text, 760px); }
.cs-body > * { margin-block: 0; }
.cs-body h2 { font-size: var(--wp--preset--font-size--h-3); color: var(--wp--custom--text--heading); margin: 0 0 var(--wp--preset--spacing--3); }
.cs-body .wp-block-post-content > p { font-size: var(--wp--preset--font-size--body); line-height: 1.7; color: var(--wp--custom--text--body); margin: 0 0 var(--wp--preset--spacing--4); }
.cs-body .wp-block-post-content > p:first-child { font-size: var(--wp--preset--font-size--lead); line-height: 1.55; margin-bottom: var(--wp--preset--spacing--5); }

/* Objetivos: checklist (.cs-goals). */
.cs-goals { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--wp--preset--spacing--3); }
.cs-goals li { display: flex; gap: 12px; align-items: flex-start; font-size: var(--wp--preset--font-size--body); color: var(--wp--custom--text--body); line-height: 1.55; }
.cs-goals .ck { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; margin-top: 1px; background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-600); display: inline-flex; align-items: center; justify-content: center; }

/* Sidebar "Datos del proyecto" (neutral, sticky). */
.cs-side { position: sticky; top: 96px; padding: var(--wp--preset--spacing--6); }
.cs-side > * { margin-block: 0; }
.cs-side__title { margin: 0 0 var(--wp--preset--spacing--4); font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); }
.cs-dl { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--4); }
.cs-dl > * { margin-block: 0; }
.cs-dl__row { display: flex; flex-direction: column; gap: 2px; }
.cs-dl__row > * { margin-block: 0; }
/* Envoltorios que no son del diseño: el <div> de JetEngine y el <p> que wpautop añade
   alrededor de los shortcodes ([cs_fecha]). Se sacan de la caja para que todas las filas
   midan igual. */
.cs-dl__row [data-is-block],
.cs-dl__row > p { display: contents; }
.cs-dl__dt { font-size: var(--wp--preset--font-size--eyebrow); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; color: var(--wp--custom--text--muted); }
.cs-dl__dd { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.5; }
.cs-dl__dd .jet-listing-dynamic-terms,
.cs-dl__dd .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }

/* Secciones de relación. Borde superior salvo la primera. */
.cs-rel { padding: var(--wp--preset--spacing--12) 0; border-top: 1px solid var(--wp--custom--border--subtle, var(--wp--preset--color--slate-200)); }
.cs-rel:first-of-type { border-top: none; padding-top: var(--wp--preset--spacing--10); }
.cs-rel:last-of-type { padding-bottom: var(--wp--preset--spacing--20); }
.cs-rel__head { margin-bottom: var(--wp--preset--spacing--6); }
.cs-rel__head > * { margin-block: 0; }
.cs-rel__head h2 { font-size: var(--wp--preset--font-size--h-3); color: var(--wp--custom--text--heading); }
.cs-rel__head p { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); }

/* Estado vacío discreto (nodo not-found de JetEngine dentro de .cs-rel).
   Confirmado en DOM real (T3): .jet-listing-not-found.jet-listing-grid__items,
   con width:1200px fijo por JetEngine en box-sizing:content-box. Sin
   box-sizing:border-box aqui el padding se SUMA al width fijo y desborda el
   viewport (scroll horizontal). box-sizing + max-width:100% lo evitan sin
   tocar el aspecto visual (fondo, radio, padding). */
.cs-rel .jet-listing-not-found {
	box-sizing: border-box; max-width: 100%;
	background: var(--wp--custom--surface--subtle); border-radius: var(--wp--custom--radius--lg);
	padding: var(--wp--preset--spacing--6) var(--wp--preset--spacing--7, 1.75rem);
	color: var(--wp--custom--text--muted); font-size: var(--wp--preset--font-size--sm); line-height: 1.5;
}

/* Colapso ≤900: 1 columna, sidebar estático. */
@media (max-width: 900px) {
	.cs-layout { grid-template-columns: 1fr; }
	.cs-side { position: static; }
}

/* ============================================================
   Red Horizonte 2030 (rebanada 7) — directorio /red/:
   CTA "Suma tu entidad" (.cs-join) + botones (.cs-btn) + barra de
   filtros de UNA sola faceta (.cs-filters--una). Valores calcados del
   export "Red Horizonte 2030 (standalone)". Sin sombra ni borde.
   ============================================================ */

/* CTA tintada auto-constreñida a 1200 (patrón .cs-cta-band), NO full-bleed. El tinte
   (blue-100 = mass--tint) y el "sin sombra/borde" los da is-style-card-tint; aquí solo el
   ancho, el radio (xl=28, fiel al export), el padding generoso y el ritmo interno. */
.cs-join {
	max-width: min(1200px, calc(100% - 2 * var(--wp--custom--row-inset)));
	margin-inline: auto;
	display: flex; flex-direction: column;
	gap: var(--wp--preset--spacing--4);
	padding: var(--wp--preset--spacing--10);
	border-radius: var(--wp--custom--radius--xl);
}
/* (0,2,0) para pisar el margin-block-start del block-gap (layout flow de WP). */
.wp-block-group.cs-join { margin-block: var(--wp--preset--spacing--4) var(--wp--preset--spacing--12); }
.wp-block-group.cs-join > * { margin-block: 0; } /* el ritmo vertical lo da el gap del flex */
.cs-join p { max-width: 62ch; }
/* Fila de botones: flex, wrap, gap 12 (fiel al export). */
.cs-join__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wp--preset--spacing--3); }
/* El bloque .cs-join__actions es layout flow: WordPress añade margin-top (blockGap) al 2.º hijo (el
   botón fantasma), que en el flex lo dejaba 24px más abajo. Zeramos el margen de todos los hijos; el
   <p> de wpautop (envuelve el botón de [cs_adhesion_pdf]) además con line-height:0 para colapsar su
   caja a la altura del <a> (46px). Así ambos botones quedan alineados en la misma línea. */
.cs-join__actions > * { margin: 0; }
.cs-join__actions > p { line-height: 0; }

/* Botón .cs-btn (CTA de Red y futuros): MISMO badge circular que is-style-pill-arrow (base del
   ::after arriba). Layout píldora, padding izq 18 / der 7, min-height 46. Primario azul/badge
   blanco; ghost secundario BLANCO por contraste (regla del design system: sobre el tinte #e3eefb
   no vale #eef2f7 → blanco, con un primario azul oscuro al lado), badge azul. Hover INVIERTE en
   ambos. El color/subrayado usan a.cs-btn* (0,1,1+) para pisar el enlace de theme.json. */
.cs-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 12px;
	min-height: 46px; padding: 0 7px 0 18px;
	border: 0; border-radius: var(--wp--custom--radius--pill);
	font-family: var(--wp--preset--font-family--jakarta);
	font-size: var(--wp--preset--font-size--body); font-weight: 600;
	line-height: 1; cursor: pointer;
	transition: background-color .16s ease, color .16s ease;
}
a.cs-btn,
a.cs-btn:hover,
a.cs-btn:focus-visible { text-decoration: none; }
/* Primario: azul sólido + badge blanco/flecha azul → hover blanco/texto azul + badge azul/flecha blanca. */
.cs-btn--primary { background: var(--wp--preset--color--blue-600); }
a.cs-btn--primary,
a.cs-btn--primary:focus-visible { color: var(--wp--preset--color--white); }
.cs-btn--primary::after { background-color: var(--wp--preset--color--white); background-image: var(--cs-arrow-blue); }
.cs-btn--primary:hover,
.cs-btn--primary:focus-visible { background: var(--wp--preset--color--white); }
a.cs-btn--primary:hover { color: var(--wp--preset--color--blue-700); }
.cs-btn--primary:hover::after,
.cs-btn--primary:focus-visible::after { background-color: var(--wp--preset--color--blue-700); background-image: var(--cs-arrow-white); }
/* Ghost/secundario: fondo BLANCO (contraste sobre el tinte) + badge blue-600/flecha blanca →
   hover invierte a blue-700/texto blanco + badge blanco/flecha azul. */
.cs-btn--ghost { background: var(--wp--preset--color--white); }
a.cs-btn--ghost,
a.cs-btn--ghost:focus-visible { color: var(--wp--preset--color--blue-700); }
.cs-btn--ghost::after { background-color: var(--wp--preset--color--blue-600); background-image: var(--cs-arrow-white); }
.cs-btn--ghost:hover,
.cs-btn--ghost:focus-visible { background: var(--wp--preset--color--blue-700); }
a.cs-btn--ghost:hover { color: var(--wp--preset--color--white); }
.cs-btn--ghost:hover::after,
.cs-btn--ghost:focus-visible::after { background-color: var(--wp--preset--color--white); background-image: var(--cs-arrow-blue); }
/* Botón a ANCHO COMPLETO (regla GENERAL para cualquier .cs-btn al 100%): box-sizing border-box (para
   que el padding no lo desborde por la derecha), el TEXTO queda centrado y el badge circular (flecha/
   icono) se JUSTIFICA A LA DERECHA (posición absoluta), en vez de ir pegado al texto en el centro. */
.cs-btn--block {
	display: flex; width: 100%; box-sizing: border-box; position: relative;
	justify-content: center;
	padding-left: var(--wp--preset--spacing--6); padding-right: var(--wp--preset--spacing--6);
}
.cs-btn--block::after {
	position: absolute; right: 8px; top: 50%; transform: translateY(-50%); margin: 0;
}

/* Barra plana de UNA faceta (el directorio Red filtra solo por Tipo de entidad): el patrón
   .cs-filters--plana reparte la fila en 3 columnas; con un único Select quedaría a 1/3 con
   2/3 vacíos. La compuesta .cs-filters--plana.cs-filters--una (0,3,0) pisa esa rejilla y deja
   el Select en una sola columna acotada, alineado a la izquierda como en los demás archivos.
   Reutilizable en futuros archivos de una sola faceta. */
.cs-filters--plana.cs-filters--una .cs-filters__row { grid-template-columns: minmax(0, 340px); }

/* ============================================================
   Ficha de entidad (single-entidad, /red/{slug}/) — rebanada 7.
   Cabecera 2-col (.cs-ehead): logo/placeholder izq + identidad der
   (eyebrow de eje + H1 + fila meta). Cuerpo (.cs-ebody): columna de
   lectura 760 alineada a la IZQUIERDA del area wide (1200). Namespacing
   propio .cs-ehead* (no colisiona con .cs-phead del single-proyecto).
   Sin sombra ni borde. La banda "Proyectos en los que participa"
   reutiliza .cs-band / .cs-sec-head--row / .cs-seeall / .cs-eyebrow.
   ============================================================ */

/* Cabecera: rejilla 2-col (logo ~200 + identidad). Colapsa a 1-col <=781. */
.cs-ehead {
	display: grid;
	grid-template-columns: 200px minmax(0, 1fr);
	gap: var(--wp--preset--spacing--8);
	align-items: start;
	padding-top: var(--wp--preset--spacing--5);
}
.cs-ehead > * { margin-block: 0; }

/* Slot de media (col 1): logo o placeholder, cuadrado tintado, radio xl. El
   dynamic-image (hide_if_empty) y el placeholder gateado son mutuamente
   excluyentes: exactamente uno se pinta. */
.cs-ehead__media { min-width: 0; }
/* El placeholder es la caja tintada 200×200. El logo real toma ESE tamaño en su <img>, NO en
   el wrapper: así, cuando la entidad no tiene foto, hide_if_empty deja el wrapper
   .cs-ehead__logo vacío y sin tamaño/fondo → colapsa (no pinta una 2ª caja azul sobre el
   placeholder). Con foto, el <img> ocupa la caja y el placeholder queda gateado fuera. */
.cs-ehead__ph {
	width: 200px; max-width: 100%;
	aspect-ratio: 1 / 1;
	border-radius: var(--wp--custom--radius--xl);
	overflow: hidden;
	background: var(--wp--custom--surface--tint);
}
.cs-ehead__logo [data-is-block] { display: contents; }
.cs-ehead__logo img {
	width: 200px; max-width: 100%; aspect-ratio: 1 / 1; height: auto;
	object-fit: contain; display: block;
	border-radius: var(--wp--custom--radius--xl); background: var(--wp--custom--surface--tint);
}
.cs-ehead__ph {
	display: flex; align-items: center; justify-content: center;
	padding: var(--wp--preset--spacing--3); text-align: center;
	color: var(--wp--custom--text--muted);
	font-size: var(--wp--preset--font-size--eyebrow);
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow);
	text-transform: uppercase; font-weight: 600;
}

/* Identidad (col 2). */
.cs-ehead__id { min-width: 0; }
.cs-ehead__id > * { margin-block: 0; }
/* Eyebrow de eje: mismo tratamiento AA que .cs-phead__eyebrow (blue-700). */
.cs-ehead__eyebrow {
	font-size: var(--wp--preset--font-size--eyebrow); text-transform: uppercase;
	letter-spacing: var(--wp--custom--typography--tracking-eyebrow); font-weight: 600;
	color: var(--wp--preset--color--blue-700); margin: 0;
}
.cs-ehead__title {
	margin: var(--wp--preset--spacing--2) 0 0; font-size: var(--wp--preset--font-size--display);
	line-height: var(--wp--custom--typography--lh-tight); color: var(--wp--custom--text--heading);
}
/* Fila meta: estado + tipo + ubicacion. Se aplanan los wrappers de bloque
   (dynamic-terms via [data-is-block], shortcode via .wp-block-shortcode/p) para
   que las pastillas sean items directos del flex; el grupo anidado .cs-ehead__loc
   NO lleva data-is-block, se conserva como par cohesionado (mismo patron que
   .cs-phead__row del single-proyecto). */
.cs-ehead__meta {
	display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
	margin-top: var(--wp--preset--spacing--4);
}
.cs-ehead__meta > * { margin-block: 0; }
.cs-ehead__meta [data-is-block] { display: contents; }
.cs-ehead__meta :where(.wp-block-shortcode, p) { display: contents; }
/* Pastilla de tipo (blue-100 / blue-700), como en la tarjeta de directorio. */
.cs-ehead__type {
	display: inline-flex; align-items: center; padding: 5px 11px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-700);
	font-size: var(--wp--preset--font-size--xs); font-weight: 500; line-height: 1; white-space: nowrap;
}
.cs-ehead__type .jet-listing-dynamic-terms,
.cs-ehead__type .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }
/* Ubicacion: pin + termino (par cohesionado). */
.cs-ehead__loc {
	display: inline-flex; align-items: center; gap: 5px;
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted);
}
.cs-ehead__loc > * { margin-block: 0; }
.cs-ehead__pin { display: inline-flex; flex: 0 0 auto; }
.cs-ehead__locterms .jet-listing-dynamic-terms,
.cs-ehead__locterms .jet-listing-dynamic-terms a { color: inherit; font-weight: inherit; }

/* Cuerpo: columna de lectura 760 alineada a la IZQUIERDA del area wide (1200).
   Rejilla de una sola pista -> justify-content:start (por defecto) la pega al
   borde izquierdo, igual que el borde de la cabecera. */
.cs-ebody {
	display: grid;
	grid-template-columns: minmax(0, var(--wp--custom--container-text, 760px));
	padding-top: var(--wp--preset--spacing--10);
}
.cs-ebody > * { margin-block: 0; min-width: 0; }

/* Lead = descripcion breve (tamano lead, color cuerpo). */
.cs-lead {
	font-size: var(--wp--preset--font-size--lead); line-height: 1.55;
	color: var(--wp--custom--text--body);
	margin: 0 0 var(--wp--preset--spacing--5);
}

/* Colapso <=781: cabecera a 1 columna (logo arriba, alineado a la izquierda). */
@media (max-width: 781px) {
	.cs-ehead { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--5); }
}

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

/* ===== Observatorio ODS ===== */
.obs-intro > * { margin-block: 0; }
.obs-sec { padding-block: var(--wp--preset--spacing--10); }
.obs-sec > * { margin-block: 0; }
.obs-sec__head { margin-bottom: var(--wp--preset--spacing--8); }
.obs-sec__head > * { margin-block: 0; }
.obs-sec__title { font-size: var(--wp--preset--font-size--h-2); color: var(--wp--custom--text--heading); margin-top: var(--wp--preset--spacing--2); }
.obs-sec__sub { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--slate-600); margin-top: var(--wp--preset--spacing--2); }

/* Contadores destacados — 4 KPIs en vivo ([cs_counters]) */
.obs-counters { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--wp--preset--spacing--4); }
.obs-counter { display: flex; flex-direction: column; gap: 4px; padding: var(--wp--preset--spacing--5); background: var(--wp--preset--color--blue-100); border-radius: var(--wp--custom--radius--lg); }
.obs-counter__num { font-size: var(--wp--preset--font-size--display); font-weight: 800; line-height: 1; color: var(--wp--preset--color--blue-700); }
.obs-counter__label { font-weight: 600; color: var(--wp--custom--text--heading); }
.obs-counter__src { font-size: var(--wp--preset--font-size--xs); color: var(--wp--custom--text--muted); }
@media (max-width: 900px) { .obs-counters { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .obs-counters { grid-template-columns: 1fr; } }

/* Indicadores destacados — eje + avance ([cs_indicadores_observatorio]) */
.obs-inds { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--wp--preset--spacing--4); }
.obs-indcard { display: flex; flex-direction: column; gap: 8px; padding: var(--wp--preset--spacing--5); border-radius: var(--wp--custom--radius--lg); background: var(--wp--custom--mass--tint); }
.obs-indcard > * { margin-block: 0; }
/* QA a11y: blue-600 sobre el tinte de la tarjeta daba 4,38:1 — por debajo del 4,5 de AA.
   blue-700 sube a 6,11:1 y es el color que ya usa .obs-indcard__metric justo debajo. */
.obs-indcard__eyebrow { font-size: var(--wp--preset--font-size--xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--wp--preset--color--blue-700); }
.obs-indcard__title { font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); line-height: 1.25; }
.obs-indcard__metric { font-size: var(--wp--preset--font-size--h-2); font-weight: 800; color: var(--wp--preset--color--blue-700); line-height: 1; }
.obs-indcard__metric .u { font-size: var(--wp--preset--font-size--sm); font-weight: 600; color: var(--wp--custom--text--muted); }
.obs-indcard__src { font-size: var(--wp--preset--font-size--xs); color: var(--wp--custom--text--muted); margin-top: auto; }
@media (max-width: 900px) { .obs-inds { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .obs-inds { grid-template-columns: 1fr; } }

/* Gráficas de seguimiento — barras horizontales + tabla accesible ([cs_chart]); T5 añade línea/donut */
/* align-items:stretch EXPLÍCITO (no el default 'normal', que con estas tarjetas flex se comportaba
   como 'start' → filas desiguales): cada tarjeta se estira a la altura de la más alta de su FILA. NO
   usar height:100% aquí: rompía el dimensionado de las pistas auto (la tarjeta salía más alta que su
   pista y se solapaba con la fila siguiente). El contenido queda justificado arriba (flex-start). */
.obs-charts { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--wp--preset--spacing--4); align-items: stretch; }
/* .obs-charts es layout flow de WP (is-layout-flow) → inyecta margin-block-start (blockGap) al 2.º+
   hijo, que desfasaba las tarjetas y confundía el stretch. Se anula en los items del grid. Con eso,
   align-items:stretch (arriba) iguala la altura de cada fila SIN height:100% (que sobredimensionaba
   la tarjeta respecto a su pista auto y la hacía solaparse con la fila siguiente). Contenido arriba. */
.obs-charts > * { margin-block: 0; }
.obs-chart { display: flex; flex-direction: column; gap: 10px; padding: var(--wp--preset--spacing--6); border-radius: var(--wp--custom--radius--lg); background: var(--wp--custom--mass--tint); }
.obs-chart > * { margin-block: 0; }
.obs-chart__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.obs-chart__title { font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); }
.obs-chart__sub { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--slate-600); }
.obs-chart__foot { font-size: var(--wp--preset--font-size--xs); color: var(--wp--custom--text--muted); margin-top: auto; }
.obs-chart__table > summary { cursor: pointer; font-size: var(--wp--preset--font-size--xs); font-weight: 600; color: var(--wp--preset--color--blue-700); list-style: none; }
.obs-chart__table > summary::-webkit-details-marker { display: none; }
.obs-chart__table table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: var(--wp--preset--font-size--sm); }
.obs-chart__table th, .obs-chart__table td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--wp--preset--color--blue-100); }
.obs-chart__table td:last-child, .obs-chart__table th:last-child { text-align: right; }
/* Barras */
.obs-bars { display: flex; flex-direction: column; gap: 12px; }
.obs-bar__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: var(--wp--preset--font-size--sm); }
.obs-bar__label { color: var(--wp--custom--text--heading); }
.obs-bar__val { font-weight: 700; color: var(--wp--preset--color--blue-700); }
.obs-bar__track { margin-top: 4px; height: 10px; border-radius: 999px; background: var(--wp--preset--color--blue-100); overflow: hidden; }
.obs-bar__fill { display: block; height: 100%; border-radius: 999px; background: var(--wp--preset--color--blue-600); }
.obs-bar__fill--mono { background: var(--wp--preset--color--blue-600); }
.obs-bar__fill--ods-1  { background: var(--wp--preset--color--ods-1); }
.obs-bar__fill--ods-2  { background: var(--wp--preset--color--ods-2); }
.obs-bar__fill--ods-3  { background: var(--wp--preset--color--ods-3); }
.obs-bar__fill--ods-4  { background: var(--wp--preset--color--ods-4); }
.obs-bar__fill--ods-5  { background: var(--wp--preset--color--ods-5); }
.obs-bar__fill--ods-6  { background: var(--wp--preset--color--ods-6); }
.obs-bar__fill--ods-7  { background: var(--wp--preset--color--ods-7); }
.obs-bar__fill--ods-8  { background: var(--wp--preset--color--ods-8); }
.obs-bar__fill--ods-9  { background: var(--wp--preset--color--ods-9); }
.obs-bar__fill--ods-10 { background: var(--wp--preset--color--ods-10); }
.obs-bar__fill--ods-11 { background: var(--wp--preset--color--ods-11); }
.obs-bar__fill--ods-12 { background: var(--wp--preset--color--ods-12); }
.obs-bar__fill--ods-13 { background: var(--wp--preset--color--ods-13); }
.obs-bar__fill--ods-14 { background: var(--wp--preset--color--ods-14); }
.obs-bar__fill--ods-15 { background: var(--wp--preset--color--ods-15); }
.obs-bar__fill--ods-16 { background: var(--wp--preset--color--ods-16); }
.obs-bar__fill--ods-17 { background: var(--wp--preset--color--ods-17); }
@media (max-width: 900px) { .obs-charts { grid-template-columns: 1fr; } }
/* Línea+área (evolución temporal) y donut (estado de ejecución) — SVG inline, T5 */
.obs-line { width: 100%; height: auto; }
.obs-line__area { fill: var(--wp--preset--color--blue-100); opacity: .7; }
.obs-line__stroke { stroke: var(--wp--preset--color--blue-600); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.obs-line__dot { fill: var(--wp--preset--color--blue-700); }
/* Los font-size de las etiquetas van en unidades de usuario del viewBox: si cambian, hay que
   actualizar $FS_X / $FS_Y en cs_obs_render_line() (inc/observatorio-charts.php), que mide el ancho
   de cada etiqueta para decidir $padL y qué años se pintan. */
.obs-line__xlabel { fill: var(--wp--custom--text--muted); font-size: 11px; }
.obs-line__grid { stroke: var(--wp--preset--color--slate-200); stroke-width: 1; }
.obs-line__ylabel { fill: var(--wp--custom--text--muted); font-size: 10px; }
/* MODO CAMBIO (evolución de un indicador en la ficha de ODS): la línea del 0 es la referencia de
   lectura ("por debajo, descenso"), así que va MÁS MARCADA que la rejilla — misma familia neutra,
   un par de escalones más oscura, sin competir con el azul del trazo de datos. slate-500 da 4,76:1
   sobre blanco y 4,05:1 sobre el tinte de la tarjeta .obs-chart (por encima del 3:1 de SC 1.4.11,
   aunque el SVG sea aria-hidden y no le aplique). */
.obs-line__zero { stroke: var(--wp--preset--color--slate-500); stroke-width: 1.5; }
/* El área del modo cambio se ancla en el 0 y es la que transmite "sube/baja": con el blue-100 de
   .obs-line__area NO se vería, porque la tarjeta .obs-chart ya tiene ese mismo fondo (mass--tint).
   Sube un escalón a blue-200 (mismo azul corporativo, sin opacidad). La clase base NO se toca: la
   comparte la gráfica de proyectos acumulados del Observatorio. */
.obs-line__area--cambio { fill: var(--wp--preset--color--blue-200); opacity: 1; }
/* Con la 3.ª columna ("Cambio desde AAAA") la regla genérica td:last-child sólo alinearía a la
   derecha esa; las dos columnas numéricas se alinean igual. El año es <th scope="row"> y no entra. */
.cs-tax-chart .obs-chart__table td { text-align: right; }
.obs-donut-wrap { display: flex; align-items: center; gap: var(--wp--preset--spacing--5); flex-wrap: wrap; }
.obs-donut { flex: 0 0 auto; width: 160px; height: 160px; }
.obs-donut__total { fill: var(--wp--custom--text--heading); font-size: 34px; font-weight: 800; }
.obs-donut__unit { fill: var(--wp--custom--text--muted); font-size: 12px; }
.obs-donut__legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: var(--wp--preset--font-size--sm); }
.obs-donut__legend li { display: flex; align-items: center; gap: 8px; }
.obs-donut__dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* CTA "¿Echas en falta un dato?" — banda azul sólida inset, redondeada, sin sombra */
.obs-cta { border-radius: var(--wp--custom--radius--xl); padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--8); }
.obs-cta .wp-block-column > * { margin-block: 0; }
/* Botón blanco sobre banda oscura (variante pill-arrow blanca): badge azul + flecha blanca */
.obs-cta .is-style-pill-arrow .wp-block-button__link.has-white-background-color::after { background-color: var(--wp--preset--color--blue-600); background-image: var(--cs-arrow-white); }
.obs-cta .is-style-pill-arrow .wp-block-button__link.has-white-background-color:hover { background-color: var(--wp--preset--color--blue-50) !important; }

/* Los 17 ODS — rejilla enlazada a /ods/{término}/ ([cs_ods_grid]) */
.obs-ods-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--wp--preset--spacing--3); }
.obs-odstile { display: flex; flex-direction: column; gap: 8px; min-height: 128px; padding: var(--wp--preset--spacing--4); border-radius: var(--wp--custom--radius--lg); text-decoration: none; color: #fff; }
.obs-odstile__n { font-size: var(--wp--preset--font-size--h-3); font-weight: 800; line-height: 1; }
.obs-odstile__name { font-size: var(--wp--preset--font-size--xs); font-weight: 600; line-height: 1.2; margin-top: auto; }
.obs-odstile:hover { filter: brightness(.95); }
.obs-odstile--1  { background: var(--wp--preset--color--ods-1); }
.obs-odstile--2  { background: var(--wp--preset--color--ods-2); }
.obs-odstile--3  { background: var(--wp--preset--color--ods-3); }
.obs-odstile--4  { background: var(--wp--preset--color--ods-4); }
.obs-odstile--5  { background: var(--wp--preset--color--ods-5); }
.obs-odstile--6  { background: var(--wp--preset--color--ods-6); }
.obs-odstile--7  { background: var(--wp--preset--color--ods-7); }
.obs-odstile--8  { background: var(--wp--preset--color--ods-8); }
.obs-odstile--9  { background: var(--wp--preset--color--ods-9); }
.obs-odstile--10 { background: var(--wp--preset--color--ods-10); }
.obs-odstile--11 { background: var(--wp--preset--color--ods-11); }
.obs-odstile--12 { background: var(--wp--preset--color--ods-12); }
.obs-odstile--13 { background: var(--wp--preset--color--ods-13); }
.obs-odstile--14 { background: var(--wp--preset--color--ods-14); }
.obs-odstile--15 { background: var(--wp--preset--color--ods-15); }
.obs-odstile--16 { background: var(--wp--preset--color--ods-16); }
.obs-odstile--17 { background: var(--wp--preset--color--ods-17); }
/* Tinta oscura para los ODS claros (mismo criterio que .cs-odstag): AA sobre amarillos/verdes claros. */
.obs-odstile--2, .obs-odstile--3, .obs-odstile--5, .obs-odstile--6, .obs-odstile--7,
.obs-odstile--9, .obs-odstile--11, .obs-odstile--12, .obs-odstile--14, .obs-odstile--15 { color: #1a1a1a; }
@media (max-width: 900px) { .obs-ods-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .obs-ods-grid { grid-template-columns: repeat(2, 1fr); } }

/* ===== Fichas de taxonomía (Detalle de ODS/eje) ===== */
.cs-tax-head { max-width: 1200px; margin-inline: auto; padding: var(--wp--preset--spacing--6) var(--wp--custom--row-inset) 0; }
.cs-tax-head > * { margin-block: 0; }
.cs-tax-hero { display: flex; align-items: center; gap: var(--wp--preset--spacing--6); margin-top: var(--wp--preset--spacing--6); padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--10); border-radius: var(--wp--custom--radius--xl); color: #fff; }
.cs-tax-hero > * { margin-block: 0; }
.cs-tax-hero__num { font-size: clamp(64px, 9vw, 120px); font-weight: 800; line-height: .9; flex: 0 0 auto; }
.cs-tax-hero__id { display: flex; flex-direction: column; justify-content: center; gap: 6px; }
.cs-tax-hero__id > * { margin-block: 0; }
.cs-tax-hero__eyebrow { font-size: var(--wp--preset--font-size--xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; opacity: .9; }
.cs-tax-hero__title { font-size: var(--wp--preset--font-size--display); font-weight: 800; line-height: 1.05; color: inherit; }
.cs-tax-hero--eje { background: var(--wp--preset--color--blue-600); }
.cs-tax-hero--ods-1  { background: var(--wp--preset--color--ods-1); }
.cs-tax-hero--ods-2  { background: var(--wp--preset--color--ods-2); }
.cs-tax-hero--ods-3  { background: var(--wp--preset--color--ods-3); }
.cs-tax-hero--ods-4  { background: var(--wp--preset--color--ods-4); }
.cs-tax-hero--ods-5  { background: var(--wp--preset--color--ods-5); }
.cs-tax-hero--ods-6  { background: var(--wp--preset--color--ods-6); }
.cs-tax-hero--ods-7  { background: var(--wp--preset--color--ods-7); }
.cs-tax-hero--ods-8  { background: var(--wp--preset--color--ods-8); }
.cs-tax-hero--ods-9  { background: var(--wp--preset--color--ods-9); }
.cs-tax-hero--ods-10 { background: var(--wp--preset--color--ods-10); }
.cs-tax-hero--ods-11 { background: var(--wp--preset--color--ods-11); }
.cs-tax-hero--ods-12 { background: var(--wp--preset--color--ods-12); }
.cs-tax-hero--ods-13 { background: var(--wp--preset--color--ods-13); }
.cs-tax-hero--ods-14 { background: var(--wp--preset--color--ods-14); }
.cs-tax-hero--ods-15 { background: var(--wp--preset--color--ods-15); }
.cs-tax-hero--ods-16 { background: var(--wp--preset--color--ods-16); }
.cs-tax-hero--ods-17 { background: var(--wp--preset--color--ods-17); }
/* El hero de taxonomía va SIEMPRE con tinta BLANCA (fidelidad al export del Detalle de ODS, que usa
   blanco sobre el color oficial del ODS; a diferencia de los tiles/pastillas ODS, que sí adaptan la
   tinta a oscuro en los colores claros). La tinta blanca la fija .cs-tax-hero { color:#fff } arriba. */
.cs-tax-desc { max-width: 1200px; margin: var(--wp--preset--spacing--6) auto 0; padding-inline: var(--wp--custom--row-inset); font-size: var(--wp--preset--font-size--lead); color: var(--wp--preset--color--slate-600); }
.cs-tax-desc p { margin: 0; max-width: 46em; }
/* Regla del manual: sobre banda azul clara (.cs-band = blue-50) las tarjetas GRISES
   (is-style-card = mass--neutral) pierden contraste → van en BLANCO. Aplica a las bandas de
   fichas (proyectos relacionados) sin tocar las tarjetas tintadas (is-style-card-tint). */
.cs-band .is-style-card { background: var(--wp--preset--color--white); }
@media (max-width: 640px) { .cs-tax-hero { flex-direction: column; align-items: flex-start; text-align: left; } }

/* ============================================================
   Banda "Indicadores" (ficha de taxonomía ods/eje) — tarjetas-stat.
   ============================================================ */
.cs-tax-sec { max-width: 1200px; margin: var(--wp--preset--spacing--10) auto 0; padding-inline: var(--wp--custom--row-inset); }
.cs-tax-sec > * { margin-block: 0; }
.cs-tax-sec__head { margin-bottom: var(--wp--preset--spacing--6); }
.cs-tax-sec__head > * { margin-block: 0; }
.cs-tax-sec__sub { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--slate-600); margin-top: var(--wp--preset--spacing--2); }
.cs-tax-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--wp--preset--spacing--4); }
.cs-tax-stat { display: flex; flex-direction: column; gap: 8px; padding: var(--wp--preset--spacing--5); border-radius: var(--wp--custom--radius--lg); background: var(--wp--custom--mass--tint); }
.cs-tax-stat > * { margin-block: 0; }
.cs-tax-stat__title { font-size: var(--wp--preset--font-size--h-5, var(--wp--preset--font-size--h-4)); color: var(--wp--custom--text--heading); line-height: 1.25; }
.cs-tax-stat__val { font-size: var(--wp--preset--font-size--h-2); font-weight: 800; color: var(--wp--preset--color--blue-700); line-height: 1; }
.cs-tax-stat__val .u { font-size: var(--wp--preset--font-size--sm); font-weight: 600; color: var(--wp--custom--text--muted); }
.cs-tax-stat__delta { font-size: var(--wp--preset--font-size--sm); font-weight: 600; color: var(--wp--custom--text--muted); }
.cs-tax-stat__src { font-size: var(--wp--preset--font-size--xs); color: var(--wp--custom--text--muted); margin-top: auto; }
@media (max-width: 720px) { .cs-tax-stats { grid-template-columns: 1fr; } }
/* .cs-tax-chart comparte elemento con .obs-chart (class="cs-tax-chart obs-chart"): reutiliza su
   padding/radio/fondo-tintado/flex y su reset de margin-block; aquí solo su margen superior. */
.cs-tax-chart { margin-top: var(--wp--preset--spacing--4); }

/* ============================================================
   Página /participa/ (última rebanada de Fase D) — secciones genéricas
   (mismo recibo visual que .obs-sec/.obs-sec__head, namespace propio), botón
   deshabilitado de [cs_adhesion_pdf], formulario JetFormBuilder "Buzón
   Agenda 2030" y tarjeta de propuesta ciudadana `propuesta-card`. El bloque
   de adhesión reutiliza .cs-join/.cs-btn (ya definidos para /red/); el
   cierre "También puedes seguir el proceso" reutiliza .obs-cta (ya definido
   para el CTA de cierre del Observatorio). Sin sombra/borde; solo azules
   corporativos; WCAG AA.
   ============================================================ */
.cs-part-sec { padding-block: var(--wp--preset--spacing--10); }
.cs-part-sec > * { margin-block: 0; }
.cs-part-sec__head { margin-bottom: var(--wp--preset--spacing--8); }
.cs-part-sec__head > * { margin-block: 0; }
.cs-part-sec__title { font-size: var(--wp--preset--font-size--h-2); color: var(--wp--custom--text--heading); margin-top: var(--wp--preset--spacing--2); }
.cs-part-sec__sub { font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--slate-600); margin-top: var(--wp--preset--spacing--2); max-width: 62ch; }

/* Buzón dentro de CAJA AZUL: el tinte lo pinta is-style-card-tint (.wp-block-group); aquí van padding
   y radio. Bloque en AZUL OSCURO con aspecto de CTA (fondo blue-900, textos claros). El formulario va
   al 100% del ancho de la caja: los dos campos de texto (nombre/email) a 2 COLUMNAS y el resto
   (asunto, mensaje, consentimientos, botón) a ancho completo. En móvil, una sola columna. */
.cs-buzon-box {
	padding: var(--wp--preset--spacing--12); border-radius: var(--wp--custom--radius--xxl);
	background: var(--wp--preset--color--blue-900); color: var(--wp--preset--color--white);
}
.cs-buzon-box > * { margin-block: 0; }
.cs-buzon-box .cs-part-sec__head { margin-bottom: var(--wp--preset--spacing--8); }
/* Textos de cabecera claros sobre el azul oscuro. */
.cs-buzon-box .cs-eyebrow { color: var(--wp--preset--color--blue-200); }
.cs-buzon-box .cs-part-sec__title { color: var(--wp--preset--color--white); }
.cs-buzon-box .cs-part-sec__sub { color: var(--wp--preset--color--blue-100); }
/* Formulario a ANCHO COMPLETO (pisa el max-width:560px de .jet-form-builder.layout-column) en grid
   de 2 columnas; .layout-column da la especificidad para ganar al display:flex de public.css de JFB. */
.cs-buzon-box .jet-form-builder.layout-column {
	display: grid; grid-template-columns: 1fr 1fr;
	column-gap: var(--wp--preset--spacing--5); row-gap: var(--wp--preset--spacing--5);
	max-width: none; width: 100%; margin-top: 0; align-items: start;
}
.cs-buzon-box .jfb-user-info { display: none; }
/* nombre|email a 2 columnas (auto-flow); asunto/mensaje/consentimientos/botón/mensajes a lo ancho. */
.cs-buzon-box .field-type-select-field,
.cs-buzon-box .field-type-textarea-field,
.cs-buzon-box .field-type-checkbox-field,
.cs-buzon-box .field-type-submit-field,
.cs-buzon-box .jet-form-builder-messages-wrap { grid-column: 1 / -1; }
/* Etiquetas de campo y de consentimiento en claro. La de checkbox lleva .for-checkbox y su regla
   base (color oscuro) va DESPUÉS en el fichero a igual especificidad; por eso aquí se sube a
   .for-checkbox (0,3,0) para ganarla. Los labels de texto (.jet-form-builder__label) heredan blanco. */
.cs-buzon-box .jet-form-builder__label,
.cs-buzon-box .jet-form-builder__field-label,
.cs-buzon-box .jet-form-builder__field-label.for-checkbox,
.cs-buzon-box .jet-form-builder__field.checkboxes-field label,
.cs-buzon-box .jet-form-builder__field.checkradio-field label { color: var(--wp--preset--color--white); }
.cs-buzon-box .jet-form-builder__field-label.for-checkbox a { color: var(--wp--preset--color--blue-200); }
.cs-buzon-box .jet-form-builder__field-label.for-checkbox a:hover,
.cs-buzon-box .jet-form-builder__field-label.for-checkbox a:focus-visible { color: var(--wp--preset--color--white); }
/* Botón como CTA invertido: blanco sobre azul oscuro. */
.cs-buzon-box button.jet-form-builder__action-button.jet-form-builder__submit {
	background: var(--wp--preset--color--white); color: var(--wp--preset--color--blue-900);
}
.cs-buzon-box button.jet-form-builder__action-button.jet-form-builder__submit:hover,
.cs-buzon-box button.jet-form-builder__action-button.jet-form-builder__submit:focus-visible {
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-900);
}
@media (max-width: 781px) {
	.cs-buzon-box { padding: var(--wp--preset--spacing--6); }
	.cs-buzon-box .jet-form-builder.layout-column { grid-template-columns: 1fr; }
}

/* [cs_adhesion_pdf] sin PDF adjunto: misma píldora que .cs-btn pero SIN badge de flecha, en el
   tono "review" (cream, ya usado para el estado "PDF pendiente" del DocumentCard, .cs-doc__pending)
   — no es un enlace, así que no lleva la afordancia de flecha ni cursor de puntero. */
.cs-btn--disabled {
	background: var(--wp--custom--state--review-bg); color: var(--wp--custom--state--review-ink);
	padding: 0 var(--wp--preset--spacing--5); cursor: default;
}
.cs-btn--disabled::after { display: none; }

/* --- Formulario JetFormBuilder "Buzón Agenda 2030" (clases reales verificadas en staging,
   v3.6.3.1): .jet-form-builder.layout-column envuelve filas .jet-form-builder__field-wrap con
   label .jet-form-builder__field-label (variante .for-checkbox) y campo .jet-form-builder__field
   (.text-field/.textarea-field select; .checkboxes-field.checkradio-field en los checkbox). --- */
.jet-form-builder.layout-column {
	display: flex; flex-direction: column; gap: var(--wp--preset--spacing--5);
	max-width: 560px; margin-top: var(--wp--preset--spacing--6);
}
.jet-form-builder__field-wrap { display: flex; flex-direction: column; gap: 6px; }
.jet-form-builder__field-label {
	font-family: var(--wp--preset--font-family--jakarta); font-weight: 600;
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--heading);
}
/* Etiqueta de checkbox: fila con la caja a la izquierda (la propia etiqueta lleva el texto +
   enlace de privacidad, no un <label> aparte); peso normal, cuerpo, no eyebrow-heading. */
.jet-form-builder__field-label.for-checkbox {
	display: flex; align-items: flex-start; gap: 10px;
	font-weight: 500; color: var(--wp--custom--text--body); font-size: var(--wp--preset--font-size--sm);
}
.jet-form-builder__field-label.for-checkbox a { color: var(--wp--preset--color--blue-700); }
.jet-form-builder__field-label.for-checkbox a:hover,
.jet-form-builder__field-label.for-checkbox a:focus-visible { color: var(--wp--preset--color--blue-800); }

/* Input/select/textarea: borde suave + radio del sistema, foco visible AA (contorno azul + halo). */
.jet-form-builder__field {
	width: 100%; min-height: 46px; padding: 10px 16px;
	border: 1px solid var(--wp--preset--color--slate-300); border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--white); color: var(--wp--custom--text--body);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--body);
	transition: border-color .16s ease, box-shadow .16s ease;
}
textarea.jet-form-builder__field { min-height: 140px; padding-top: 12px; resize: vertical; }
.jet-form-builder__field:focus,
.jet-form-builder__field:focus-visible {
	outline: none; border-color: var(--wp--preset--color--blue-500);
	box-shadow: 0 0 0 3px var(--wp--preset--color--blue-100);
}
/* Checkbox: el wrapper .checkboxes-field.checkradio-field deja de ser una caja de texto y pasa a
   fila flex; la caja (18px) alineada con la primera línea de su etiqueta, acento azul. */
.jet-form-builder__field.checkboxes-field,
.jet-form-builder__field.checkradio-field {
	display: flex; flex-direction: column; gap: 8px;
	width: auto; min-height: 0; padding: 0; border: 0; background: transparent;
}
.jet-form-builder__field.checkboxes-field label,
.jet-form-builder__field.checkradio-field label {
	display: flex; align-items: flex-start; gap: 10px;
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.5;
}
.jet-form-builder__field.checkboxes-field input[type="checkbox"],
.jet-form-builder__field.checkradio-field input[type="checkbox"] {
	width: 18px; height: 18px; margin: 2px 0 0; flex: 0 0 auto;
	accent-color: var(--wp--preset--color--blue-600);
}
.jet-form-builder__field.checkboxes-field input[type="checkbox"]:focus-visible,
.jet-form-builder__field.checkradio-field input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-500); outline-offset: 2px;
}

/* Botón "Enviar mensaje": misma familia visual que .cs-btn--primary (píldora azul, texto blanco),
   sin el badge circular de flecha (es un <button>, no un enlace con afordancia de navegación). */
button.jet-form-builder__action-button.jet-form-builder__submit {
	display: inline-flex; align-items: center; justify-content: center; align-self: flex-start;
	min-height: 46px; padding: 0 var(--wp--preset--spacing--6);
	border: 0; border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--jakarta); font-size: var(--wp--preset--font-size--body);
	font-weight: 600; line-height: 1; cursor: pointer; transition: background-color .16s ease;
}
button.jet-form-builder__action-button.jet-form-builder__submit:hover,
button.jet-form-builder__action-button.jet-form-builder__submit:focus-visible {
	background: var(--wp--preset--color--blue-700);
}
button.jet-form-builder__action-button.jet-form-builder__submit:focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-700); outline-offset: 3px;
}

/* ============================================================
   Tarjeta de propuesta ciudadana (Listing Item `propuesta-card`) —
   /participa/, banda "Propuestas ciudadanas". Fondo BLANCO (is-style-card,
   NO tint: no está sobre una banda azul clara), radio xl como el resto de
   tarjetas de listado. Sin foto, sin enlace (CPT public:false).
   ============================================================ */
.wp-block-group.cs-propuesta-card { border-radius: var(--wp--custom--radius--xl); }
.cs-propuesta-card { height: 100%; }
.cs-propuesta-card [data-is-block] { display: contents; }
.cs-propuesta-card :where(p, h3) { margin-block: 0; }
.cs-propuesta { display: flex; flex-direction: column; gap: 10px; padding: var(--wp--preset--spacing--5); height: 100%; }
.cs-propuesta > * { margin-block: 0; }
.cs-propuesta__title { font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); line-height: 1.3; }
.cs-propuesta__desc { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.55; }
.cs-propuesta__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cs-propuesta__meta > * { margin-block: 0; }
.cs-propuesta__by { font-size: var(--wp--preset--font-size--xs); color: var(--wp--custom--text--muted); margin-top: auto; padding-top: 4px; }

/* --- StatePill: variantes de tramitación de la propuesta ciudadana --- */
/* Recibida = tono "active" (blue-100/blue-800, coincide con state--activeInk); En estudio = tono
   "review" (cream, ya usado como "en trámite/pendiente" en el DocumentCard); Aceptada = tono "done"
   (azul más oscuro = resolución positiva); Rechazada = neutro (slate-100/slate-600, mismo criterio
   que StatePill--archivado): NADA de rojo/verde, solo azules + un neutro, contraste AA. */
.cs-statepill--recibida   { background: var(--wp--custom--state--active-bg); color: var(--wp--custom--state--active-ink); }
.cs-statepill--en-estudio { background: var(--wp--custom--state--review-bg); color: var(--wp--custom--state--review-ink); }
.cs-statepill--aceptada   { background: var(--wp--custom--state--done-bg);   color: var(--wp--custom--state--done-ink); }
.cs-statepill--rechazada  { background: var(--wp--preset--color--slate-100); color: var(--wp--preset--color--slate-600); }

/* ============================================================
   Página /contacto/ (última página del frontend) — cuerpo a 2 columnas
   (Buzón + sidebar "Datos de contacto") y fila de mapa a ancho completo.
   El CSS del propio formulario JetFormBuilder (.jet-form-builder*) YA
   EXISTE arriba (§Página /participa/) y NO se toca aquí: solo se añade
   la maquetación de columnas, el sidebar y el contenedor del mapa.
   Reutiliza .cs-part-sec/.cs-part-sec__head (§/participa/) para los
   encabezados de sección; namespace propio .cs-contact* para lo nuevo.
   Sin sombra/borde; solo azules corporativos; WCAG AA.
   ============================================================ */

/* Rejilla 2 columnas (form / sidebar 340), colapsa a 1 columna ≤900 —
   mismo criterio que .cs-layout de single-proyecto. */
.cs-contact { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--wp--preset--spacing--10); align-items: start; }
.cs-contact > * { margin-block: 0; }
.cs-contact__form > * { margin-block: 0; }
.cs-contact__form .cs-part-sec__head { margin-bottom: var(--wp--preset--spacing--6); }

/* Sidebar "Datos de contacto" (neutral, sticky, is-style-card = sin sombra/borde). */
.cs-contact__data { position: sticky; top: 96px; padding: var(--wp--preset--spacing--6); }
.cs-contact__data > * { margin-block: 0; }
.cs-contact__title { font-size: var(--wp--preset--font-size--h-4); color: var(--wp--custom--text--heading); margin-bottom: var(--wp--preset--spacing--2); }
.cs-contact__org { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); line-height: 1.5; margin-bottom: var(--wp--preset--spacing--5); }

.cs-contact__list { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--4); }
.cs-contact__item { display: flex; gap: 12px; align-items: flex-start; }
.cs-contact__ic {
	flex: 0 0 auto; width: 32px; height: 32px; margin-top: 1px; border-radius: 8px;
	background: var(--wp--preset--color--blue-100); color: var(--wp--preset--color--blue-600);
	display: inline-flex; align-items: center; justify-content: center;
}
.cs-contact__body { display: flex; flex-direction: column; gap: 2px; }
.cs-contact__label { font-size: var(--wp--preset--font-size--eyebrow); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; color: var(--wp--custom--text--muted); }
.cs-contact__value { font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--body); line-height: 1.5; }
.cs-contact__value a { color: var(--wp--preset--color--blue-700); }

@media (max-width: 900px) {
	.cs-contact { grid-template-columns: 1fr; }
	.cs-contact__data { position: static; }
}

/* Botón "Ver mapa" al pie del sidebar "Datos de contacto": abre la ubicación en Google Maps (pestaña
   nueva). Sustituye a la fila de mapa embebido (el iframe de Google no pinta en la UE sin
   consentimiento de cookies). Ocupa el ancho del sidebar; separación del listado de datos arriba. */
.cs-contact__map-btn { margin-top: var(--wp--preset--spacing--6); }
/* Hover: OSCURECER (blue-600 → blue-800) en vez de invertir a blanco; el texto sigue blanco y el
   badge se mantiene (círculo blanco + flecha azul). Pisa el hover de .cs-btn--primary (más arriba en
   el fichero, misma especificidad) por orden de cascada. */
a.cs-contact__map-btn:hover,
a.cs-contact__map-btn:focus-visible { color: var(--wp--preset--color--white); }
.cs-contact__map-btn:hover,
.cs-contact__map-btn:focus-visible { background: var(--wp--preset--color--blue-800); }
.cs-contact__map-btn:hover::after,
.cs-contact__map-btn:focus-visible::after { background-color: var(--wp--preset--color--white); background-image: var(--cs-arrow-blue); }

/* ============================================================
   Galería del proyecto (single-proyecto) — réplica del componente
   Gallery del design system (cs-gallery.jsx, export 2026-08-21):
   marco tintado radio-xl padding 12, media 16/9 radio-md, flechas
   circulares 44 blancas→azul, pie + dots píldora + contador. El
   lightbox es adicional (petición del propietario): <dialog> con
   fondo oscuro semitransparente.
   ============================================================ */
.cs-gal__title { margin-top: var(--wp--preset--spacing--10); }
.cs-gal {
	margin: 0;
	background: var(--wp--preset--color--blue-100);
	border-radius: var(--wp--custom--radius--xl);
	padding: 12px;
}
.cs-gal__media {
	position: relative;
	aspect-ratio: 16 / 9;
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
	background: var(--wp--preset--color--blue-50);
}
.cs-gal__slide {
	position: absolute; inset: 0; width: 100%; height: 100%;
	border: none; padding: 0; background: none; cursor: zoom-in;
	opacity: 0; transition: opacity .32s ease; pointer-events: none;
}
.cs-gal__slide.is-on { opacity: 1; pointer-events: auto; }
.cs-gal__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-gal__arrow {
	position: absolute; top: 50%; transform: translateY(-50%);
	width: 44px; height: 44px; border-radius: 999px; border: none; padding: 0;
	display: inline-flex; align-items: center; justify-content: center;
	background: var(--wp--preset--color--white); color: var(--wp--preset--color--blue-600);
	cursor: pointer; transition: background .18s ease, color .18s ease; z-index: 2;
}
.cs-gal__arrow--prev { left: var(--wp--preset--spacing--4); }
.cs-gal__arrow--next { right: var(--wp--preset--spacing--4); }
.cs-gal__arrow:hover,
.cs-gal__arrow:focus-visible { background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white); }
.cs-gal__foot {
	display: flex; align-items: center; gap: var(--wp--preset--spacing--4);
	padding: 12px 8px 4px;
}
.cs-gal__caption { flex: 1; font-size: var(--wp--preset--font-size--sm); color: var(--wp--custom--text--muted); line-height: 1.5; }
.cs-gal__dots { display: flex; gap: 6px; flex: 0 0 auto; }
.cs-gal__dot {
	width: 8px; height: 8px; border-radius: 999px; border: none; padding: 0; cursor: pointer;
	background: var(--wp--preset--color--blue-200); transition: width .2s ease, background .2s ease;
}
.cs-gal__dot.is-on { width: 22px; background: var(--wp--preset--color--blue-600); }
.cs-gal__count {
	flex: 0 0 auto; font-size: var(--wp--preset--font-size--xs); font-weight: 600;
	letter-spacing: 0.1em; color: var(--wp--custom--text--heading);
}
/* Lightbox: imagen a tamaño completo sobre fondo oscuro con transparencia. */
.cs-gal__lightbox {
	border: none; padding: 0; background: transparent;
	max-width: min(92vw, 1400px); max-height: 92vh; overflow: visible;
}
.cs-gal__lightbox::backdrop { background: rgba(15, 23, 42, 0.82); }
.cs-gal__lightbox img {
	display: block; width: 100%; max-height: 80vh; object-fit: contain;
	border-radius: var(--wp--custom--radius--md); background: transparent;
}
.cs-gal__lbcap {
	margin: 10px 44px 0 0; text-align: center;
	font-size: var(--wp--preset--font-size--sm); color: var(--wp--preset--color--blue-100); line-height: 1.5;
}
.cs-gal__lbcap:empty { display: none; }
.cs-gal__close {
	position: absolute; top: -12px; right: -12px;
	width: 44px; height: 44px; border-radius: 999px; border: none; padding: 0;
	display: inline-flex; align-items: center; justify-content: center;
	background: var(--wp--preset--color--white); color: var(--wp--preset--color--blue-600);
	cursor: pointer; transition: background .18s ease, color .18s ease; z-index: 2;
}
.cs-gal__close:hover,
.cs-gal__close:focus-visible { background: var(--wp--preset--color--blue-600); color: var(--wp--preset--color--white); }
@media (max-width: 600px) {
	.cs-gal__close { top: 4px; right: 4px; }
}
@media (prefers-reduced-motion: reduce) {
	.cs-gal__slide, .cs-gal__arrow, .cs-gal__dot { transition: none; }
}

/* ---------------------------------------------------------------------------
   Respaldo de paginación sin JavaScript (QA de accesibilidad, punto 10).
   El bloque de JetSmartFilters llega vacío al navegador y lo rellena su JS, así
   que sin scripts no existía ningún enlace de paginación. `inc/paginacion.php`
   emite enlaces reales en el servidor y aquí se ocultan en cuanto hay JS, para
   que no se vean dos paginaciones. Si el JS falla o tarda, los enlaces siguen.
   --------------------------------------------------------------------------- */
.cs-js .cs-pagefallback:not(.cs-pagefallback--siempre) { display: none; }

.cs-pagefallback { margin-top: var(--wp--preset--spacing--5); }

.cs-pagefallback .nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	justify-content: center;
}

/* Objetivo táctil ≥44px (WCAG 2.5.5) en todos los elementos, activos o no. */
.cs-pagefallback .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 12px;
	border-radius: 999px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	color: var(--wp--preset--color--blue-700);
	background: var(--wp--preset--color--blue-50);
}

.cs-pagefallback a.page-numbers:hover { background: var(--wp--preset--color--blue-100); }

.cs-pagefallback a.page-numbers:focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-700);
	outline-offset: 2px;
}

/* La página actual: sin enlace, contraste alto y marcada con aria-current. */
.cs-pagefallback .page-numbers.current {
	color: var(--wp--preset--color--white);
	background: var(--wp--preset--color--blue-700);
}

.cs-pagefallback .page-numbers.dots { background: none; min-width: 0; padding: 0 4px; }

/* ---------------------------------------------------------------------------
   QA de accesibilidad: foco visible en el botón de cerrar de Complianz.
   Es marcado de un tercero y no traía ningún indicador al recibir el foco.
   NOTA: el buscador de filtros se revisó y NO necesita nada. Su input quita el
   outline a propósito (regla de arriba) porque el anillo lo pinta la píldora
   contenedora con :focus-within — medido en la página real: 2px, 1200x48 y
   contraste 5,14:1, por encima del 3:1 que pide WCAG 1.4.11.
   --------------------------------------------------------------------------- */
.cmplz-close:focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-700);
	outline-offset: 2px;
}
