/* ==========================================================================
   Casabiel Cubiertas — sistema visual
   Port literal del prototipo. Todos los valores (tamaños, pesos, opacidades,
   grosores de línea, paddings) están copiados de los HTML de referencia:
   Home, Servicios, Servicio, Obras, Quiénes Somos, FAQ, Trabaja, Contacto,
   Landing, Header, Footer y Formulario.

   No depende del personalizador de Astra: los colores y la tipografía están
   fijados aquí. Lo que se toque en el personalizador es cosmético y no puede
   romper la composición.

    0. Anulación de Astra
    1. Tokens
    2. Base
    3. Contenedor y retículas
    4. Tipografía
    5. Cabecera de página y banda de claim
    6. Botones y flechas
    7. Hero de la home
    8. Tarjetas de servicio destacado
    9. Mosaico de servicios
   10. Celdas de retícula con líneas
   11. Banner COMPROMISO
   12. Caja de presentación
   13. Cifras
   14. Testimonios
   15. Obras
   16. Clientes
   17. Ficha de servicio
   18. Galería
   19. Acordeón (FAQ)
   20. Formularios
   21. Modales
   22. Footer y menús de Astra
   23. Animaciones y reveals
   24. Utilidades
   25. Responsive
   ========================================================================== */

/* 0. ANULACIÓN DE ASTRA =====================================================
   Astra imprime su CSS dinámico en línea, después de este archivo, así que
   todo lo que pueda pisar la composición se neutraliza con especificidad de
   body.cb-site y, donde no hay otra vía, con !important. Es deliberado: el
   diseño no debe depender de qué valores haya en el personalizador. */

body.cb-site,
body.cb-site .site,
body.cb-site #page,
body.cb-site #content,
body.cb-site .site-content,
body.cb-site .ast-container,
body.cb-site .ast-container-fluid,
body.cb-site #primary,
body.cb-site .site-main,
body.cb-site .entry-content,
body.cb-site .ast-article-single,
body.cb-site .ast-article-post,
body.cb-site .ast-separate-container,
body.cb-site .ast-separate-container .ast-article-single,
body.cb-site .ast-plain-container .site-content {
	background: transparent;
	background-color: transparent;
	box-shadow: none;
}

/* En el CONTENIDO, el contenedor de Astra tiene que desaparecer: las líneas
   de 1px del diseño llegan al borde de la ventana y el ancho lo pone .cb-wrap
   por dentro. Ojo: esto se limita al área de contenido a propósito. El header
   y el footer los monta Israel con el constructor de Astra y ahí el contenedor
   SÍ tiene que seguir centrando. */
body.cb-site #content .ast-container,
body.cb-site .site-content > .ast-container,
body.cb-site #primary > .ast-container {
	max-width: none !important;
	width: 100% !important;
	padding-left: 0 !important;
	padding-right: 0 !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
	display: block !important;
}

/*
 * Y AQUÍ ESTABA EL FALLO EN MÓVIL.
 *
 * Astra le pone padding lateral a #content en las pantallas pequeñas. La regla
 * de arriba se lo quita al .ast-container de dentro, pero además .cb-wrap
 * dependía de ese padding en algunos sitios donde el contenido no va envuelto
 * en un .cb-wrap: los bloques a ancho completo, el contenido del editor y lo
 * que pinta un shortcode. Sin el padding de Astra y sin .cb-wrap, el texto se
 * iba de lado a lado de la pantalla.
 *
 * La solución no es devolver el padding a Astra —eso rompería las líneas de
 * 1px— sino asegurarse de que TODO lo que se pinta suelto lleve el gutter.
 */
body.cb-site #content,
body.cb-site .site-content {
	padding-left: 0 !important;
	padding-right: 0 !important;
}

/*
 * Red de seguridad: cualquier hijo directo de la zona de contenido que no sea
 * uno de los bloques a sangre (bandas, banners, hero, secciones que ya traen su
 * .cb-wrap dentro) recibe el gutter. Así el contenido del editor, un shortcode
 * o un bloque de Gutenberg nunca se pegan al borde.
 */
body.cb-site .entry-content > *:not(.cb-wrap):not(.cb-band):not(.cb-band--both):not(.cb-banner):not(.cb-hero):not(.cb-claim):not(section):not(.alignfull):not(.alignwide) {
	padding-left: var(--cb-gutter, 24px);
	padding-right: var(--cb-gutter, 24px);
	max-width: var(--cb-max);
	margin-left: auto;
	margin-right: auto;
	box-sizing: border-box;
}

/* Header y footer: mismo contenedor que el resto del sitio, 1400px con el
   mismo gutter, para que el logotipo y el menú caigan a plomo con el
   contenido de las páginas. */
body.cb-site .site-header .ast-container,
body.cb-site .site-footer .ast-container,
body.cb-site .ast-builder-grid-row-container-inner,
body.cb-site .site-primary-header-wrap.ast-container,
body.cb-site .site-primary-footer-wrap.ast-container,
body.cb-site .ast-primary-header-bar .ast-container,
body.cb-site #ast-desktop-header .ast-container,
body.cb-site #ast-mobile-header .ast-container,
body.cb-site .site-primary-header-wrap > .ast-container,
body.cb-site .site-above-header-wrap > .ast-container,
body.cb-site .site-below-header-wrap > .ast-container,
body.cb-site .site-primary-footer-wrap > .ast-container,
body.cb-site .site-above-footer-wrap > .ast-container,
body.cb-site .site-below-footer-wrap > .ast-container,
body.cb-site .ast-mobile-header-content,
body.cb-site .ast-desktop-header-content,
body.cb-site .site-below-footer-wrap .ast-builder-grid-row,
body.cb-site .site-primary-footer-wrap .ast-builder-grid-row,
/*
 * En móvil Astra monta otra estructura: #ast-mobile-header con sus propios
 * wraps, y los selectores de escritorio no existen. Sin estos, el logotipo y el
 * botón del menú se pegaban al borde de la pantalla.
 */
body.cb-site .ast-mobile-header-wrap > .ast-main-header-wrap > .ast-primary-header-bar,
body.cb-site #ast-mobile-header .ast-primary-header-bar,
body.cb-site .ast-mobile-popup-inner > .ast-mobile-popup-content,
body.cb-site .ast-mobile-header-content > .ast-builder-menu-mobile,
body.cb-site .ast-above-footer-wrap .ast-builder-grid-row {
	max-width: var(--cb-max) !important;
	width: 100% !important;
	margin-left: auto !important;
	margin-right: auto !important;
	padding-left: var(--cb-gutter, 24px) !important;
	padding-right: var(--cb-gutter, 24px) !important;
	box-sizing: border-box !important;
}

body.cb-site #primary,
body.cb-site .site-main,
body.cb-site .entry-content,
body.cb-site .ast-article-single {
	max-width: none !important;
	width: 100% !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
}

/*
 * Restos de plantilla de blog que Astra pinta y aquí no pintan nada.
 *
 * Incluye las migas de pan: el tema ya no las imprime, pero Astra tiene las
 * suyas —y Rank Math otras— y se pueden activar desde el personalizador o desde
 * los ajustes del plugin sin querer. Aquí quedan ocultas en cualquier caso.
 */
body.cb-site .ast-breadcrumbs,
body.cb-site .ast-breadcrumbs-wrapper,
body.cb-site .rank-math-breadcrumb,
body.cb-site .breadcrumbs,
body.cb-site .yoast-breadcrumb,
body.cb-site #secondary,
body.cb-site .ast-single-post-order,
body.cb-site .ast-archive-description,
body.cb-site .page-links,
body.cb-site .post-navigation,
body.cb-site .ast-author-details,
body.cb-site .ast-blog-featured-section,
body.cb-site .read-more {
	display: none !important;
}

/* Tipografía y color: mandan los nuestros, no los del personalizador. */
body.cb-site,
body.cb-site p,
body.cb-site li,
body.cb-site td,
body.cb-site th,
body.cb-site dd,
body.cb-site dt,
body.cb-site blockquote,
body.cb-site h1,
body.cb-site h2,
body.cb-site h3,
body.cb-site h4,
body.cb-site h5,
body.cb-site h6,
body.cb-site input,
body.cb-site select,
body.cb-site textarea,
body.cb-site button,
body.cb-site .entry-title,
body.cb-site .widget-title {
	font-family: 'League Spartan', system-ui, -apple-system, 'Segoe UI', sans-serif;
	color: #fff;
}

body.cb-site h1,
body.cb-site h2,
body.cb-site h3,
body.cb-site h4,
body.cb-site h5,
body.cb-site h6 {
	text-transform: none;
	letter-spacing: normal;
}

/* Astra estiliza los enlaces y los botones del contenido. */
body.cb-site a,
body.cb-site .entry-content a {
	box-shadow: none;
	text-decoration: none;
}

body.cb-site .cb-btn,
body.cb-site button.cb-btn,
body.cb-site input.cb-btn,
body.cb-site .entry-content .cb-btn {
	border-radius: 0 !important;
	box-shadow: none !important;
}

body.cb-site .entry-content > *:first-child {
	margin-top: 0;
}

body.cb-site .entry-content > *:last-child {
	margin-bottom: 0;
}

body.cb-site img,
body.cb-site figure {
	border-radius: 0;
	box-shadow: none;
}

/* 1. TOKENS ================================================================ */
:root {
	--cb-bg: #363845;
	--cb-bg-soft: #424557;
	--cb-bg-deep: #2C2E3A;
	--cb-accent: #A4163F;
	--cb-accent-soft: #E4708F;

	/* Los grosores de línea del prototipo, ni uno más. */
	--cb-line: rgba(255, 255, 255, .16);
	--cb-line-12: rgba(255, 255, 255, .12);
	--cb-line-14: rgba(255, 255, 255, .14);
	--cb-line-18: rgba(255, 255, 255, .18);
	--cb-line-20: rgba(255, 255, 255, .20);
	--cb-line-24: rgba(255, 255, 255, .24);
	--cb-line-30: rgba(255, 255, 255, .30);
	--cb-line-strong: rgba(255, 255, 255, .30);
	--cb-line-soft: rgba(255, 255, 255, .12);

	--cb-text: #fff;
	--cb-text-85: rgba(255, 255, 255, .85);
	--cb-text-82: rgba(255, 255, 255, .82);
	--cb-text-75: rgba(255, 255, 255, .75);
	--cb-text-74: rgba(255, 255, 255, .74);
	--cb-text-72: rgba(255, 255, 255, .72);
	--cb-text-70: rgba(255, 255, 255, .70);
	--cb-text-68: rgba(255, 255, 255, .68);
	--cb-text-66: rgba(255, 255, 255, .66);
	--cb-text-65: rgba(255, 255, 255, .65);
	--cb-text-62: rgba(255, 255, 255, .62);
	--cb-text-60: rgba(255, 255, 255, .60);
	--cb-text-55: rgba(255, 255, 255, .55);
	--cb-text-50: rgba(255, 255, 255, .50);
	--cb-text-45: rgba(255, 255, 255, .45);
	--cb-text-40: rgba(255, 255, 255, .40);
	--cb-text-30: rgba(255, 255, 255, .30);

	--cb-font: 'League Spartan', system-ui, -apple-system, 'Segoe UI', sans-serif;
	--cb-max: 1980px;
	/*
	 * Gutter. Antes era clamp(18px, 4vw, 40px), que a 390px de ancho daba 18px:
	 * demasiado poco para un texto a 17px, el contenido parecía pegado. Y no
	 * llegaba a los 40 hasta 1000px, así que en tableta se quedaba corto.
	 * Ahora arranca en 20 y llega a 40 a los 768px.
	 */
	--cb-gutter: clamp(20px, 6.275px + 3.922vw, 40px);
	--cb-measure: 820px;

	/* ------------------------------------------------------------------
	   Escala tipográfica fluida.

	   Cada tamaño crece linealmente entre 1400px y 1980px de ventana. La
	   fórmula de los dos puntos es:

	     pendiente = (grande - pequeño) / (1980 - 1400)
	     vw        = pendiente × 100
	     fijo      = pequeño - pendiente × 1400

	   El primer valor del clamp es el tamaño que ya tenía el proyecto, así
	   que POR DEBAJO DE 1400px no cambia absolutamente nada: la web se ve
	   hoy igual que ayer en portátil, tableta y móvil. Solo crece cuando la
	   ventana pasa de 1400.
	   ------------------------------------------------------------------ */
	--cb-fs-xxs:   clamp(11px, 8.586px + 0.172vw, 12px);   /* 11 → 12 */
	--cb-fs-xs:    clamp(12px, 7.172px + 0.345vw, 14px);   /* 12 → 14 */
	--cb-fs-sm:    clamp(13px, 8.172px + 0.345vw, 15px);   /* 13 → 15 */
	--cb-fs-md:    clamp(16px, 11.172px + 0.345vw, 18px);  /* 16 → 18 */
	--cb-fs-base:  clamp(18px, 10.759px + 0.517vw, 21px);  /* 18 → 21 */
	--cb-fs-lg:    clamp(20px, 12.759px + 0.517vw, 23px);  /* 20 → 23 */
	--cb-fs-xl:    clamp(21px, 13.759px + 0.517vw, 24px);  /* 21 → 24 */
	--cb-fs-quote: clamp(22px, 12.345px + 0.690vw, 26px);  /* 22 → 26 */
	--cb-fs-num:   clamp(24px, 14.345px + 0.690vw, 28px);  /* 24 → 28 */
	--cb-fs-tel:   clamp(34px, 19.517px + 1.034vw, 40px);  /* 34 → 40 */

	/* Ritmo vertical del prototipo. */
	--cb-s70: 70px;
	--cb-s80: 80px;
	--cb-s90: 90px;
	--cb-s100: 100px;
	--cb-s110: 110px;

	--cb-t: .3s;
	--cb-t-mid: .35s;
	--cb-t-slow: .45s;
	--cb-t-slower: .55s;
	--cb-ease: cubic-bezier(.16, 1, .3, 1);
}

/* 2. BASE ================================================================== */
html,
body {
	margin: 0;
	padding: 0;
	background: var(--cb-bg);
}

body.cb-site {
	font-family: var(--cb-font);
	color: var(--cb-text);
	font-weight: 300;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

body.cb-site a {
	color: #fff;
	text-decoration: none;
	transition: color var(--cb-t);
}

/*
 * Hover de los enlaces.
 *
 * Esta regla era body.cb-site a:hover, con especificidad (0,2,2), y le ganaba a
 * todos los componentes: .cb-filters a:hover es (0,2,1). Resultado: un botón de
 * filtro con fondo granate se quedaba con el texto también en granate, o sea
 * invisible. Ahora el granate del hover solo se aplica a los enlaces de texto
 * corrido —los que no llevan clase— y a los sitios donde se pide a propósito.
 * Cada componente manda sobre su propio hover.
 */
body.cb-site a:where(:not([class])):hover,
body.cb-site a:where(:not([class])):focus-visible,
body.cb-site .cb-text a:hover,
body.cb-site .cb-legal a:hover,
body.cb-site .cb-legal-menu a:hover,
body.cb-site .cb-legal-menu button:hover,
body.cb-site a.cb-dato:hover,
body.cb-site .site-footer a:hover {
	color: var(--cb-accent);
}

::selection {
	background: var(--cb-accent);
	color: #fff;
}

body.cb-site img {
	max-width: 100%;
	height: auto;
	display: block;
}

body.cb-site input,
body.cb-site textarea,
body.cb-site button,
body.cb-site select {
	font-family: inherit;
}

body.cb-site input::placeholder,
body.cb-site textarea::placeholder {
	color: var(--cb-text-30);
}

body.cb-site strong,
body.cb-site b {
	font-weight: 500;
}

body.cb-site em,
body.cb-site i {
	font-style: normal;
}

hr {
	border: none;
	border-top: 1px solid var(--cb-line);
	margin: 0;
}

[hidden] {
	display: none !important;
}

#cb-main {
	position: relative;
	background: var(--cb-bg);
	/* Red de seguridad: si algo mide mal, se recorta en vez de romper la
	   maqueta y aparecer barra horizontal en toda la web. */
	max-width: 100vw;
	overflow-x: clip;
}

/* La cita del testimonio: el prototipo la deja correr a todo el ancho de su
   columna, pero con una línea de 1.250px se lee fatal. Se limita a la medida
   de lectura que usa el resto del sitio. */
.cb-testi__swiper .cb-quote {
	max-width: 1100px;
}

/* 3. CONTENEDOR Y RETÍCULAS ================================================ */
.cb-wrap {
	max-width: var(--cb-max);
	margin: 0 auto;
	padding: 0 var(--cb-gutter, 24px);
}

/* Secciones. En el prototipo casi todas llevan solo padding arriba y la
   siguiente aporta el suyo, de ahí los modificadores. */
.cb-section {
	padding: var(--cb-s100) 0 0;
}

.cb-section--both {
	padding: var(--cb-s100) 0;
}

.cb-section--tight {
	padding: var(--cb-s70) 0 0;
}

.cb-section--80 {
	padding: var(--cb-s80) 0 0;
}

.cb-section--90 {
	padding: var(--cb-s90) 0 0;
}

.cb-section--110 {
	padding: var(--cb-s110) 0 0;
}

.cb-section--flush {
	padding-bottom: 0;
}

.cb-section--top {
	padding-top: var(--cb-s110);
}

/* Bandas: la línea llega al borde de la ventana, el contenido no. */
.cb-band {
	border-top: 1px solid var(--cb-line);
}

.cb-band--both {
	border-top: 1px solid var(--cb-line);
	border-bottom: 1px solid var(--cb-line);
}

.cb-grid {
	display: grid;
}

.cb-grid--2 { grid-template-columns: repeat(2, 1fr); }
.cb-grid--3 { grid-template-columns: repeat(3, 1fr); }
.cb-grid--4 { grid-template-columns: repeat(4, 1fr); }
.cb-grid--auto { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.cb-grid--auto-sm { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.cb-grid--auto-210 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.cb-grid--auto-275 { grid-template-columns: repeat(auto-fit, minmax(275px, 1fr)); }
.cb-grid--auto-290 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
/* 340px da tres columnas a 1400, dos en tableta y una en móvil: con seis
   testimonios las filas salen siempre completas. */
.cb-grid--auto-340 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.cb-grid--gap { gap: 24px; }

/* Separación por línea de 1px.
 *
 * El prototipo lo hace con un fondo del color de la línea y un gap de 1px, con
 * las celdas opacas encima. Funciona mientras la última fila esté completa: en
 * cuanto sobra un hueco, ese hueco enseña el fondo y aparece un rectángulo
 * gris del tamaño de las celdas que faltan. Con seis testimonios en cuatro
 * columnas pasaba justo eso.
 *
 * Aquí las líneas se dibujan con bordes en cada celda. Se ve exactamente igual
 * cuando la fila está completa, y cuando no lo está el hueco simplemente queda
 * vacío. */
.cb-lines {
	display: grid;
	gap: 0;
	border-top: 1px solid var(--cb-line);
	border-left: 1px solid var(--cb-line);
}

.cb-lines > * {
	background: var(--cb-bg);
	border-right: 1px solid var(--cb-line);
	border-bottom: 1px solid var(--cb-line);
	min-width: 0;
}

/* Variante con bordes reales (los servicios destacados de la home): la
   retícula cierra por los dos costados y cada celda pone su línea derecha. */
.cb-grid--lines {
	border-left: 1px solid var(--cb-line);
	border-right: 1px solid var(--cb-line);
}

.cb-grid--lines > * {
	border-right: 1px solid var(--cb-line);
}

.cb-grid--lines > *:last-child {
	border-right: none;
}

.cb-split {
	display: grid;
	grid-template-columns: 1.05fr 1fr;
	gap: clamp(30px, 4.5vw, 60px);
	align-items: center;
}

.cb-split--wide {
	display: grid;
	grid-template-columns: 1.6fr 1fr;
	gap: 0;
}

.cb-split--text {
	display: grid;
	grid-template-columns: 1fr 1.25fr;
	gap: clamp(34px, 5vw, 70px);
	align-items: start;
}

.cb-split--nav {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: clamp(30px, 4.5vw, 60px);
	align-items: center;
}

.cb-box { border: 1px solid var(--cb-line-30); }
.cb-box--soft { border: 1px solid var(--cb-line); }
.cb-box--24 { border: 1px solid var(--cb-line-24); }

/* 4. TIPOGRAFÍA ============================================================ */
.cb-h1,
body.cb-site h1.cb-h1 {
	font-size: clamp(34px, 4.4vw, 64px);
	font-weight: 200;
	line-height: 1.12;
	letter-spacing: .02em;
	margin: 0 0 56px;
	text-wrap: balance;
}

.cb-h2,
body.cb-site h2.cb-h2 {
	font-size: clamp(30px, 5vw, 52px);
	font-weight: 600;
	line-height: 1.18;
	margin: 0 0 .6em;
	text-wrap: balance;
}

.cb-h2--light {
	font-weight: 500;
	line-height: 1.14;
}

/* El tamaño intermedio que el prototipo repite en casi todos los bloques. */
.cb-h3,
body.cb-site h3.cb-h3 {
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 600;
	line-height: 1.3;
	margin: 0 0 .6em;
}

.cb-h4,
body.cb-site h4.cb-h4 {
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 600;
	line-height: 1.3;
	margin: 0 0 .5em;
}

.cb-h5 {
	font-size: var(--cb-fs-xl);
	font-weight: 600;
	line-height: 1.3;
	margin: 0 0 12px;
}

.cb-lead {
	font-size: var(--cb-fs-lg);
	line-height: 1.75;
	color: var(--cb-text-70);
	margin: 0 0 1em;
	font-weight: 300;
}

.cb-text {
	font-size: var(--cb-fs-base);
	line-height: 1.85;
	color: var(--cb-text-74);
}

.cb-text p,
.cb-text ul,
.cb-text ol {
	margin: 0 0 22px;
	font-size: var(--cb-fs-base);
	line-height: 1.85;
	color: var(--cb-text-74);
}

.cb-text > *:last-child {
	margin-bottom: 0;
}

.cb-text h2 {
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 600;
	line-height: 1.3;
	margin: 44px 0 18px;
}

.cb-text h3 {
	font-size: var(--cb-fs-xl);
	font-weight: 600;
	margin: 34px 0 14px;
}

.cb-text a:not(.cb-btn):not(.cb-link-arrow) {
	border-bottom: 1px solid var(--cb-line-30);
}

.cb-text a:hover {
	border-color: var(--cb-accent);
}

.cb-text ul,
.cb-text ol {
	padding-left: 20px;
}

.cb-text li {
	margin-bottom: 8px;
}

.cb-note {
	font-size: var(--cb-fs-md);
	color: var(--cb-text-45);
}

.cb-center { text-align: center; }

.cb-measure {
	max-width: 820px;
	margin-left: auto;
	margin-right: auto;
}

/* Antetítulo: línea granate de 52px + texto espaciado. */
.cb-eyebrow {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-bottom: clamp(10px, 2.4vh, 30px);
	font-size: var(--cb-fs-md);
	font-weight: 600;
	letter-spacing: .2em;
	color: var(--cb-text-60);
	text-transform: uppercase;
}

.cb-eyebrow span {
	width: 52px;
	height: 1px;
	background: var(--cb-accent);
	flex: none;
}

.cb-eyebrow--center {
	justify-content: center;
}

/* Filete suelto sobre un titular. */
.cb-rule {
	width: 56px;
	height: 1px;
	background: var(--cb-accent);
	margin-bottom: 26px;
}

.cb-rule--sm {
	width: 44px;
	margin-bottom: 22px;
}

.cb-num {
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 200;
	color: var(--cb-accent);
}

/* Etiqueta pequeña espaciada: FICHA DEL SERVICIO, NAVEGACIÓN, DATOS… */
.cb-label {
	font-size: var(--cb-fs-xs);
	letter-spacing: .18em;
	color: var(--cb-text-45);
	margin-bottom: 18px;
	text-transform: uppercase;
}

/* 5. CABECERA DE PÁGINA Y BANDA DE CLAIM ===================================
   Todas las páginas interiores del prototipo abren igual: 170px de aire,
   un H1 gigantesco centrado en peso 200, y debajo una banda con dos líneas
   horizontales y dos verticales que encajonan un párrafo de 860px. */

.cb-page-header {
	padding: 170px 0 60px;
}

.cb-page-header__title,
body.cb-site h1.cb-page-header__title {
	margin: 0;
	font-size: clamp(52px, 9vw, 130px);
	font-weight: 200;
	letter-spacing: .06em;
	text-align: center;
	line-height: 1;
	text-transform: uppercase;
}

/* Titulares largos: el prototipo los baja de tamaño para que no rompan. */
.cb-page-header__title--long {
	font-size: clamp(40px, 6.4vw, 98px);
	letter-spacing: .05em;
	line-height: 1.05;
}

.cb-page-header__title--mid {
	font-size: clamp(46px, 7.6vw, 116px);
}

/* Ficha de servicio: H1 más contenido y con migas encima. */
.cb-page-header--servicio {
	padding: 150px 0 0;
}

.cb-page-header--servicio .cb-page-header__title {
	font-size: clamp(34px, 4.4vw, 64px);
	letter-spacing: .02em;
	line-height: 1.12;
	text-transform: none;
	margin-bottom: 56px;
	text-wrap: balance;
}

.cb-claim {
	border-top: 1px solid var(--cb-line);
	border-bottom: 1px solid var(--cb-line);
}

.cb-claim__grid {
	max-width: var(--cb-max);
	margin: 0 auto;
	padding: 0 var(--cb-gutter, 24px);
	display: grid;
	grid-template-columns: 1fr minmax(0, 860px) 1fr;
}

.cb-claim__grid::before,
.cb-claim__grid::after {
	content: "";
	display: block;
}

.cb-claim__grid::before { border-right: 1px solid var(--cb-line); }
.cb-claim__grid::after { border-left: 1px solid var(--cb-line); }

.cb-claim__text {
	padding: 34px clamp(20px, 4vw, 60px);
	text-align: center;
	margin: 0;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-65);
	grid-column: 2;
}


/* 6. BOTONES Y FLECHAS ===================================================== */

/* Sólido granate, versalitas espaciadas. */
.cb-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	background: var(--cb-accent);
	border: none;
	color: #fff;
	padding: 19px 34px;
	font-size: var(--cb-fs-md);
	font-weight: 400;
	letter-spacing: .18em;
	text-transform: uppercase;
	cursor: pointer;
	transition: opacity var(--cb-t);
	line-height: 1;
	font-family: inherit;
}

body.cb-site .cb-btn:hover,
body.cb-site .cb-btn:focus {
	opacity: .86;
	color: #fff;
}

/* Contorno claro que se rellena de granate. */
.cb-btn--ghost {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, .5);
	padding: clamp(11px, 1.8vh, 17px) clamp(22px, 3vw, 34px);
	font-size: var(--cb-fs-md);
	letter-spacing: normal;
	text-transform: none;
	transition: background var(--cb-t), border-color var(--cb-t);
}

body.cb-site .cb-btn--ghost:hover,
body.cb-site .cb-btn--ghost:focus {
	background: var(--cb-accent);
	border-color: var(--cb-accent);
	color: #fff;
	opacity: 1;
}

/* Contorno que se rellena del gris suave (acciones secundarias). */
.cb-btn--line {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, .45);
	padding: 16px 20px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .14em;
	transition: background var(--cb-t);
}

body.cb-site .cb-btn--line:hover,
body.cb-site .cb-btn--line:focus {
	background: var(--cb-bg-soft);
	color: #fff;
	opacity: 1;
}

.cb-btn--line-soft {
	border-color: rgba(255, 255, 255, .25);
	color: var(--cb-text-75);
}

/* El peso del archivo, dentro del botón de descarga. */
.cb-btn__meta {
	display: inline-block;
	margin-left: 8px;
	font-size: 11px;
	letter-spacing: .06em;
	color: var(--cb-text-50);
	text-transform: none;
}

/* Botón de acción de la ficha: texto a la izquierda, icono a la derecha. */
.cb-btn--block {
	width: 100%;
	justify-content: space-between;
	gap: 14px;
	padding: 17px 20px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .14em;
}

/* Botón de formulario: ancho completo, sin flecha. */
.cb-btn--submit {
	width: 100%;
	padding: 19px;
	font-size: var(--cb-fs-md);
	letter-spacing: .18em;
}

/* Enlace de texto con flecha. */
.cb-link-arrow {
	font-size: var(--cb-fs-md);
	color: var(--cb-text-65);
	padding: 12px 6px;
	display: inline-block;
}

body.cb-site .cb-link-arrow:hover { color: #fff; }

.cb-btn--pill {
	padding: 17px 34px;
	font-size: var(--cb-fs-md);
	letter-spacing: .1em;
}

/* Botones circulares de los sliders. */
body.cb-site .cb-round {
	/*
	 * Astra aplica padding: 15px 30px a todos los <button>. Un elemento
	 * border-box no puede ser más estrecho que su padding más el borde, así
	 * que los 52px de ancho se convertían en 62px (de ahí la elipse) y el
	 * hueco para el contenido quedaba en cero, por lo que la flecha
	 * desaparecía. El padding a cero es obligatorio, no cosmético.
	 */
	padding: 0 !important;
	width: 52px !important;
	height: 52px !important;
	min-width: 52px;
	min-height: 52px;
	max-width: 52px;
	max-height: 52px;
	box-sizing: border-box !important;
	border-radius: 50% !important;
	border: 1px solid var(--cb-text-40);
	background: transparent;
	color: #fff;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	line-height: 0;
	overflow: visible;
	transition: background var(--cb-t), border-color var(--cb-t);
}

body.cb-site .cb-round:hover,
body.cb-site .cb-round:focus {
	background: var(--cb-accent);
	border-color: var(--cb-accent);
	color: #fff;
}

body.cb-site .cb-round--sm {
	width: 46px !important;
	height: 46px !important;
	min-width: 46px;
	min-height: 46px;
	max-width: 46px;
	max-height: 46px;
}

.cb-nav-pair {
	display: flex;
	gap: 14px;
}


/* Iconos en línea (flechas, candado, teléfono, descarga).
   Los atributos fill y stroke de un SVG los pisa cualquier regla CSS, así que
   se declaran aquí. vector-effect mantiene el trazo a 1px real aunque el
   viewBox se escale, que es lo que evita que la línea se quede en nada. */
body.cb-site .cb-icon {
	display: block;
	flex: 0 0 auto;
	overflow: visible;
	max-width: none;
	height: auto;
	color: inherit;
}

body.cb-site .cb-icon path,
body.cb-site .cb-icon rect,
body.cb-site .cb-icon circle {
	fill: none;
	stroke: currentColor;
	vector-effect: non-scaling-stroke;
	stroke-linecap: square;
}

body.cb-site .cb-icon circle[fill] {
	fill: currentColor;
	stroke: none;
}

body.cb-site .cb-round .cb-icon {
	pointer-events: none;
}

/* 7. HERO DE LA HOME =======================================================
   El prototipo no usa slider: la sección mide 590vh, el contenido queda
   sticky y las diapositivas se cruzan según el scroll. Cada tramo de 0.7
   pantallas avanza una diapositiva. Las variables --cb-o / --cb-y las
   escribe el JS en cada slide. */

.cb-hero {
	position: relative;
	height: calc(var(--cb-hero-slides, 8) * 70vh + 100vh);
}

.cb-hero__sticky {
	position: sticky;
	top: 0;
	height: 100vh;
	display: flex;
	align-items: center;
	overflow: hidden;
}

.cb-hero__inner {
	max-width: var(--cb-max);
	margin: 0 auto;
	padding: 88px var(--cb-gutter, 24px) 74px;
	width: 100%;
	height: 100%;
	display: grid;
	align-content: center;
	/*
	 * El prototipo reparte 1.05fr / 1fr sobre 1400px, o sea unos 660px de
	 * imagen. Con el contenedor a 1980 esa proporción deja el texto en 940px
	 * —demasiado ancho para leer— y la imagen sin ganar nada. Se le da más peso
	 * a la imagen y el texto se queda en una medida legible.
	 */
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
	gap: clamp(30px, 4.5vw, 70px);
	align-items: center;
}

/* El texto del hero, a medida de lectura aunque la columna sea ancha. */
.cb-hero__stack {
	max-width: 720px;
}

.cb-hero__stack {
	position: relative;
	display: grid;
	min-height: 0;
}

.cb-hero__slide {
	grid-area: 1 / 1;
	align-self: start;
	opacity: var(--cb-o, 0);
	transform: translate3d(0, var(--cb-y, 0), 0);
	will-change: transform, opacity;
	pointer-events: none;
}

.cb-hero__slide.is-active {
	pointer-events: auto;
}

.cb-hero__num {
	font-size: 15px;
	letter-spacing: .2em;
	color: var(--cb-accent);
	margin-bottom: clamp(6px, 1.6vh, 14px);
}

.cb-hero__title,
body.cb-site h1.cb-hero__title {
	margin: 0 0 clamp(8px, 2vh, 18px);
	font-size: clamp(24px, min(3.4vw, 5.6vh), 54px);
	line-height: 1.12;
	font-weight: 200;
	text-wrap: balance;
	letter-spacing: normal;
}

.cb-hero__text {
	margin: 0 0 clamp(14px, 2.6vh, 26px);
	font-size: clamp(13px, min(1.25vw, 2vh), 17px);
	line-height: 1.6;
	color: var(--cb-text-72);
	max-width: 620px;
}

.cb-hero__actions {
	display: flex;
	gap: 16px;
	align-items: center;
	flex-wrap: wrap;
}

/* Recorte hexagonal de la imagen. */
/*
 * La imagen del hero.
 *
 * Antes era height: min(74vh, 100%), que es lo que dice el prototipo. El
 * problema es que ese 100% se mide contra la fila del grid, y la altura de la
 * fila la marca la columna de texto: con una diapositiva de texto corto la fila
 * bajaba a 380px y la imagen se quedaba en 380px en lugar de en 666. Por eso se
 * veía pequeña y variaba de tamaño entre diapositivas.
 *
 * Con una altura en vh la imagen manda sobre la fila y mide siempre lo mismo.
 */
.cb-hero__media {
	position: relative;
	align-self: stretch;
	height: clamp(420px, 78vh, 900px);
	overflow: hidden;
	/*
	 * El corte del prototipo. Antes iba al 14 %, que sobre 380px de alto son
	 * 53px de sesgo y casi no se apreciaba; a esta altura el ángulo se lee como
	 * en el diseño. Se deja en una variable para poder ajustarlo en un sitio.
	 */
	clip-path: polygon(0% var(--cb-hero-corte, 12%), 100% 0%, 100% calc(100% - var(--cb-hero-corte, 12%)), 0% 100%);
}

.cb-hero__layer {
	position: absolute;
	inset: -8% 0;
	background-size: cover;
	background-position: center;
	opacity: var(--cb-o, 0);
	transform: translate3d(0, var(--cb-img-y, 0), 0) scale(var(--cb-scale, 1));
	will-change: transform, opacity;
}

.cb-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(54, 56, 69, .22), rgba(54, 56, 69, .05));
	pointer-events: none;
}

/* Paginador de barras. */
.cb-hero__pager {
	position: absolute;
	bottom: 22px;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	gap: 14px;
	width: min(460px, 70vw);
	z-index: 3;
}

.cb-hero__bullet {
	flex: 1;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	display: flex;
	flex-direction: column;
	gap: 8px;
	align-items: center;
}

.cb-hero__bar {
	height: 2px;
	width: 100%;
	background: rgba(255, 255, 255, .22);
	display: block;
	position: relative;
	overflow: hidden;
}

.cb-hero__bar i {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: var(--cb-fill, 0%);
	background: var(--cb-accent);
	display: block;
}

.cb-hero__bullet em {
	font-size: var(--cb-fs-sm);
	letter-spacing: .14em;
	color: var(--cb-text-40);
	font-style: normal;
	transition: color .4s;
}

.cb-hero__bullet.is-active em {
	color: #fff;
}

/* Indicador de scroll. */
.cb-scrollhint {
	position: absolute;
	bottom: 30px;
	right: 40px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 9px;
	opacity: var(--cb-hint, 1);
	transition: opacity .4s;
	z-index: 3;
	/* El icono hereda el color: aquí es blanco al 50 %, como el prototipo. */
	color: rgba(255, 255, 255, .5);
}

.cb-scrollhint svg {
	animation: cb-bob 2.4s ease-in-out infinite;
}

.cb-scrollhint span {
	font-size: var(--cb-fs-xxs);
	letter-spacing: .26em;
	color: var(--cb-text-45);
}

/* 8. TARJETAS DE SERVICIO DESTACADO ======================================== */
.cb-card {
	position: relative;
	min-height: 520px;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	color: #fff;
	transition: box-shadow var(--cb-t-slow), background var(--cb-t-slow);
}

body.cb-site .cb-card:hover,
body.cb-site .cb-card:focus-visible {
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28), 0 0 44px rgba(255, 255, 255, .14);
	background: rgba(255, 255, 255, .04);
	color: #fff;
}

.cb-card__bg {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	opacity: 0;
	transition: opacity var(--cb-t-slower);
}

.cb-card:hover .cb-card__bg { opacity: 1; }

.cb-card__veil {
	position: absolute;
	inset: 0;
	background: rgba(54, 56, 69, .62);
	opacity: 0;
	transition: opacity var(--cb-t-slower);
	pointer-events: none;
}

.cb-card:hover .cb-card__veil { opacity: 1; }

.cb-card__body {
	position: relative;
	flex: 1;
	padding: 48px 32px 20px;
	pointer-events: none;
}

.cb-card__num {
	display: block;
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 400;
	margin-bottom: 20px;
}

.cb-card__title {
	margin: 0 0 16px;
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 600;
	line-height: 1.25;
}

.cb-card__text {
	/* Es un <span> dentro del enlace de la tarjeta: sin block, ni el margen ni
	   el interlineado se comportan como en un párrafo. */
	display: block;
	margin: 0;
	font-size: var(--cb-fs-base);
	line-height: 1.75;
	color: var(--cb-text-70);
}

.cb-card__foot {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	border-top: 1px solid var(--cb-line);
	pointer-events: none;
}

.cb-card__foot span:first-child {
	padding: 20px 32px;
	font-size: var(--cb-fs-base);
	color: var(--cb-text-72);
}

.cb-card__foot span:last-child {
	padding: 20px 26px;
	border-left: 1px solid var(--cb-line);
	display: flex;
	align-items: center;
}

/* 9. MOSAICO DE SERVICIOS ================================================== */
.cb-tile {
	position: relative;
	display: block;
	aspect-ratio: 1 / 1.12;
	overflow: hidden;
	border: 1px solid var(--cb-line-18);
	color: #fff;
	transition: box-shadow var(--cb-t-slow), border-color var(--cb-t-slow), filter var(--cb-t-slow);
}

body.cb-site .cb-tile:hover,
body.cb-site .cb-tile:focus-visible {
	box-shadow: 0 0 44px rgba(255, 255, 255, .18), inset 0 0 0 1px rgba(255, 255, 255, .3);
	border-color: rgba(255, 255, 255, .5);
	filter: brightness(1.2) contrast(1.04);
	color: #fff;
}

.cb-tile__bg {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	opacity: .72;
}

.cb-tile::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(54, 56, 69, .15) 0%, rgba(54, 56, 69, .86) 78%);
}

.cb-tile__body {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 22px 22px 24px;
	z-index: 2;
}

.cb-tile__num {
	display: block;
	font-size: var(--cb-fs-xxs);
	letter-spacing: .2em;
	color: var(--cb-text-55);
	margin-bottom: 8px;
}

.cb-tile__title {
	display: block;
	font-size: var(--cb-fs-base);
	font-weight: 600;
	line-height: 1.3;
	margin: 0;
}

/* Mosaico cuadrado de «otros servicios». */
.cb-tile--square { aspect-ratio: 1 / 1; }
.cb-tile--square .cb-tile__bg { opacity: .55; }

.cb-tile--square::after {
	background: linear-gradient(180deg, rgba(54, 56, 69, .2) 0%, rgba(54, 56, 69, .9) 78%);
}

.cb-tile--square .cb-tile__body { padding: 20px; }

/* 10. CELDAS DE RETÍCULA CON LÍNEAS ======================================== */
.cb-cell {
	padding: clamp(28px, 4vw, 46px) clamp(22px, 3vw, 34px);
	transition: background var(--cb-t-mid);
}

.cb-cell:hover { background: var(--cb-bg-soft); }
.cb-cell--center { text-align: center; }
.cb-cell--sm { padding: clamp(28px, 4vw, 40px) clamp(22px, 3vw, 32px); }
.cb-cell--xs { padding: 38px 26px; }
.cb-cell--md { padding: 44px 32px; }

/*
 * Iconos de las ventajas.
 *
 * Estaban en una caja de 56×56 con object-fit: contain, y ahí el que manda es
 * el lado más largo del icono: uno apaisado se escala por el ancho y acaba
 * midiendo 40px de alto, mientras que uno vertical llega a 56. Todos caben en
 * la caja, pero a la vista tienen alturas distintas.
 *
 * Fijando la ALTURA y dejando el ancho libre, todos miden exactamente lo mismo
 * de alto y lo que varía es el ancho, que es lo que no se nota.
 */
/*
 * Aquí estaba el fallo: la regla base body.cb-site img lleva height: auto y es
 * (0,1,1), mientras que .cb-cell__icon es (0,1,0). Le ganaba, así que el icono
 * volvía a su tamaño natural —240px— y se salía de la celda. Con body.cb-site
 * delante son (0,2,1) contra (0,1,1) y manda esta.
 */
body.cb-site .cb-cell__icon,
body.cb-site img.cb-cell__icon {
	/*
	 * Altura idéntica en todos, ancho libre. Sin max-width a propósito: si se le
	 * pone, un icono muy apaisado se topa con el ancho de la celda, se encoge
	 * por el ancho y su ALTURA baja con él, que es justo lo que no queremos. El
	 * caso extremo lo recorta el hueco, que tiene overflow: hidden.
	 */
	height: clamp(56px, 36.690px + 1.379vw, 64px) !important;
	min-height: clamp(56px, 36.690px + 1.379vw, 64px) !important;
	max-height: clamp(56px, 36.690px + 1.379vw, 64px) !important;
	width: auto !important;
	max-width: none !important;
	flex: none;
	opacity: .9;
	display: block;
}

.cb-cell--center .cb-cell__icon {
	margin-left: auto;
	margin-right: auto;
}

/*
 * Hueco reservado para el icono.
 *
 * Si una ventaja se queda sin icono, su título sube y rompe la línea con las
 * demás. El hueco se reserva siempre, haya icono o no.
 */
.cb-cell--center .cb-cell__slot {
	display: flex;
	align-items: flex-end;
	justify-content: center;
	height: clamp(56px, 36.690px + 1.379vw, 64px);
	margin-bottom: 18px;
	/* Doble seguro: si el icono se escapa por cualquier vía, se recorta aquí en
	   lugar de salirse por encima del bloque y taparle el titular. */
	overflow: hidden;
}

.cb-cell--center .cb-cell__slot .cb-cell__icon {
	margin-bottom: 0;
}

/* El hueco es el que recorta si un icono muy apaisado se pasa de ancho. */
.cb-cell__slot {
	overflow: hidden;
}

.cb-cell--center .cb-cell__slot .cb-num {
	margin: 0;
	line-height: 1;
}

.cb-cell__num {
	font-size: var(--cb-fs-num);
	font-weight: 200;
	color: var(--cb-accent);
	margin-bottom: 16px;
}

.cb-cell__title {
	margin: 0 0 12px;
	font-size: var(--cb-fs-lg);
	font-weight: 600;
	line-height: 1.3;
}

.cb-cell--center .cb-cell__title {
	font-size: var(--cb-fs-quote);
	margin-bottom: 14px;
}

.cb-cell__text {
	margin: 0;
	font-size: var(--cb-fs-base);
	line-height: 1.75;
	color: var(--cb-text-62);
}

.cb-cell--center .cb-cell__text {
	color: var(--cb-text-66);
}

/* 11. BANNER COMPROMISO ==================================================== */
.cb-banner {
	position: relative;
	height: 360px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

.cb-banner__bg {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
}

.cb-banner__bg img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cb-banner__veil {
	position: absolute;
	inset: 0;
	background: rgba(54, 56, 69, .58);
}

.cb-banner__title,
body.cb-site h2.cb-banner__title {
	position: relative;
	margin: 0;
	font-size: clamp(48px, 7vw, 104px);
	font-weight: 500;
	letter-spacing: .05em;
	text-align: center;
	padding: 0 var(--cb-gutter, 24px);
	line-height: 1;
}

.cb-banner__title i {
	font-weight: 200;
	opacity: .8;
	font-style: normal;
}

.cb-banner__title--long {
	font-size: clamp(40px, 5.6vw, 84px);
	letter-spacing: .04em;
}

/* 12. CAJA DE PRESENTACIÓN ================================================= */
.cb-pitch {
	border: 1px solid var(--cb-line-30);
	padding: 64px var(--cb-gutter, 24px);
	text-align: center;
}

.cb-pitch__title {
	margin: 0 0 20px;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 600;
	line-height: 1.3;
}

.cb-pitch__text {
	margin: 0 auto;
	max-width: 820px;
	font-size: var(--cb-fs-lg);
	line-height: 1.75;
	color: var(--cb-text-70);
}

/* 13. CIFRAS =============================================================== */
.cb-figure {
	padding: 38px 30px;
}

.cb-figure__num {
	font-size: clamp(30px, 5vw, 52px);
	font-weight: 200;
	line-height: 1;
}

.cb-figure__label {
	font-size: var(--cb-fs-xs);
	letter-spacing: .16em;
	color: var(--cb-text-50);
	margin-top: 8px;
	text-transform: uppercase;
}

/* 14. TESTIMONIOS ========================================================== */
.cb-quote {
	margin: 0 0 26px;
	font-size: var(--cb-fs-quote);
	line-height: 1.7;
	color: var(--cb-text-85);
	min-height: 120px;
	font-weight: 300;
}

.cb-quote__author {
	font-size: var(--cb-fs-base);
	font-weight: 600;
}

.cb-quote__role {
	font-size: var(--cb-fs-base);
	color: var(--cb-text-55);
	margin-top: 4px;
}

.cb-quote__counter {
	margin-top: 20px;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-45);
}

/* Rejilla de testimonios (página de obras). */
.cb-testi-cell {
	padding: clamp(28px, 4vw, 40px) clamp(22px, 3vw, 32px);
	display: flex;
	flex-direction: column;
	gap: 18px;
	transition: background var(--cb-t-mid);
}

/* La firma se pega abajo: con citas de distinta longitud, si no, cada nombre
   queda a una altura distinta y la rejilla parece descuadrada. */
.cb-testi-cell > div:last-child {
	margin-top: auto;
}

.cb-testi-cell:hover { background: var(--cb-bg-soft); }

.cb-testi-cell p {
	margin: 0;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-74);
}

/*
 * Contenedores de Swiper dentro de una retícula.
 *
 * Un hijo de grid tiene min-width: auto, es decir, no puede encogerse por
 * debajo del ancho de su contenido. Swiper mide el contenedor y le pone a cada
 * diapositiva ese ancho en línea (width: 1400px), la columna crece para
 * caberlo, Swiper vuelve a medir… y la sección se sale de la pantalla
 * arrastrando las flechas fuera de la ventana. El min-width: 0 rompe ese
 * bucle: es obligatorio, no cosmético.
 */
.cb-testi__swiper,
.cb-obras__swiper,
.cb-gallery__swiper,
.cb-hero__swiper {
	width: 100%;
	max-width: 100%;
	min-width: 0;
	overflow: hidden;
}

.cb-split > *,
.cb-split--wide > *,
.cb-split--text > *,
.cb-split--nav > *,
.cb-grid > *,
.cb-lines > * {
	min-width: 0;
}

.cb-split,
.cb-split--wide,
.cb-split--text,
.cb-split--nav,
.cb-grid,
.cb-lines {
	min-width: 0;
}

/* Y que el propio carrusel no herede un ancho mayor que su columna. */
.cb-testi__swiper .swiper-wrapper,
.cb-obras__swiper .swiper-wrapper,
.cb-gallery__swiper .swiper-wrapper {
	max-width: 100%;
}

.cb-testi__swiper .swiper-slide {
	height: auto;
}

/* 15. OBRAS ================================================================ */
.cb-obra {
	text-align: left;
	padding: 0;
	background: var(--cb-bg);
	border: 1px solid var(--cb-line-20);
	color: #fff;
	cursor: pointer;
	display: block;
	width: 100%;
	transition: border-color var(--cb-t-mid);
}

body.cb-site .cb-obra:hover,
body.cb-site .cb-obra:focus-visible {
	border-color: var(--cb-accent);
	color: #fff;
}

/*
 * La foto de la ficha de obra. Dos fallos que se sumaban y por eso no se veía
 * ninguna imagen:
 *
 *  1. La marca es un <span>, que es de línea, y un elemento de línea ignora
 *     aspect-ratio, width y height. La caja no llegaba a existir.
 *  2. El selector del interior pedía «> div» y la plantilla pinta un <span>,
 *     así que el fondo tampoco se aplicaba.
 *
 * Con display:block y el selector correcto la foto aparece. Si una obra no
 * tiene imagen destacada se ve la caja en el gris oscuro, que es mejor que una
 * tarjeta descuadrada respecto a las demás.
 */
.cb-obra__img {
	display: block;
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--cb-bg-deep);
}

.cb-obra__img img,
.cb-obra__img > span,
.cb-obra__img > div {
	display: block;
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	background-size: cover;
	background-position: center;
	transition: transform var(--cb-t-slow);
}

/* Un punto de acercamiento al pasar: da a entender que la ficha se abre. */
body.cb-site .cb-obra:hover .cb-obra__img > span,
body.cb-site .cb-obra:hover .cb-obra__img img {
	transform: scale(1.04);
}

.cb-obra__body {
	padding: 22px 22px 24px;
	border-top: 1px solid var(--cb-line-20);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
}

.cb-obra__title {
	display: block;
	font-size: var(--cb-fs-lg);
	font-weight: 600;
	margin: 0;
}

.cb-obra__tipo {
	display: block;
	font-size: var(--cb-fs-base);
	color: rgba(255, 255, 255, .58);
	margin-top: 6px;
}

.cb-obra__meta {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 0;
	border-bottom: 1px solid var(--cb-line-14);
	font-size: var(--cb-fs-base);
}

.cb-obra__meta span:first-child { color: var(--cb-text-55); }
.cb-obra__meta span:last-child { text-align: right; }
.cb-obra__meta:last-child { border-bottom: none; }

/* Filtros de la lista. */
.cb-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 40px;
}

.cb-filters a,
.cb-filters button {
	border: 1px solid var(--cb-line-30);
	background: transparent;
	color: var(--cb-text-72);
	padding: 11px 20px;
	font-size: var(--cb-fs-md);
	cursor: pointer;
	font-family: inherit;
	transition: background var(--cb-t), border-color var(--cb-t), color var(--cb-t);
}

body.cb-site .cb-filters a:hover,
body.cb-site .cb-filters button:hover,
body.cb-site .cb-filters .is-active {
	background: var(--cb-accent);
	border-color: var(--cb-accent);
	color: #fff;
}

/* 16. CLIENTES ============================================================= */
.cb-clientes__title {
	margin: 0 0 44px;
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 600;
}

.cb-clientes__grid {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 1px;
	background: var(--cb-line);
	border: 1px solid var(--cb-line);
}

.cb-clientes__item {
	background: var(--cb-bg);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 30px 20px;
	min-height: 132px;
	transition: background var(--cb-t-mid);
}

.cb-clientes__item:hover { background: var(--cb-bg-soft); }

body.cb-site .cb-clientes__logo {
	max-width: 100%;
	max-height: 46px;
	height: auto;
	width: auto;
	object-fit: contain;
	filter: grayscale(1) brightness(2.2);
	opacity: .55;
	transition: opacity var(--cb-t), filter var(--cb-t);
}

.cb-clientes__item:hover .cb-clientes__logo {
	filter: none;
	opacity: 1;
}

.cb-clientes__meta {
	font-size: var(--cb-fs-xs);
	letter-spacing: .1em;
	color: var(--cb-text-45);
	text-align: center;
	text-transform: uppercase;
}

body.cb-site .cb-cliente-card__logo {
	max-height: 54px;
	width: auto;
	object-fit: contain;
	margin-bottom: 16px;
}

/* 17. FICHA DE SERVICIO ==================================================== */
.cb-ficha__label {
	font-size: var(--cb-fs-xs);
	letter-spacing: .18em;
	color: var(--cb-text-45);
	margin-bottom: 18px;
	text-transform: uppercase;
}

.cb-ficha__row {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	padding: 11px 0;
	border-bottom: 1px solid var(--cb-line-12);
	font-size: var(--cb-fs-base);
}

.cb-ficha__row span:first-child { color: var(--cb-text-50); }
.cb-ficha__row span:last-child { text-align: right; }
.cb-ficha__row:last-child { border-bottom: none; }

.cb-ficha__head {
	padding: 34px 34px 28px;
	border-bottom: 1px solid var(--cb-line-24);
}

.cb-ficha__actions {
	padding: 30px 34px;
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.cb-ficha__body {
	padding: clamp(26px, 4vw, 52px) clamp(24px, 4vw, 52px) clamp(26px, 4vw, 46px);
	border-right: 1px solid var(--cb-line-24);
}

.cb-ficha__col {
	display: flex;
	flex-direction: column;
}

/* Lista de filas con línea superior (perfiles, «qué buscamos»). */
.cb-rows > * {
	padding: 14px 0;
	border-top: 1px solid var(--cb-line);
	font-size: var(--cb-fs-base);
}

.cb-rows > *:last-child {
	border-bottom: 1px solid var(--cb-line);
}

/* Pasos numerados. */
.cb-steps {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.cb-steps > * {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 18px;
	align-items: start;
}

.cb-steps b {
	font-size: var(--cb-fs-lg);
	font-weight: 200;
	color: var(--cb-accent);
}

.cb-steps span {
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-70);
}

/* 18. GALERÍA ============================================================== */
.cb-gallery {
	border: 1px solid var(--cb-line-24);
	padding: 22px;
}

.cb-gallery__stage {
	aspect-ratio: 16 / 8;
	background-color: var(--cb-bg-deep);
	background-size: cover;
	background-position: center;
	position: relative;
	overflow: hidden;
}

.cb-gallery__stage img,
.cb-gallery__stage .swiper-slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cb-gallery__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 20px 6px 4px;
	flex-wrap: wrap;
}

.cb-gallery__meta {
	font-size: var(--cb-fs-md);
	color: var(--cb-text-55);
}

.cb-gallery__count {
	font-size: var(--cb-fs-sm);
	color: var(--cb-text-45);
}

.cb-gallery__nav {
	display: flex;
	align-items: center;
	gap: 14px;
}

/* Miniaturas. */
.cb-thumbs {
	display: flex;
	gap: 12px;
	padding: 14px 22px;
	border-bottom: 1px solid var(--cb-line-18);
	overflow-x: auto;
	/* Scroll horizontal dentro de un flex: hace falta min-width por el mismo
	   motivo que min-height en el vertical. */
	min-width: 0;
	flex: none;
	overscroll-behavior-x: contain;
	-webkit-overflow-scrolling: touch;
}

.cb-thumbs button {
	width: 96px;
	height: 64px;
	border: 1px solid var(--cb-line-24);
	padding: 0;
	background-size: cover;
	background-position: center;
	cursor: pointer;
	opacity: .55;
	flex: none;
	transition: opacity var(--cb-t), border-color var(--cb-t);
}

body.cb-site .cb-thumbs button:hover,
body.cb-site .cb-thumbs button.is-active {
	opacity: 1;
	border-color: var(--cb-accent);
}

/* 19. ACORDEÓN (FAQ) ======================================================= */
.cb-acc {
	border-top: 1px solid var(--cb-line-30);
}

.cb-acc__item {
	border-bottom: 1px solid var(--cb-line-18);
}

.cb-acc__head {
	width: 100%;
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: 30px;
	background: none;
	border: none;
	color: #fff;
	text-align: left;
	padding: 22px 0;
	cursor: pointer;
	font-size: var(--cb-fs-base);
	font-weight: 600;
	line-height: 1.35;
	font-family: inherit;
}

/*
 * Fondo transparente en TODOS los estados.
 *
 * Astra le pinta el color de marca al :focus de cualquier <button>, y al pulsar
 * una pregunta el foco se queda en ella: la pregunta abierta salía con el
 * fondo granate a todo lo ancho. Es el mismo mecanismo que deformaba las
 * flechas de los carruseles y pintaba la × del modal.
 */
body.cb-site .cb-acc__head,
body.cb-site .cb-acc__head:hover,
body.cb-site .cb-acc__head:focus,
body.cb-site .cb-acc__head:active,
body.cb-site .cb-acc__item.is-open .cb-acc__head {
	background: none !important;
	background-color: transparent !important;
	color: #fff !important;
	border: none !important;
	box-shadow: none !important;
	outline: none;
}

/* El foco por teclado sí se ve, pero con un filete, no con un bloque de color. */
body.cb-site .cb-acc__head:focus-visible {
	outline: 1px solid var(--cb-accent);
	outline-offset: -4px;
}

/* La marca es una línea de 34px que se pone granate al abrir. */
.cb-acc__icon {
	width: 34px;
	height: 1px;
	background: var(--cb-line-30);
	display: block;
	transition: background var(--cb-t);
}

.cb-acc__item.is-open .cb-acc__icon,
.cb-acc__head[aria-expanded="true"] .cb-acc__icon {
	background: var(--cb-accent);
}

.cb-acc__panel {
	display: none;
}

.cb-acc__item.is-open .cb-acc__panel {
	display: block;
}

.cb-acc__inner {
	margin: 0 0 26px;
	max-width: 900px;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-66);
}

.cb-acc__inner p {
	margin: 0 0 16px;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-66);
}

.cb-acc__inner p:last-child { margin-bottom: 0; }

/* 20. FORMULARIOS ==========================================================
   Campos con borde completo de 1px al 40 %, etiqueta en versalitas de 13px
   con letter-spacing .14em encima, y foco en granate. */

.cb-form {
	display: grid;
	gap: 26px;
}

.cb-form__head {
	display: flex;
	align-items: end;
	justify-content: space-between;
	gap: 40px;
	flex-wrap: wrap;
	margin-bottom: 46px;
}

.cb-form__head h2 {
	margin: 0;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 600;
}

.cb-form__head p {
	margin: 0;
	font-size: var(--cb-fs-base);
	color: var(--cb-text-60);
	max-width: 520px;
}

.cb-form__row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
	gap: 26px;
}

.cb-form__row--3 {
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.cb-form__row--wide {
	grid-template-columns: 1.4fr 1fr 1fr;
}

.cb-field {
	display: flex;
	flex-direction: column;
	gap: 9px;
	min-width: 0;
}

.cb-field > label,
.cb-field > span,
.cb-field__label {
	font-size: var(--cb-fs-sm);
	letter-spacing: .14em;
	color: var(--cb-text-60);
	text-transform: uppercase;
	font-weight: 300;
}

.cb-field input[type="search"],
.cb-field input[type="text"],
.cb-field input[type="email"],
.cb-field input[type="tel"],
.cb-field input[type="number"],
.cb-field input[type="url"],
.cb-field input[type="date"],
.cb-field input[type="password"],
.cb-field textarea,
.cb-field select,
.cb-form input[type="search"],
.cb-form input[type="text"],
.cb-form input[type="email"],
.cb-form input[type="tel"],
.cb-form input[type="number"],
.cb-form input[type="url"],
.cb-form input[type="date"],
.cb-form input[type="password"],
.cb-form textarea,
.cb-form select {
	background: transparent;
	border: 1px solid var(--cb-text-40);
	border-radius: 0;
	color: #fff;
	padding: 15px 16px;
	font-size: var(--cb-fs-base);
	line-height: 1.4;
	outline: none;
	width: 100%;
	min-width: 0;
	max-width: 100%;
	box-shadow: none;
	transition: border-color var(--cb-t);
}

.cb-field select,
.cb-form select {
	background-color: var(--cb-bg);
	appearance: none;
	background-image: linear-gradient(45deg, transparent 50%, rgba(255, 255, 255, .55) 50%),
		linear-gradient(135deg, rgba(255, 255, 255, .55) 50%, transparent 50%);
	background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
	background-size: 6px 6px, 6px 6px;
	background-repeat: no-repeat;
	padding-right: 40px;
}

.cb-field textarea,
.cb-form textarea {
	resize: vertical;
	line-height: 1.6;
}

.cb-field input:focus,
.cb-field textarea:focus,
.cb-field select:focus,
.cb-form input:focus,
.cb-form textarea:focus,
.cb-form select:focus {
	border-color: var(--cb-accent);
	box-shadow: none;
	outline: none;
}

.cb-field input[type="file"],
.cb-form input[type="file"] {
	background: transparent;
	border: 1px solid var(--cb-text-40);
	color: var(--cb-text-70);
	padding: 14px 16px;
	font-size: var(--cb-fs-base);
	outline: none;
	width: 100%;
	border-radius: 0;
}

.cb-field input.cb-error,
.cb-form input.cb-error,
.cb-form textarea.cb-error,
.cb-form select.cb-error {
	border-color: var(--cb-accent-soft);
}

/* Consentimiento. */
.cb-check {
	display: flex;
	align-items: center;
	gap: 12px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .1em;
	color: var(--cb-text-60);
	text-transform: uppercase;
	cursor: pointer;
}

.cb-check input[type="checkbox"] {
	width: 16px;
	height: 16px;
	accent-color: var(--cb-accent);
	flex: none;
	margin: 0;
}

.cb-check a,
.cb-check button {
	background: none;
	border: none;
	padding: 0;
	color: #fff;
	font-weight: 600;
	font-size: var(--cb-fs-sm);
	letter-spacing: .1em;
	text-decoration: underline;
	cursor: pointer;
	font-family: inherit;
}

/* Mensajes. */
.cb-form__msg {
	border: 1px solid var(--cb-accent);
	padding: 44px var(--cb-gutter, 24px);
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.cb-form__msg strong {
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 500;
}

.cb-form__msg p {
	margin: 0;
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-68);
}

.cb-form__msg--ko {
	border-color: var(--cb-accent-soft);
}

.cb-form__error {
	font-size: var(--cb-fs-sm);
	letter-spacing: .06em;
	color: var(--cb-accent-soft);
}

/* Honeypot: fuera de pantalla, nunca display:none. */
.cb-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}


/* Astra fija una altura a los controles de formulario (select sobre todo).
   Con padding vertical propio, el hueco interior se queda por debajo del
   cuerpo de letra y el texto aparece cortado por la mitad. La altura la
   calcula el contenido, siempre. */
body.cb-site .cb-form input,
body.cb-site .cb-form select,
body.cb-site .cb-form textarea,
body.cb-site .cb-field input,
body.cb-site .cb-field select,
body.cb-site .cb-field textarea,
body.cb-site .cb-doc input {
	height: auto !important;
	min-height: 0;
	max-height: none;
	line-height: 1.4;
	box-sizing: border-box;
}

body.cb-site .cb-form select,
body.cb-site .cb-field select {
	/* Alto real del control: 15px + 15px de padding + una línea de texto. */
	min-height: calc(1.4em + 32px);
}

body.cb-site .cb-form textarea,
body.cb-site .cb-field textarea {
	min-height: 150px;
}

/* Las opciones desplegadas las pinta el sistema, no la página: hay que
   darles fondo o en Windows salen blancas sobre blanco. */
body.cb-site .cb-form select option,
body.cb-site .cb-field select option {
	background: var(--cb-bg);
	color: #fff;
}

/* 21. MODALES ============================================================== */
.cb-modal {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: none;
	align-items: center;
	justify-content: center;
	padding: 40px;
}

.cb-modal.is-open { display: flex; }

.cb-modal__veil {
	position: absolute;
	inset: 0;
	background: rgba(20, 21, 27, .75);
	backdrop-filter: blur(6px);
}

/*
 * La caja del modal es hija de .cb-modal, que es flex para centrarla. Mismo
 * motivo que en .cb-legal: sin min-height 0 no puede encogerse y el
 * overflow-y no llega a activarse cuando el contenido es más alto que el 86vh.
 */
.cb-modal__box {
	position: relative;
	width: 100%;
	min-height: 0;
	max-width: 560px;
	background: var(--cb-bg);
	border: 1px solid var(--cb-line-24);
	padding: clamp(26px, 4vw, 52px) clamp(24px, 4vw, 48px);
	text-align: left;
	max-height: 86vh;
	overflow-y: auto;
}

.cb-modal__box--wide {
	max-width: 940px;
	max-height: 82vh;
	padding: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.cb-modal__box--obra {
	min-height: 0;
	max-width: 1080px;
	max-height: 86vh;
	padding: 0;
	overflow-y: auto;
}

/*
 * Cerrar. En el prototipo es una × suelta, sin fondo.
 *
 * Astra pinta el color de marca en el fondo de todo <button>, y aquí lo hacía
 * con más peso que nuestra regla: salía un cuadrado granate estrecho con la ×
 * dentro. De ahí los !important, y de ahí también el tamaño fijo: sin él, el
 * padding de Astra deformaba la caja igual que pasaba con las flechas
 * circulares de los carruseles.
 */
body.cb-site .cb-modal__close {
	position: absolute;
	top: 10px;
	right: 12px;
	z-index: 3;

	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px !important;
	height: 40px !important;
	padding: 0 !important;
	margin: 0;

	background: none !important;
	background-color: transparent !important;
	border: none !important;
	border-radius: 0 !important;
	box-shadow: none !important;

	color: var(--cb-text-60);
	font-size: 30px;
	font-weight: 200;
	line-height: 1;
	cursor: pointer;
	transition: color var(--cb-t);
}

body.cb-site .cb-modal__close:hover,
body.cb-site .cb-modal__close:focus {
	background: none !important;
	background-color: transparent !important;
	color: #fff;
	transform: none;
}

body.cb-site .cb-modal__close:focus-visible {
	outline: 1px solid var(--cb-line-30);
	outline-offset: -6px;
}

.cb-modal__title {
	margin: 0 0 14px;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 200;
}

.cb-modal__text {
	margin: 0 0 30px;
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-68);
}

/* Pestañas del modal legal. */
.cb-tabs {
	display: flex;
	border-bottom: 1px solid var(--cb-line-18);
	flex-wrap: wrap;
}

.cb-tabs button {
	flex: 1;
	background: transparent;
	border: none;
	border-right: 1px solid var(--cb-line-18);
	color: #fff;
	padding: 22px 14px;
	font-size: var(--cb-fs-md);
	cursor: pointer;
	transition: background var(--cb-t);
	font-family: inherit;
}

body.cb-site .cb-tabs button:hover,
body.cb-site .cb-tabs button.is-active {
	background: var(--cb-bg-soft);
}

/*
 * El panel de texto legal.
 *
 * Tenía overflow-y: auto y aun así no hacía scroll. La causa es que es un hijo
 * de un contenedor flex, y en flexbox el min-height por defecto de un hijo es
 * «auto»: el elemento no puede encogerse por debajo del alto de su contenido,
 * así que nunca llega a desbordar y overflow no entra en juego. El texto se
 * salía de la caja y quedaba cortado sin barra.
 *
 * min-height: 0 es lo que permite que se encoja y, con ello, que aparezca el
 * scroll. Es la línea que resuelve el 90 % de los «no me hace scroll» dentro de
 * un flex.
 */
.cb-legal {
	flex: 1 1 auto;
	min-height: 0;
	padding: 44px 48px;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
}

/* Las pestañas se quedan fijas arriba mientras el texto se desplaza. */
.cb-modal__box--wide .cb-tabs {
	flex: none;
}

.cb-legal h3 {
	margin: 0 0 22px;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 200;
}

.cb-legal p {
	margin: 0 0 18px;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-70);
}

/* Acceso a documentación. */
.cb-doc {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cb-doc input[type="password"] {
	background: transparent;
	border: 1px solid var(--cb-text-40);
	color: #fff;
	padding: 15px 16px;
	font-size: var(--cb-fs-base);
	outline: none;
	border-radius: 0;
	width: 100%;
}

.cb-doc input[type="password"]:focus {
	border-color: var(--cb-accent);
}

.cb-doc__error {
	font-size: var(--cb-fs-base);
	color: var(--cb-accent-soft);
}

.cb-doc__links {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

/*
 * Fila de documento. Ojo con el selector: escrito como «.cb-doc__links a»
 * alcanzaba también al botón ABRIR de dentro de cada fila —(0,1,1) le gana a
 * .cb-btn, que es (0,1,0)— y lo convertía en una barra granate a todo el ancho
 * con borde. Solo los hijos directos, y nunca un .cb-btn.
 */
.cb-doc__links > a:not(.cb-btn) {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	border: 1px solid rgba(255, 255, 255, .35);
	padding: 20px 22px;
	transition: background var(--cb-t);
}

body.cb-site .cb-doc__links > a:not(.cb-btn):hover {
	background: var(--cb-bg-soft);
	color: #fff;
}

/* Ficha de documento: título y nota a la izquierda, botón a la derecha. */
.cb-doc__card {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: clamp(18px, 3vw, 32px);
	border: 1px solid var(--cb-line-24);
	padding: clamp(20px, 3vw, 28px) clamp(20px, 3vw, 26px);
}

.cb-doc__card > div {
	min-width: 0;
}

.cb-doc__card .cb-h4 {
	font-size: clamp(18px, 2vw, 21px);
	font-weight: 600;
}

.cb-doc__card .cb-btn {
	flex: none;
	padding: 15px 26px;
}

@media (max-width: 700px) {
	.cb-doc__card {
		flex-direction: column;
		align-items: stretch;
	}

	.cb-doc__card .cb-btn {
		width: 100%;
	}
}

.cb-doc__links strong {
	display: block;
	font-size: var(--cb-fs-base);
	font-weight: 300;
	margin-bottom: 5px;
}

.cb-doc__links small {
	display: block;
	font-size: var(--cb-fs-base);
	color: var(--cb-text-55);
}

/* 22. FOOTER Y MENÚS DE ASTRA ==============================================
   Israel monta el header y el footer con el constructor de Astra: aquí solo
   se le da el aspecto del prototipo a lo que Astra pinta. */

body.cb-site .ast-primary-header-bar,
body.cb-site .site-header,
body.cb-site .ast-above-header,
body.cb-site .ast-below-header {
	background: rgba(54, 56, 69, .9) !important;
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--cb-line);
	box-shadow: none;
}

body.cb-site .main-header-menu,
body.cb-site .main-header-menu .menu-link,
body.cb-site.ast-header-break-point .main-header-menu .menu-link {
	background: transparent;
	color: #fff;
	/*
	 * En el prototipo los enlaces del menú van a 18px, peso 300 y en caja
	 * normal: «Servicios», no «SERVICIOS». Las versalitas y el espaciado extra
	 * los mete la tipografía del menú del personalizador de Astra, y aquí se
	 * anulan porque las mayúsculas son cosa de los dos botones, no del menú.
	 */
	font-size: var(--cb-fs-base) !important;
	font-weight: 300 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	line-height: 1.4 !important;
}

/*
 * El subrayado del menú. Ojo: esta regla es (0,4,1) y le ganaba a la del botón,
 * que es (0,3,1), así que le ponía border-bottom transparent a Documentación y
 * a Llamar y les dejaba el recuadro abierto por abajo. Se excluyen los dos.
 */
body.cb-site .main-header-menu > .menu-item:not(.cb-lock):not(.cb-call) > .menu-link {
	padding-bottom: 3px;
	border-bottom: 1px solid transparent;
	transition: border-color var(--cb-t);
}

/*
 * Astra estira los enlaces del menú a toda la altura de la barra para que el
 * hover cubra la franja entera. En un enlace normal no se nota, pero los dos
 * botones llevan borde, y ese borde salía del techo al suelo del header en vez
 * de dibujar una caja de su tamaño. De ahí el height auto.
 */
body.cb-site .main-header-menu > .cb-lock,
body.cb-site .main-header-menu > .cb-call {
	align-items: center;
	align-self: center;
}

body.cb-site .cb-lock > .menu-link,
body.cb-site .cb-call > .menu-link {
	height: auto !important;
	min-height: 0 !important;
	line-height: 1 !important;
	font-size: var(--cb-fs-sm) !important;
	font-weight: 500 !important;
	letter-spacing: .1em !important;
	text-transform: uppercase !important;
}

body.cb-site .main-header-menu > .current-menu-item:not(.cb-lock):not(.cb-call) > .menu-link,
body.cb-site .main-header-menu > .current_page_item:not(.cb-lock):not(.cb-call) > .menu-link,
body.cb-site .main-header-menu > .menu-item:not(.cb-lock):not(.cb-call) > .menu-link:hover {
	border-bottom-color: var(--cb-accent);
	color: #fff;
}

/*
 * El menú del prototipo separa los elementos con un gap de 24px.
 *
 * Ojo con el selector: ast-desktop y ast-header-break-point son clases del
 * propio <body>, no de un elemento de dentro. Escrito con espacio —
 * «body.cb-site .ast-desktop» — el selector no casa con nada y la regla no se
 * aplica nunca. Va concatenado.
 */
body.cb-site:not(.ast-header-break-point) .main-header-menu {
	display: flex;
	align-items: center;
	gap: 24px;
	flex-wrap: wrap;
}

body.cb-site:not(.ast-header-break-point) .main-header-menu > .menu-item > .menu-link {
	padding-left: 0;
	padding-right: 0;
}

/* El subrayado de la página activa no se le pone a los dos botones. */
body.cb-site .main-header-menu > .cb-lock.current-menu-item > .menu-link,
body.cb-site .main-header-menu > .cb-call.current-menu-item > .menu-link {
	border-color: rgba(255, 255, 255, .45);
}

body.cb-site .main-header-menu > .cb-call.current-menu-item > .menu-link {
	border-color: var(--cb-accent);
}

/* El candado de Documentación. */
body.cb-site .cb-lock > .menu-link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	border: 1px solid rgba(255, 255, 255, .45);
	padding: 12px 18px !important;
	transition: background var(--cb-t), border-color var(--cb-t);
}

body.cb-site .cb-lock > .menu-link::before {
	content: "";
	width: 13px;
	height: 13px;
	flex: none;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'><rect x='4' y='10' width='16' height='11' rx='1'/><path d='M8 10V7a4 4 0 0 1 8 0v3'/></svg>") center / contain no-repeat;
	mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'><rect x='4' y='10' width='16' height='11' rx='1'/><path d='M8 10V7a4 4 0 0 1 8 0v3'/></svg>") center / contain no-repeat;
}

/*
 * Hover de los dos botones.
 *
 * El color del texto lo lleva !important a propósito. Astra imprime el color de
 * hover del menú (el granate del personalizador) con selectores que le ganan a
 * los nuestros: uno usa #ast-desktop-header, que es un id, y otros añaden una
 * clase más. Resultado: texto granate sobre fondo granate, es decir invisible.
 * Aquí no hay forma de ganar por especificidad sin escribir un selector absurdo.
 */
body.cb-site .cb-lock > .menu-link:hover,
body.cb-site .cb-lock > .menu-link:focus,
body.cb-site .cb-lock:hover > .menu-link {
	background: var(--cb-accent) !important;
	border-color: var(--cb-accent) !important;
	color: #fff !important;
}

/*
 * El segundo botón del header: «Llamar», relleno de granate. En el prototipo
 * los dos van juntos a la derecha del menú, el de documentación con contorno y
 * este macizo. Se le pone la clase cb-call al elemento del menú.
 */
body.cb-site .cb-call > .menu-link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: var(--cb-accent);
	border: 1px solid var(--cb-accent);
	color: #fff;
	padding: 13px 20px !important;
	transition: transform var(--cb-t), background var(--cb-t);
}

body.cb-site .cb-call > .menu-link::before {
	content: "";
	width: 13px;
	height: 13px;
	flex: none;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'><path d='M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.5 2.8.6a2 2 0 0 1 1.7 2Z'/></svg>") center / contain no-repeat;
	mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'><path d='M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.5 2.8.6a2 2 0 0 1 1.7 2Z'/></svg>") center / contain no-repeat;
}

body.cb-site .cb-call > .menu-link:hover,
body.cb-site .cb-call > .menu-link:focus,
body.cb-site .cb-call:hover > .menu-link {
	transform: translateY(-2px);
	background: var(--cb-accent) !important;
	color: #fff !important;
}

/* El recuadro de los botones, cerrado por los cuatro costados. */
body.cb-site .main-header-menu > .cb-lock > .menu-link {
	border: 1px solid rgba(255, 255, 255, .45);
	color: #fff !important;
}

body.cb-site .main-header-menu > .cb-call > .menu-link {
	border: 1px solid var(--cb-accent);
	background: var(--cb-accent) !important;
	color: #fff !important;
}

body.cb-site .main-header-menu > .cb-lock,
body.cb-site .main-header-menu > .cb-call {
	display: flex;
	align-items: center;
}

/* En el menú desplegado del móvil los dos ocupan todo el ancho. */
body.cb-site.ast-header-break-point .cb-lock > .menu-link,
body.cb-site.ast-header-break-point .cb-call > .menu-link {
	justify-content: center;
	width: 100%;
	font-size: 15px;
	padding: 16px 18px;
	margin: 8px 0;
}

/* Menú desplegado en móvil. */
body.cb-site .ast-mobile-popup-drawer .ast-mobile-popup-inner,
body.cb-site .ast-mobile-header-wrap,
body.cb-site .main-navigation ul.ast-desktop-toggle-menu {
	background: var(--cb-bg) !important;
	border-top: 1px solid var(--cb-line);
}

body.cb-site.ast-header-break-point .main-header-menu .menu-item > .menu-link {
	font-size: var(--cb-fs-quote);
	padding: 16px 0;
	border-bottom: 1px solid var(--cb-line-14);
}

/* Footer. */
body.cb-site .site-footer,
body.cb-site .ast-footer-overlay,
body.cb-site .site-primary-footer-wrap,
body.cb-site .site-above-footer-wrap,
body.cb-site .site-below-footer-wrap {
	background: var(--cb-bg) !important;
	color: #fff;
}

body.cb-site .site-footer {
	border-top: 1px solid var(--cb-line);
}

body.cb-site .site-primary-footer-wrap {
	padding: 64px 0;
}

body.cb-site .site-below-footer-wrap {
	padding: 22px 0;
	border-top: 1px solid var(--cb-line);
	font-size: var(--cb-fs-sm);
	color: var(--cb-text-40);
}

body.cb-site .site-footer a {
	color: rgba(255, 255, 255, .8);
	font-size: var(--cb-fs-base);
}

body.cb-site .site-footer a:hover {
	color: var(--cb-accent);
}

body.cb-site .site-footer .widget-title,
body.cb-site .site-footer h2,
body.cb-site .site-footer h3 {
	font-size: var(--cb-fs-xs);
	letter-spacing: .18em;
	color: var(--cb-text-45);
	margin-bottom: 6px;
	font-weight: 300;
	text-transform: uppercase;
}

body.cb-site .site-footer p {
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-55);
}

body.cb-site .site-footer ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

/* Menú legal del pie. */
.cb-legal-menu {
	display: flex;
	align-items: center;
	gap: 14px;
	flex-wrap: wrap;
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-70);
}

.cb-legal-menu a,
.cb-legal-menu button {
	font-size: var(--cb-fs-md);
	color: var(--cb-text-70);
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	font-family: inherit;
}

.cb-legal-menu a:hover,
.cb-legal-menu button:hover {
	color: var(--cb-accent);
}

/* 23. ANIMACIONES Y REVEALS ================================================ */
@keyframes cb-bob {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(7px); }
}

@keyframes cb-marquee {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}

@keyframes cb-drift {
	0%, 100% { transform: translateY(0) rotate(0deg); }
	50% { transform: translateY(-16px) rotate(2deg); }
}

.cb-reveal {
	opacity: 0;
	transform: translateY(26px);
	transition: opacity .9s var(--cb-ease), transform .9s var(--cb-ease);
}

.cb-reveal.cb-in {
	opacity: 1;
	transform: none;
}

.cb-parallax { will-change: transform; }

.cb-marquee {
	overflow: hidden;
	white-space: nowrap;
}

.cb-marquee > * {
	display: inline-flex;
	animation: cb-marquee 28s linear infinite;
}

/* 24. UTILIDADES =========================================================== */
.cb-line {
	height: 1px;
	background: var(--cb-line);
	border: none;
	margin: 0;
}

.cb-mt-60 { margin-top: 60px; }
.cb-mt-100 { margin-top: 100px; }
.cb-mt-110 { margin-top: 110px; }
.cb-pt-0 { padding-top: 0 !important; }
.cb-gap-24 { gap: 24px; }
.cb-flex { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.cb-col { display: flex; flex-direction: column; gap: 10px; }
.cb-relative { position: relative; }
.cb-full { width: 100%; }

.cb-img--4x3 {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border: 1px solid rgba(255, 255, 255, .2);
}

.cb-map {
	position: relative;
	min-height: 420px;
}

.cb-map iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	filter: grayscale(1) invert(.92) hue-rotate(180deg) contrast(.9);
}

.cb-tel-big {
	font-size: var(--cb-fs-tel);
	font-weight: 400;
	line-height: 1.2;
}

.cb-tel-mid {
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 400;
}

.cb-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

/* Hexágono de la landing. */
.cb-hex {
	clip-path: polygon(0% 0%, 50% 26%, 100% 0%, 100% 68%, 50% 100%, 0% 68%);
}

.cb-hex--ghost {
	position: absolute;
	width: min(34vw, 480px);
	aspect-ratio: 1 / 1.02;
	border: 1px solid var(--cb-line-30);
	animation: cb-drift 13s ease-in-out infinite;
}

/* 25. RESPONSIVE ===========================================================
   El prototipo solo tiene dos cortes: 900px para apilar las columnas y
   768px para el cuerpo de texto. Se respeta tal cual. */

@media (max-width: 900px) {
	.cb-stack,
	[data-stack],
	.cb-split,
	.cb-split--wide,
	.cb-split--text,
	.cb-split--nav,
	.cb-hero__inner,
	.cb-form__row--wide {
		grid-template-columns: 1fr !important;
		gap: 34px !important;
	}

	.cb-stack > *,
	[data-stack] > *,
	.cb-split > *,
	.cb-split--wide > * {
		border-right: none !important;
		border-left: none !important;
	}

	.cb-ficha__body {
		border-right: none !important;
		border-bottom: 1px solid var(--cb-line-24);
	}
}

@media (max-width: 768px) {
	body.cb-site p {
		font-size: 17px;
		line-height: 1.75;
	}

	.cb-page-header { padding: 120px 0 40px; }
	.cb-page-header--servicio { padding: 110px 0 0; }

	.cb-section,
	.cb-section--80,
	.cb-section--90,
	.cb-section--110,
	.cb-section--both {
		padding-top: var(--cb-s70);
	}

	.cb-section--both { padding-bottom: var(--cb-s70); }

	.cb-pitch { padding: 40px 24px; }
	.cb-card { min-height: 440px; }
	.cb-card__body { padding: 34px 24px 18px; }
	.cb-card__foot span:first-child { padding: 18px 24px; }
	.cb-card__foot span:last-child { padding: 18px 20px; }
	.cb-banner { height: 260px; }
	.cb-modal { padding: 16px; }
	.cb-legal { padding: 28px 22px; }

	.cb-ficha__head,
	.cb-ficha__actions {
		padding: 26px 22px;
	}

	.cb-gallery { padding: 12px; }
	.cb-quote { font-size: 19px; min-height: 0; }
	.cb-tel-big { font-size: 28px; }
	.cb-figure { padding: 28px 22px; }
	.cb-thumbs { padding: 12px 16px; }
}

/* El muro de logotipos baja de 6 a 4 y a 2. */
@media (max-width: 1100px) {
	.cb-clientes__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

@media (max-width: 700px) {
	.cb-clientes__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.cb-claim__grid {
		grid-template-columns: 1fr;
	}

	.cb-claim__grid::before,
	.cb-claim__grid::after {
		display: none;
	}

	.cb-claim__text {
		grid-column: 1;
		padding: 26px 0;
	}

	/*
	 * El hero en móvil funciona como carrusel, no con el scroll: ocho pantallas
	 * de altura para pasar el encabezado no tienen sentido en un teléfono. El
	 * JS lo detecta y cambia de modo; aquí se le da la caja que necesita.
	 */
	.cb-hero {
		height: auto;
	}

	.cb-hero__sticky {
		position: relative;
		height: auto;
		min-height: 0;
		display: block;
	}

	.cb-hero__inner {
		height: auto;
		padding: 100px var(--cb-gutter, 24px) 30px;
		gap: 26px !important;
	}

	/*
	 * Las ocho diapositivas están apiladas en la misma celda. En modo scroll da
	 * igual porque todas caben, pero aquí el bloque debe medir lo que la más
	 * alta o el texto largo se sale por debajo de la imagen.
	 */
	.cb-hero__stack {
		align-items: start;
	}

	.cb-hero__slide {
		transition: opacity .45s ease;
	}

	.cb-hero__media {
		height: clamp(260px, 42vh, 400px);
		--cb-hero-corte: 7%;
	}

	.cb-hero__layer {
		transition: opacity .45s ease;
	}

	/* El paginador, dentro del flujo y no flotando sobre la imagen. */
	.cb-hero__pager {
		position: static;
		transform: none;
		width: auto;
		margin: 26px var(--cb-gutter, 24px) 0;
		gap: 8px;
	}

	.cb-hero__bullet em {
		display: none;
	}

	.cb-hero__bar {
		height: 3px;
	}

	/* La barra de la diapositiva activa se rellena entera: aquí no hay
	   progreso de scroll que representar. */
	.cb-hero__bullet.is-active .cb-hero__bar i {
		width: 100% !important;
	}

	.cb-scrollhint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.cb-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.cb-scrollhint svg,
	.cb-marquee > *,
	.cb-hex--ghost {
		animation: none;
	}

	/* Sin movimiento, el hero pasa también a carrusel: el JS hace lo mismo. */
	.cb-hero { height: auto; }

	.cb-hero__sticky {
		position: relative;
		height: auto;
		min-height: 0;
		display: block;
	}

	.cb-hero__inner {
		height: auto;
	}

	.cb-hero__slide,
	.cb-hero__layer {
		transition: none;
	}
}

/* Impresión de la ficha de servicio. */

/*
 * Con un modal abierto se bloquea el scroll de la página, pero NO el de lo que
 * hay dentro del modal: por eso el bloqueo va en el body y cada panel tiene su
 * propio overflow. Lenis, que es quien maneja el desplazamiento suave, también
 * se para: si no, sigue moviendo la página por debajo del modal.
 */
body.cb-modal-open {
	overflow: hidden;
}

/* Lo de dentro del modal sí se desplaza, y su scroll no arrastra a la página. */
body.cb-modal-open .cb-modal,
body.cb-modal-open .cb-lightbox {
	overscroll-behavior: contain;
}

.cb-modal--obra .cb-modal__veil {
	background: rgba(20, 21, 27, .78);
}

.cb-obra-modal__stage {
	position: relative;
	aspect-ratio: 16 / 7;
	background-color: var(--cb-bg-deep);
}

.cb-obra-modal__foto {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	transition: background-image .3s;
}

.cb-obra-modal__bar {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 18px 22px;
	background: linear-gradient(180deg, rgba(54, 56, 69, 0) 0%, rgba(54, 56, 69, .9) 100%);
}

.cb-obra-modal__count {
	font-size: var(--cb-fs-base);
	color: var(--cb-text-75);
}

.cb-obra-modal__bar .cb-round {
	background: rgba(54, 56, 69, .5);
	border-color: rgba(255, 255, 255, .45);
}

.cb-obra-modal__body {
	display: grid;
	grid-template-columns: 1.5fr 1fr;
	gap: clamp(28px, 4vw, 48px);
	padding: clamp(26px, 4vw, 40px) clamp(22px, 4vw, 44px) clamp(28px, 4vw, 46px);
}

.cb-obra-modal__title,
body.cb-site h3.cb-obra-modal__title {
	margin: 0 0 8px;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 500;
	line-height: 1.2;
}

.cb-obra-modal__tipo {
	font-size: var(--cb-fs-base);
	color: var(--cb-text-60);
	margin-bottom: 26px;
}

.cb-obra-modal__cita {
	margin: 30px 0 0;
	padding: 22px 24px;
	border-left: 1px solid var(--cb-accent);
	background: rgba(255, 255, 255, .03);
}

.cb-obra-modal__cita p {
	margin: 0 0 10px;
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-82);
}

.cb-obra-modal__cita footer {
	font-size: var(--cb-fs-md);
	color: var(--cb-text-55);
}

@media (max-width: 900px) {
	.cb-obra-modal__body {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   27. FORMULARIOS DEL PLUGIN (.cbf)
   El plugin trae su propia hoja, pero esa se carga antes y la caché del
   hosting la deja atrás con facilidad. El aspecto definitivo del formulario
   se define AQUÍ, en la última hoja del sitio, con los valores del prototipo:
   caja completa de 1px al 40 %, etiqueta en versalitas de 13px con
   letter-spacing .14em encima, foco en granate y botón a todo el ancho.
   ========================================================================== */

body.cb-site .cbf {
	font-family: var(--cb-font);
	color: #fff;
}

/* Retícula de seis columnas: full = 6, half = 3, third = 2. */
body.cb-site .cbf__fields {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 26px;
}

body.cb-site .cbf__field {
	display: flex;
	flex-direction: column;
	gap: 9px;
	min-width: 0;
	grid-column: span 6;
}

body.cb-site .cbf__field--full { grid-column: span 6; }
body.cb-site .cbf__field--half { grid-column: span 3; }
body.cb-site .cbf__field--third { grid-column: span 2; }

body.cb-site .cbf__label {
	font-size: var(--cb-fs-sm);
	font-weight: 300;
	letter-spacing: .14em;
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--cb-text-60);
	margin: 0;
}

body.cb-site .cbf__req {
	color: var(--cb-accent);
}

/* ---------------------------------------------------------- Controles */

body.cb-site .cbf input[type="search"],
body.cb-site .cbf input[type="text"],
body.cb-site .cbf input[type="email"],
body.cb-site .cbf input[type="tel"],
body.cb-site .cbf input[type="number"],
body.cb-site .cbf input[type="url"],
body.cb-site .cbf input[type="date"],
body.cb-site .cbf select,
body.cb-site .cbf textarea {
	/*
	 * La altura la decide el contenido. Astra y su addon fijan una altura a
	 * los controles de formulario y, con padding vertical propio, el hueco
	 * interior se queda por debajo del cuerpo de letra: el valor elegido de un
	 * select sale cortado por la mitad. De ahí el !important, que aquí no es
	 * pereza sino la única forma de ganar a una regla que llega después.
	 */
	height: auto !important;
	min-height: 0;
	max-height: none;
	box-sizing: border-box !important;

	width: 100%;
	min-width: 0;
	max-width: 100%;
	margin: 0;
	padding: 15px 16px;

	font-family: inherit;
	font-size: var(--cb-fs-base);
	font-weight: 300;
	line-height: 1.4;
	color: #fff;

	background: transparent;
	border: 1px solid var(--cb-text-40);
	border-radius: 0 !important;
	box-shadow: none !important;
	outline: none;
	appearance: none;
	-webkit-appearance: none;
	transition: border-color var(--cb-t);
}

body.cb-site .cbf input:focus,
body.cb-site .cbf select:focus,
body.cb-site .cbf textarea:focus {
	border-color: var(--cb-accent);
	box-shadow: none !important;
	outline: none;
}

body.cb-site .cbf input::placeholder,
body.cb-site .cbf textarea::placeholder {
	color: var(--cb-text-30);
	opacity: 1;
}

body.cb-site .cbf textarea {
	min-height: 150px;
	line-height: 1.6;
	resize: vertical;
}

/* Select: flecha propia y hueco suficiente para una línea completa. */
body.cb-site .cbf select {
	/* 15 + 15 de padding + una línea de texto: nunca corta el valor. */
	min-height: calc(1.4em + 32px);
	padding-right: 44px;
	cursor: pointer;

	background-color: var(--cb-bg);
	background-image:
		linear-gradient(45deg, transparent 50%, rgba(255, 255, 255, .6) 50%),
		linear-gradient(135deg, rgba(255, 255, 255, .6) 50%, transparent 50%);
	background-position: calc(100% - 22px) calc(50% + 1px), calc(100% - 16px) calc(50% + 1px);
	background-size: 7px 7px, 7px 7px;
	background-repeat: no-repeat;

	/* Sin esto, Firefox y Windows recortan la línea de texto del valor. */
	text-overflow: ellipsis;
	white-space: nowrap;
	overflow: hidden;
}

/*
 * El desplegable lo pinta el sistema operativo, no la página. Sin fondo y
 * color explícitos sale blanco sobre blanco en Windows y negro sobre negro en
 * algunos Linux.
 */
body.cb-site .cbf select option,
body.cb-site .cbf select optgroup {
	background: var(--cb-bg);
	color: #fff;
	font-size: var(--cb-fs-md);
	padding: 6px 10px;
}

body.cb-site .cbf input[type="file"] {
	width: 100%;
	padding: 14px 16px;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-70);
	background: transparent;
	border: 1px solid var(--cb-text-40);
	border-radius: 0;
	height: auto !important;
}

body.cb-site .cbf input[type="file"]::file-selector-button {
	margin-right: 14px;
	padding: 9px 18px;
	font-family: inherit;
	font-size: 14px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: #fff;
	background: var(--cb-bg-soft);
	border: 1px solid var(--cb-line-30);
	border-radius: 0;
	cursor: pointer;
	transition: background var(--cb-t);
}

body.cb-site .cbf input[type="file"]::file-selector-button:hover {
	background: var(--cb-accent);
	border-color: var(--cb-accent);
}

/* ------------------------------------------------------ Consentimiento */

body.cb-site .cbf__consent {
	display: flex;
	align-items: center;
	gap: 12px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .1em;
	line-height: 1.5;
	text-transform: uppercase;
	color: var(--cb-text-60);
	cursor: pointer;
}

body.cb-site .cbf__consent input[type="checkbox"] {
	width: 16px !important;
	height: 16px !important;
	min-width: 16px;
	margin: 0;
	padding: 0;
	flex: none;
	accent-color: var(--cb-accent);
	appearance: auto;
	-webkit-appearance: checkbox;
	border-radius: 0;
}

body.cb-site .cbf__consent a,
body.cb-site .cbf__consent button {
	color: #fff;
	font-weight: 600;
	font-size: var(--cb-fs-sm);
	letter-spacing: .1em;
	text-decoration: underline;
	text-underline-offset: 3px;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	font-family: inherit;
}

/* Opciones sueltas (radios y casillas múltiples). */
body.cb-site .cbf__options {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 24px;
	padding-top: 4px;
}

body.cb-site .cbf__option {
	display: flex;
	align-items: center;
	gap: 9px;
	font-size: var(--cb-fs-base);
	color: var(--cb-text-72);
	cursor: pointer;
}

body.cb-site .cbf__option input {
	width: 16px !important;
	height: 16px !important;
	margin: 0;
	flex: none;
	accent-color: var(--cb-accent);
}

/* ------------------------------------------------------------- Errores */

body.cb-site .cbf__error {
	display: block;
	font-size: var(--cb-fs-sm);
	letter-spacing: .04em;
	color: var(--cb-accent-soft);
	min-height: 0;
}

body.cb-site .cbf__field--error input,
body.cb-site .cbf__field--error select,
body.cb-site .cbf__field--error textarea {
	border-color: var(--cb-accent-soft);
}

/* -------------------------------------------------------------- Envío */

body.cb-site .cbf__actions {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin-top: 8px;
}

body.cb-site .cbf__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	width: 100%;
	padding: 19px 34px !important;
	height: auto !important;

	font-family: inherit;
	font-size: var(--cb-fs-md);
	font-weight: 400;
	letter-spacing: .18em;
	line-height: 1;
	text-transform: uppercase;
	color: #fff;

	background: var(--cb-accent) !important;
	border: none;
	border-radius: 0 !important;
	box-shadow: none !important;
	cursor: pointer;
	transition: opacity var(--cb-t);
}

body.cb-site .cbf__submit:hover,
body.cb-site .cbf__submit:focus {
	opacity: .86;
	background: var(--cb-accent) !important;
	color: #fff;
	transform: none;
}

body.cb-site .cbf__submit:disabled {
	opacity: .55;
	cursor: progress;
}

body.cb-site .cbf__arrow {
	display: block;
	flex: none;
	max-width: none;
	height: auto;
	overflow: visible;
	transition: transform var(--cb-t);
}

body.cb-site .cbf__arrow path {
	fill: none;
	stroke: currentColor;
	vector-effect: non-scaling-stroke;
}

body.cb-site .cbf__submit:hover .cbf__arrow {
	transform: translateX(4px);
}

body.cb-site .cbf__status {
	margin: 0;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-55);
}

/* Mensajes de resultado: caja con borde granate, como el prototipo. */
body.cb-site .cbf__msg {
	margin: 0 0 26px;
	padding: 44px var(--cb-gutter, 24px);
	border: 1px solid var(--cb-accent);
	border-left-width: 1px;
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-68);
	background: none;
}

body.cb-site .cbf__msg--ko {
	border-color: var(--cb-accent-soft);
}

/* Honeypot: fuera de pantalla, nunca display:none. */
body.cb-site .cbf-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Cabecera propia del plugin: la del tema ya pinta el titular. */
body.cb-site .cbf__head {
	margin-bottom: 34px;
}

body.cb-site .cbf__title {
	margin: 0 0 14px;
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 600;
	line-height: 1.3;
}

body.cb-site .cbf__text {
	margin: 0;
	max-width: 520px;
	font-size: var(--cb-fs-base);
	line-height: 1.7;
	color: var(--cb-text-60);
}

@media (max-width: 900px) {
	body.cb-site .cbf__fields {
		grid-template-columns: 1fr;
		gap: 22px;
	}

	body.cb-site .cbf__field,
	body.cb-site .cbf__field--full,
	body.cb-site .cbf__field--half,
	body.cb-site .cbf__field--third {
		grid-column: 1;
	}
}

/* ==========================================================================
   28. DATOS DE CONTACTO Y PALABRAS LARGAS
   Un email o una URL no tienen dónde partirse: en una columna estrecha se
   salen de su celda por mucho que la celda tenga overflow. Se le dice al
   navegador que puede partir dentro de la palabra cuando no hay otra opción.
   ========================================================================== */

body.cb-site {
	overflow-wrap: break-word;
}

.cb-dato {
	display: block;
	margin: 0;
	font-size: clamp(18px, 1.6vw, 22px);
	font-weight: 500;
	line-height: 1.4;
	color: #fff;
	/* anywhere permite partir la palabra y además deja que la celda se
	   estreche; break-word por sí solo no reduce el ancho mínimo. */
	overflow-wrap: anywhere;
	word-break: break-word;
	hyphens: none;
}

a.cb-dato:hover {
	color: var(--cb-accent);
}

.cb-cell--dato {
	min-width: 0;
}

/* Lo mismo donde puede caer un dato largo: fichas, tablas del modal, footer. */
.cb-ficha__row span,
.cb-obra__meta span,
.cb-clientes__meta,
.cb-doc__links strong,
.cb-doc__links small,
body.cb-site .site-footer a,
body.cb-site .cbf__label {
	overflow-wrap: anywhere;
	min-width: 0;
}

/* El email en pantallas estrechas baja de cuerpo antes que partirse. */
@media (max-width: 1200px) {
	.cb-dato {
		font-size: var(--cb-fs-base);
	}
}

/* ==========================================================================
   29. ESCALA GRANDE (a partir de 1400px)
   El contenedor llega hasta 1980px y los encabezados crecen con él. Todo lo
   que hay aquí solo entra en juego por encima de 1400, así que la web en
   portátil, tableta y móvil se ve exactamente igual que antes.
   ========================================================================== */

@media (min-width: 1400px) {

	:root {
		/* Más aire en los costados cuando hay sitio. */
		--cb-gutter: clamp(40px, 1.143px + 2.759vw, 56px);   /* 40 → 56 */
		--cb-measure: clamp(820px, 530.345px + 20.690vw, 940px);
	}

	/* Titulares ------------------------------------------------------- */
	.cb-h1,
	body.cb-site h1.cb-h1 {
		font-size: clamp(64px, 39.862px + 1.724vw, 74px);
	}

	.cb-h2,
	body.cb-site h2.cb-h2 {
		font-size: clamp(52px, 32.690px + 1.379vw, 60px);
	}

	.cb-h3,
	body.cb-site h3.cb-h3,
	.cb-text h2,
	.cb-pitch__title,
	.cb-modal__title,
	.cb-legal h3,
	.cb-form__head h2,
	body.cb-site .cbf__title,
	.cb-obra-modal__title,
	body.cb-site h3.cb-obra-modal__title {
		font-size: clamp(32px, 17.517px + 1.034vw, 38px);
	}

	.cb-h4,
	body.cb-site h4.cb-h4,
	.cb-num,
	.cb-card__num,
	.cb-card__title,
	.cb-clientes__title,
	.cb-tel-mid,
	.cb-form__msg strong {
		font-size: clamp(26px, 16.345px + 0.690vw, 30px);
	}

	/* Cabecera de página y banda ---------------------------------------- */
	.cb-page-header__title,
	body.cb-site h1.cb-page-header__title {
		font-size: clamp(130px, -0.345px + 9.310vw, 184px);
	}

	.cb-page-header__title--mid {
		font-size: clamp(116px, 3.586px + 8.046vw, 163px);
	}

	.cb-page-header__title--long {
		font-size: clamp(98px, 3.034px + 6.786vw, 137px);
	}

	.cb-page-header--servicio .cb-page-header__title {
		font-size: clamp(64px, 39.862px + 1.724vw, 74px);
	}

	.cb-banner__title,
	body.cb-site h2.cb-banner__title {
		font-size: clamp(104px, 7.448px + 6.897vw, 144px);
	}

	.cb-banner__title--long {
		font-size: clamp(84px, 6.207px + 5.517vw, 116px);
	}

	.cb-figure__num {
		font-size: clamp(52px, 27.862px + 1.724vw, 62px);
	}

	/* Cabecera más alta: el H1 gigante necesita más aire. */
	.cb-page-header {
		padding: clamp(170px, 96.552px + 5.172vw, 200px) 0 clamp(60px, 26.897px + 2.362vw, 74px);
	}

	/* Medidas de lectura ------------------------------------------------ */
	.cb-measure,
	.cb-pitch__text {
		max-width: var(--cb-measure);
	}

	.cb-claim__grid {
		grid-template-columns: 1fr minmax(0, clamp(860px, 522.759px + 24.138vw, 1000px)) 1fr;
	}

	.cb-hero__text {
		max-width: clamp(620px, 378.621px + 17.241vw, 720px);
	}

	.cb-acc__inner {
		max-width: clamp(900px, 561.379px + 24.138vw, 1040px);
	}

	.cb-testi__swiper .cb-quote {
		max-width: clamp(1100px, 617.241px + 34.483vw, 1300px);
	}

	.cb-form__head p,
	body.cb-site .cbf__text {
		max-width: clamp(520px, 326.897px + 13.793vw, 600px);
	}

	/* Tarjetas y cajas -------------------------------------------------- */
	.cb-card {
		min-height: clamp(520px, 375.172px + 10.345vw, 580px);
	}

	.cb-modal__box {
		max-width: clamp(560px, 366.897px + 13.793vw, 640px);
	}

	.cb-modal__box--wide {
		max-width: clamp(940px, 601.379px + 24.138vw, 1080px);
	}

	.cb-modal__box--obra {
		max-width: clamp(1080px, 693.793px + 27.586vw, 1240px);
	}

	body.cb-site .cb-clientes__logo {
		max-height: clamp(46px, 26.690px + 1.379vw, 54px);
	}
}

/* ==========================================================================
   30. NÚMERO DE COLUMNAS EN PANTALLAS ANCHAS
   Al pasar el contenedor de 1400 a 1980px, las retículas de auto-fit dejan de
   ser una decisión de diseño y se convierten en una división: el mosaico de
   servicios pasaba de 5 a 7 columnas y los testimonios de 3 a 5, con las
   tarjetas cada vez más pequeñas y la última fila siempre a medias. Aquí el
   número de columnas se fija a propósito, y se eligen los divisores que llenan
   las filas: 12 servicios en 6 columnas, 6 testimonios en 3.
   ========================================================================== */

/* Mosaico de servicios: 12 fichas. */
/*
 * Mosaico de servicios: cuatro por fila como máximo.
 *
 * Antes subía a seis a partir de 1500px. Los 12 servicios son divisibles por 1,
 * 2, 3 y 4, así que cualquiera de esos repartos deja las filas completas y se
 * puede escalonar con tranquilidad.
 */
.cb-grid--servicios {
	display: grid;
	gap: 24px;
	grid-template-columns: 1fr;
}

@media (min-width: 520px) {
	.cb-grid--servicios {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 900px) {
	.cb-grid--servicios {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1200px) {
	.cb-grid--servicios {
		grid-template-columns: repeat(4, 1fr);
	}
}

/*
 * Y el alto.
 *
 * La ficha es 1/1.12, o sea más alta que ancha. Con cinco columnas a 1400 eso
 * daba 273px, que es lo que pide el diseño. Con cuatro columnas a 1980 la celda
 * mide 449px y la proporción la llevaría a 503px de alto: una torre. A partir de
 * 1200 se suelta la proporción y se fija un alto razonable, que es lo que
 * mantiene la ficha con la misma pinta en todas las pantallas.
 */
@media (min-width: 1200px) {
	.cb-grid--servicios .cb-tile {
		aspect-ratio: auto;
		height: clamp(300px, 224.138px + 5.172vw, 360px);
	}
}

/*
 * Obras: cuatro por fila como máximo, igual que los servicios. El número de
 * obras es variable, así que aquí no hay un reparto que llene siempre las filas;
 * lo que se evita es que a 1980 salgan seis tarjetas diminutas.
 */
@media (min-width: 1200px) {
	.cb-grid--auto-275 {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* Testimonios en rejilla: tres columnas fijas, que es lo que llena las filas
   con seis citas. */
@media (min-width: 1100px) {
	.cb-grid--auto-340 {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* Servicios destacados de la home: cuatro, siempre cuatro. */
@media (min-width: 1100px) {
	.cb-grid--auto.cb-grid--lines {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* Muro de logotipos y vías de contacto: los divisores naturales. */
@media (min-width: 1500px) {
	.cb-clientes__grid {
		grid-template-columns: repeat(8, 1fr);
	}
}

/* Caja de acceso a documentación (área comercial). */
.cb-doc-cta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
	padding: clamp(30px, 4vw, 44px) clamp(24px, 3vw, 40px);
}

.cb-doc-cta .cb-btn {
	flex: none;
}

/* ==========================================================================
   31. COLUMNAS DE TEXTO
   Dos o tres párrafos en paralelo. Con la retícula de auto-fit se pegaban al
   titular y entre sí: el gap horizontal servía, pero no había respiración
   vertical ni separación con lo que viene detrás.
   ========================================================================== */

.cb-bienvenida__titulo {
	margin-bottom: clamp(26px, 3vw, 40px);
}

.cb-cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: clamp(28px, 3.4vw, 56px);
	align-items: start;
}

/* Cada columna respira por dentro y no se pega a la línea de la sección. */
.cb-cols > * {
	min-width: 0;
	padding-bottom: clamp(8px, 1vw, 16px);
}

.cb-cols p {
	margin: 0 0 22px;
}

.cb-cols > * > p:last-child {
	margin-bottom: 0;
}

/* Con dos párrafos, dos columnas: no más, aunque haya sitio a 1980. */
@media (min-width: 1100px) {
	.cb-cols {
		grid-template-columns: repeat(2, 1fr);
	}

	.cb-cols:has(> :nth-child(3)) {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* --------------------------------------------------------------------------
   Texto corrido a varias columnas.
   Para cuando los párrafos son un solo bloque de prosa y no piezas separadas:
   ahí no vale una retícula, porque cada párrafo iría a una celda y quedarían
   de alturas distintas. Con columns el texto fluye y se reparte solo.
   -------------------------------------------------------------------------- */
.cb-prose {
	/*
	 * Se declara el ANCHO de columna, no el número.
	 *
	 * Con `columns: 2` y una consulta de medios el número lo decide el ancho de
	 * la VENTANA, no el del contenedor: el mismo bloque metido en una columna
	 * estrecha —la ficha de un servicio, por ejemplo— se partía en dos columnas
	 * de doscientos píxeles. Con un ancho mínimo de 420px y un máximo de tres,
	 * el navegador calcula cuántas caben de verdad ahí dentro: una en una
	 * columna estrecha y dos en cuanto hay sitio. Dos es el máximo: con tres,
	 * a 1980px cada columna se queda en 590px y el ojo pierde el renglón al
	 * volver del final de una línea al principio de la siguiente.
	 */
	columns: 420px 2;   /* dos como máximo */
	column-gap: clamp(32px, 3.4vw, 64px);
	max-width: 100%;
}

.cb-prose p {
	margin: 0 0 22px;
	/* Un párrafo no se parte entre dos columnas: se lee fatal. */
	break-inside: avoid;
	-webkit-column-break-inside: avoid;
}

.cb-prose p:last-child {
	margin-bottom: 0;
}

/* Con poco texto, una sola columna aunque haya sitio: dos columnas de tres
   líneas cada una quedan peor que un párrafo entero. */
.cb-prose--corto {
	columns: 1 !important;
	max-width: var(--cb-measure);
}

/* Las celdas de las vías de contacto también pedían aire por debajo. */
.cb-cell--md .cb-dato {
	margin-top: 4px;
}

/* ==========================================================================
   32. AIRE ENTRE SECCIONES
   Las secciones del proyecto solo llevan padding arriba: la siguiente aporta
   el suyo y así el ritmo lo marca una sola regla. El problema aparece cuando
   detrás viene una banda o un banner, que traen su propia línea de 1px: el
   texto se quedaba pegado a esa línea. Aquí se le da el aire que falta.
   ========================================================================== */

/*
 * Y aquí metí la pata: el selector era «cualquier elemento seguido de una
 * banda», y una banda seguida de otra también encaja. Los servicios destacados
 * de la home son un section.cb-band--both con línea arriba y abajo, y el
 * banner COMPROMISO va justo detrás: la regla le metía 74px de padding DENTRO,
 * o sea entre el pie de las tarjetas y su propia línea inferior.
 *
 * El aire solo lo necesita un bloque que NO tenga borde propio. Los que sí lo
 * tienen —bandas, banners, hero y la banda de claim— ya cierran con su línea y
 * el padding se lo dan sus celdas.
 */
#cb-main > *:not(.cb-band):not(.cb-band--both):not(.cb-banner):not(.cb-hero):not(.cb-claim):has(+ .cb-band),
#cb-main > *:not(.cb-band):not(.cb-band--both):not(.cb-banner):not(.cb-hero):not(.cb-claim):has(+ .cb-band--both),
#cb-main > *:not(.cb-band):not(.cb-band--both):not(.cb-banner):not(.cb-hero):not(.cb-claim):has(+ .cb-banner),
#cb-main > *:not(.cb-band):not(.cb-band--both):not(.cb-banner):not(.cb-hero):not(.cb-claim):has(+ .cb-claim) {
	padding-bottom: clamp(60px, 26.897px + 2.362vw, 74px);
}

/* Y la última sección antes del pie, que no tiene nada detrás que la separe. */
#cb-main > *:last-child:not(.cb-banner):not(.cb-band):not(.cb-band--both):not(.cb-hero):not(.cb-claim) {
	padding-bottom: clamp(80px, 46.897px + 2.362vw, 94px);
}

/* Un bloque de texto pegado al borde inferior de su caja tampoco. */
.cb-section > .cb-text:last-child,
.cb-wrap > .cb-text:last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   33. MÓVIL Y TABLETA: QUE NADA SE PEGUE AL BORDE
   Casos que se escapaban del .cb-wrap y llegaban al filo de la pantalla.
   ========================================================================== */

/*
 * El titular de la cabecera.
 *
 * Aquí metí la pata en la tanda anterior: le puse el gutter al titular y se lo
 * quité al .cb-wrap que lo envuelve, y con eso las migas —que van en el mismo
 * wrap— se quedaron pegadas al borde. El padding lo pone el wrap, como en todo
 * el sitio, y el titular no lleva ninguno.
 */
.cb-page-header__title,
body.cb-site h1.cb-page-header__title {
	padding-left: 0;
	padding-right: 0;
}

/* La rejilla de logotipos y las celdas con línea: en móvil el borde exterior
   quedaba fuera de la pantalla. */
@media (max-width: 700px) {
	.cb-clientes__grid {
		margin-left: var(--cb-gutter, 24px);
		margin-right: var(--cb-gutter, 24px);
	}
}

/* Los modales, con margen a los lados en pantallas pequeñas. */
@media (max-width: 600px) {
	.cb-modal {
		padding: 12px;
	}

	.cb-modal__box,
	.cb-modal__box--wide,
	.cb-modal__box--obra {
		max-height: 92vh;
	}
}

/* El formulario del plugin pintado con un shortcode, fuera de un .cb-wrap: se
   le da el gutter para que los campos no lleguen al borde. */
body.cb-site .entry-content > .cbf,
body.cb-site .entry-content > div > .cbf {
	padding-left: var(--cb-gutter, 24px);
	padding-right: var(--cb-gutter, 24px);
	box-sizing: border-box;
}

/* Tabla de datos de la ficha y del modal: el valor de la derecha se salía. */
@media (max-width: 600px) {
	.cb-ficha__row,
	.cb-obra__meta {
		flex-direction: column;
		gap: 2px;
	}

	.cb-ficha__row span:last-child,
	.cb-obra__meta span:last-child {
		text-align: left;
	}
}

/* Los filtros de obras: en móvil se apilan y necesitan aire. */
@media (max-width: 600px) {
	.cb-filters {
		margin-bottom: 30px;
	}

	.cb-filters a,
	.cb-filters button {
		font-size: var(--cb-fs-md);
		padding: 10px 16px;
	}
}

/* La cabecera del formulario y de las obras: en móvil, en columna. */
@media (max-width: 700px) {
	.cb-form__head,
	.cb-obras__head {
		flex-direction: column;
		align-items: flex-start;
		gap: 16px;
	}
}

/* ==========================================================================
   34. GUTTER GARANTIZADO
   Hasta ahora el margen lateral dependía de que cada bloque llevara .cb-wrap.
   Basta con que uno se me olvide, o con que un plugin pinte algo suelto, para
   que ese trozo se vaya al borde de la pantalla. Aquí el margen se asegura por
   estructura: se le da a TODA sección directa del contenido, y se le quita solo
   a las que van a sangre a propósito.
   ========================================================================== */

/* Toda sección del contenido lleva margen lateral… */
#cb-main > section,
#cb-main > div:not(.cb-band):not(.cb-band--both) {
	padding-left: var(--cb-gutter, 24px);
	padding-right: var(--cb-gutter, 24px);
	box-sizing: border-box;
}

/* …y el .cb-wrap de dentro no lo repite. */
#cb-main > section > .cb-wrap,
#cb-main > div > .cb-wrap {
	padding-left: 0;
	padding-right: 0;
}

/*
 * Excepciones: los bloques que en el diseño llegan de lado a lado. Sus líneas
 * de 1px y sus fondos tienen que tocar el borde de la ventana; el margen lo
 * pone el .cb-wrap que llevan dentro.
 */
#cb-main > .cb-hero,
#cb-main > .cb-banner,
#cb-main > .cb-claim,
#cb-main > .cb-band,
#cb-main > .cb-band--both,
#cb-main > section.cb-band,
#cb-main > section.cb-band--both,
#cb-main > section.cb-banner,
#cb-main > section.cb-hero {
	padding-left: 0;
	padding-right: 0;
}

#cb-main > .cb-hero .cb-wrap,
#cb-main > .cb-banner .cb-wrap,
#cb-main > .cb-claim .cb-wrap,
#cb-main > .cb-band .cb-wrap,
#cb-main > .cb-band--both .cb-wrap,
#cb-main > section.cb-band .cb-wrap,
#cb-main > section.cb-band--both .cb-wrap {
	padding-left: var(--cb-gutter, 24px);
	padding-right: var(--cb-gutter, 24px);
}

/* Y el propio main, como última red: si algo se pinta fuera de una sección
   —un shortcode, un aviso de plugin— tampoco toca el borde. */
#cb-main > p,
#cb-main > ul,
#cb-main > ol,
#cb-main > h1,
#cb-main > h2,
#cb-main > h3,
#cb-main > figure,
#cb-main > table,
#cb-main > form,
#cb-main > .cbf {
	padding-left: var(--cb-gutter, 24px);
	padding-right: var(--cb-gutter, 24px);
	box-sizing: border-box;
	max-width: var(--cb-max);
	margin-left: auto;
	margin-right: auto;
}

/* ==========================================================================
   35. TEXTO DE LOS BOTONES DEL HEADER
   Astra envuelve el rótulo en un <span class="menu-text"> y le da color propio,
   así que forzar el color en el enlace no basta: hay que forzarlo también en el
   span, o el texto se queda del color del personalizador. Solo el color: si se
   le pone fondo, el rectángulo del texto se dibuja aparte del botón.
   ========================================================================== */

body.cb-site .cb-lock .menu-text,
body.cb-site .cb-call .menu-text,
body.cb-site .cb-lock > .menu-link > *,
body.cb-site .cb-call > .menu-link > * {
	color: #fff !important;
	background: none !important;
}

/* El icono se dibuja con máscara sobre currentColor, así que sigue al texto. */
body.cb-site .cb-lock > .menu-link::before,
body.cb-site .cb-call > .menu-link::before {
	background: currentColor !important;
}

/* Astra también pinta un subrayado animado en el hover del menú: en un botón
   con fondo se ve como una raya suelta encima del texto. */
body.cb-site .cb-lock > .menu-link::after,
body.cb-site .cb-call > .menu-link::after {
	display: none !important;
}

/* ==========================================================================
   36. RETÍCULA DE VENTAJAS / DIFERENCIAS
   El mismo bloque sirve para las 4 ventajas de la home y para las 12
   diferencias de Nuestra empresa. Con columnas automáticas salían 7 y luego 5,
   con celdas de 240px: texto en columnas de dos palabras y una fila coja.

   Solo se usan 1, 2 y 4 columnas, porque son los únicos repartos que dejan
   filas completas con 4 elementos y con 12 a la vez. Tres columnas quedaría
   bien con 12 (tres filas de cuatro… no, cuatro filas de tres) pero dejaría dos
   huecos con las 4 de la home, así que se descarta.
   ========================================================================== */

.cb-grid--ventajas {
	grid-template-columns: 1fr;
}

@media (min-width: 600px) {
	.cb-grid--ventajas {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1100px) {
	.cb-grid--ventajas {
		grid-template-columns: repeat(4, 1fr);
	}
}

/*
 * Las celdas de las diferencias llevan texto largo y poco ancho. Se les da algo
 * más de aire lateral y se alinea el texto a la izquierda por encima de cierto
 * tamaño: centrado y en columna estrecha, cada línea empieza en un sitio
 * distinto y cuesta leerlo.
 */
.cb-grid--ventajas .cb-cell {
	padding: clamp(28px, 3vw, 44px) clamp(22px, 2.4vw, 34px);
}

.cb-grid--ventajas .cb-cell__text {
	max-width: 42ch;
	margin-left: auto;
	margin-right: auto;
}

/* Los títulos de dos líneas descuadraban el arranque del texto: se reserva el
   alto de dos líneas para que todos los párrafos empiecen a la misma altura. */
@media (min-width: 1100px) {
	.cb-grid--ventajas .cb-cell__title {
		min-height: calc(2 * 1.3em);
		display: flex;
		align-items: center;
		justify-content: center;
	}
}

/* El título de la ficha se apoya abajo, así que uno de tres líneas empuja hacia
   arriba y descuadra la fila. Se reserva el alto de tres líneas: es lo que ocupa
   el título más largo del catálogo, «Cubiertas Metálicas Simples, Sándwich
   In-Situ y Panel Sándwich». */
@media (min-width: 1200px) {
	.cb-grid--servicios .cb-tile__title {
		min-height: calc(3 * 1.3em);
	}
}

/* En móvil la ficha no necesita ser tan alta: con una sola columna, 1/1.12 deja
   una tarjeta de 390px de alto para un título de dos palabras. */
@media (max-width: 519px) {
	.cb-grid--servicios .cb-tile {
		aspect-ratio: auto;
		min-height: 200px;
	}
}

/* ==========================================================================
   37. BARRA DE ENLACES LEGALES DEL PIE
   La pinta cb_footer_legal_auto() al final del footer de Astra. Los enlaces
   llevan la clase cb-open-legal, así que abren el modal en su pestaña en lugar
   de navegar a la página.
   ========================================================================== */

.cb-legal-bar {
	background: var(--cb-bg);
	border-top: 1px solid var(--cb-line);
	padding: 20px 0;
}

.cb-legal-bar .cb-legal-menu {
	justify-content: center;
	font-size: var(--cb-fs-md);
}

.cb-legal-menu__sep {
	color: var(--cb-text-30);
	-webkit-user-select: none;
	user-select: none;
}

.cb-legal-menu__copy {
	color: var(--cb-text-40);
	margin-left: auto;
}

body.cb-site .cb-legal-menu a {
	cursor: pointer;
	border-bottom: 1px solid transparent;
	transition: border-color var(--cb-t), color var(--cb-t);
}

body.cb-site .cb-legal-menu a:hover {
	color: var(--cb-accent);
	border-bottom-color: var(--cb-accent);
}

@media (max-width: 700px) {
	.cb-legal-bar .cb-legal-menu {
		flex-direction: column;
		align-items: center;
		gap: 10px;
	}

	.cb-legal-menu__sep {
		display: none;
	}

	.cb-legal-menu__copy {
		margin-left: 0;
		margin-top: 6px;
	}
}

/* ==========================================================================
   38. PREGUNTAS FRECUENTES
   El acordeón del prototipo, con lo que 25 preguntas necesitan para poder
   usarse. Nada nuevo: los filtros son los de Obras y el buscador usa los campos
   del formulario.
   ========================================================================== */

/*
 * Ancho de lectura.
 *
 * El acordeón ocupaba los 1.900px del contenedor y la marca de abrir quedaba a
 * un metro del texto: había que cruzar la pantalla con la vista para saber si
 * una pregunta estaba abierta. Se limita a la medida de lectura y la marca cae
 * junto a la pregunta.
 */
.cb-faq__lista,
.cb-faq__tools,
.cb-faq__filtros,
.cb-faq__vacio,
.cb-faq__cierre {
	max-width: clamp(820px, 530.345px + 20.690vw, 1040px);
}

.cb-faq__tools {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
	margin-bottom: 30px;
}

.cb-faq__buscador {
	flex: 1 1 320px;
	max-width: 460px;
}

.cb-faq__buscador input {
	/* La lupa, dibujada en el propio campo: no hace falta ningún icono. */
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,.45)' stroke-width='1.6'><circle cx='11' cy='11' r='7'/><path d='M20 20l-4.3-4.3'/></svg>");
	background-repeat: no-repeat;
	background-position: left 16px center;
	background-size: 18px 18px;
	padding-left: 46px;
}

.cb-faq__buscador input::-webkit-search-cancel-button {
	filter: invert(1);
	opacity: .5;
	cursor: pointer;
}

.cb-faq__contador {
	margin: 0 0 6px;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-45);
	white-space: nowrap;
}

/* Los chips de categoría llevan el número de preguntas. */
.cb-faq__filtros {
	margin-bottom: 40px;
}

.cb-filters__n {
	margin-left: 8px;
	font-size: 12px;
	color: var(--cb-text-45);
}

body.cb-site .cb-filters .is-active .cb-filters__n {
	color: rgba(255, 255, 255, .7);
}

.cb-faq__grupo {
	margin-bottom: clamp(44px, 3.4vw, 70px);
}

.cb-faq__grupo:last-child {
	margin-bottom: 0;
}

/* La pregunta, con sitio para respirar respecto a la marca. */
.cb-acc__q {
	padding-right: 20px;
}

.cb-faq__vacio {
	margin: 30px 0 0;
	padding: 30px 0;
	border-top: 1px solid var(--cb-line);
	font-size: var(--cb-fs-lg);
	color: var(--cb-text-60);
}

/* La pregunta a la que se ha llegado por enlace directo se señala un momento. */
.cb-acc__item:target {
	box-shadow: -3px 0 0 0 var(--cb-accent);
}

.cb-faq__cierre {
	padding: clamp(34px, 4vw, 50px) var(--cb-gutter, 24px);
	margin-top: 50px;
}

.cb-faq__cierre-btn {
	margin-top: 24px;
}

@media (max-width: 700px) {
	.cb-faq__tools {
		flex-direction: column;
		align-items: stretch;
		gap: 14px;
	}

	.cb-faq__contador {
		margin: 0;
	}

	.cb-faq__buscador {
		max-width: none;
	}
}

/* ==========================================================================
   39. IMPRESIÓN
   El botón «Descargar PDF» sirve el archivo del campo personalizado, así que
   esto ya no es la vía oficial. Pero si alguien imprime una ficha con Ctrl+P
   —pasa más de lo que parece cuando se va a visitar una obra— lo que sale es
   una ficha técnica de una página en lugar de la web en blanco y negro:
   membrete, título, entradilla, tabla de datos, texto a una columna y pie con
   los datos de contacto.
   ========================================================================== */

@page {
	size: A4;
	margin: 18mm 16mm 20mm;
}

@media print {

	/* ---------------------------------------------------------- Base */

	body.cb-site {
		background: #fff !important;
		color: #1a1a1a !important;
		font-size: 10.5pt;
		line-height: 1.55;
	}

	body.cb-site *,
	body.cb-site *::before,
	body.cb-site *::after {
		background-image: none !important;
		box-shadow: none !important;
		text-shadow: none !important;
		animation: none !important;
		transition: none !important;
	}

	body.cb-site h1,
	body.cb-site h2,
	body.cb-site h3,
	body.cb-site h4,
	body.cb-site h5,
	body.cb-site p,
	body.cb-site li,
	body.cb-site span,
	body.cb-site div,
	body.cb-site strong,
	body.cb-site a {
		color: #1a1a1a !important;
	}

	/* --------------------------------------------- Lo que no se imprime */

	.cb-noprint,
	[data-noprint],
	.site-header,
	.site-footer,
	.cb-legal-bar,
	.cb-modal,
	.cb-hero,
	.cb-banner,
	.cb-claim,
	.cb-filters,
	.cb-gallery,
	.cb-thumbs,
	.cb-round,
	.cb-nav-pair,
	.cb-btn,
	.cb-form,
	.cbf,
	.cb-form__head,
	.cb-testi__swiper,
	.cb-obras__swiper,
	.cb-scrollhint,
	.joinchat,
	#wpadminbar,
	#ast-scroll-top,
	.moove_gdpr_cookie_info_bar,
	#moove_gdpr_cookie_modal {
		display: none !important;
	}

	/* ------------------------------------------------------ Estructura */

	#cb-main,
	.cb-wrap,
	.cb-section,
	.cb-section--80,
	.cb-section--90,
	.cb-section--110,
	.cb-section--tight,
	.cb-section--both {
		max-width: none !important;
		width: auto !important;
		margin: 0 !important;
		padding: 0 !important;
		overflow: visible !important;
	}

	/* Nada de columnas en papel: el texto va corrido. */
	.cb-prose,
	.cb-cols,
	.cb-text {
		columns: 1 !important;
		column-gap: 0 !important;
		display: block !important;
		max-width: none !important;
	}

	/* --------------------------------------------------- Cabecera del PDF */

	/*
	 * El nombre de la empresa y el teléfono en la primera página. Se dibujan con
	 * ::before sobre el titular, así que no hace falta tocar la plantilla ni que
	 * aparezca nada de esto en pantalla.
	 */
	.cb-page-header--servicio::before {
		content: "CASABIEL CUBIERTAS · Cubiertas metálicas y mantenimiento industrial · 651 839 082 · casabielcubiertas.com";
		display: block;
		padding-bottom: 6pt;
		margin-bottom: 16pt;
		border-bottom: 1.5pt solid #A4163F;
		font-size: 8pt;
		letter-spacing: .06em;
		text-transform: uppercase;
		color: #A4163F !important;
	}

	.cb-page-header,
	.cb-page-header--servicio {
		padding: 0 !important;
	}

	.cb-page-header__title,
	body.cb-site h1.cb-page-header__title {
		font-size: 22pt !important;
		font-weight: 600 !important;
		line-height: 1.15 !important;
		letter-spacing: 0 !important;
		text-align: left !important;
		text-transform: none !important;
		margin: 0 0 10pt !important;
		padding: 0 !important;
	}

	/* La entradilla, que en pantalla va en la banda de claim. */
	.cb-claim__text {
		display: block !important;
		padding: 0 !important;
		margin: 0 0 16pt !important;
		font-size: 11.5pt !important;
		font-style: italic;
		text-align: left !important;
		color: #444 !important;
	}

	.cb-claim {
		display: block !important;
		border: none !important;
	}

	.cb-claim__grid {
		display: block !important;
		padding: 0 !important;
	}

	.cb-claim__grid::before,
	.cb-claim__grid::after {
		display: none !important;
	}

	/* ------------------------------------------------ Cuerpo de la ficha */

	.cb-box,
	.cb-box--soft,
	.cb-box--24,
	.cb-split,
	.cb-split--wide {
		display: block !important;
		border: none !important;
		padding: 0 !important;
		gap: 0 !important;
	}

	.cb-ficha__body {
		border: none !important;
		padding: 0 !important;
	}

	.cb-text p {
		margin: 0 0 8pt !important;
		font-size: 10.5pt !important;
		line-height: 1.55 !important;
		orphans: 3;
		widows: 3;
	}

	.cb-text strong {
		font-weight: 600 !important;
	}

	/* ------------------------------------------------- Tabla de datos */

	.cb-ficha__col {
		display: block !important;
		margin-top: 14pt;
		page-break-inside: avoid;
		break-inside: avoid;
	}

	.cb-ficha__head {
		padding: 0 0 6pt !important;
		border-bottom: 1pt solid #ccc !important;
	}

	.cb-ficha__label {
		font-size: 8pt !important;
		letter-spacing: .12em;
		color: #A4163F !important;
		margin: 0 0 4pt !important;
	}

	.cb-ficha__row {
		display: flex !important;
		justify-content: space-between;
		gap: 12pt;
		padding: 4pt 0 !important;
		border-bottom: .5pt solid #ddd !important;
		font-size: 10pt !important;
	}

	.cb-ficha__row span:first-child {
		color: #666 !important;
	}

	.cb-ficha__row span:last-child {
		font-weight: 600;
		text-align: right;
	}

	/* --------------------------------------------- «Qué incluye» y pasos */

	.cb-lines,
	.cb-grid,
	.cb-grid--ventajas,
	.cb-grid--servicios {
		display: block !important;
		border: none !important;
		gap: 0 !important;
	}

	.cb-cell {
		border: none !important;
		border-bottom: .5pt solid #ddd !important;
		padding: 6pt 0 !important;
		page-break-inside: avoid;
		break-inside: avoid;
	}

	.cb-cell__title,
	.cb-h5 {
		font-size: 11pt !important;
		font-weight: 600 !important;
		margin: 0 0 3pt !important;
	}

	.cb-cell__text {
		font-size: 10pt !important;
		color: #444 !important;
	}

	.cb-cell__icon,
	.cb-cell__slot {
		display: none !important;
	}

	.cb-num {
		color: #A4163F !important;
		font-size: 10pt !important;
	}

	.cb-h2,
	.cb-h3,
	.cb-h4 {
		font-size: 13pt !important;
		font-weight: 600 !important;
		margin: 14pt 0 6pt !important;
		page-break-after: avoid;
		break-after: avoid;
	}

	.cb-eyebrow {
		font-size: 8pt !important;
		letter-spacing: .12em;
		color: #A4163F !important;
		margin: 0 0 4pt !important;
	}

	.cb-eyebrow span {
		display: none !important;
	}

	/* ------------------------------------------------------ Imágenes */

	img {
		max-width: 100% !important;
		page-break-inside: avoid;
		break-inside: avoid;
	}

	/* El mosaico de otros servicios no aporta nada en papel. */
	.cb-tile,
	.cb-card,
	.cb-obra {
		display: none !important;
	}

	/* ---------------------------------------------------------- Pie */

	#cb-main::after {
		content: "Casabiel Cubiertas SL · C/ Monterregado nº 6, Local · 50007 Zaragoza · 651 839 082 · info@casabielcubiertas.com";
		display: block;
		margin-top: 18pt;
		padding-top: 6pt;
		border-top: .5pt solid #ccc;
		font-size: 8pt;
		color: #666 !important;
		text-align: center;
	}

	/* Los enlaces, sin subrayado y sin la URL detrás: en una ficha comercial
	   ensucia más de lo que aporta. */
	a[href]::after {
		content: "" !important;
	}
}

/* ==========================================================================
   40. AJUSTES DE LAS PREGUNTAS FRECUENTES
   ========================================================================== */

/*
 * El buscador.
 *
 * Era un <input type="search"> y ese tipo no estaba en ninguna de las listas de
 * campos del tema, así que se quedaba con el fondo blanco que Astra le pone a
 * los inputs. Aquí va explícito y con body.cb-site delante para ganarle.
 */
body.cb-site .cb-faq__buscador input[type="search"] {
	background-color: transparent !important;
	color: #fff !important;
	border: 1px solid var(--cb-text-40) !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	-webkit-appearance: none;
	appearance: none;
}

body.cb-site .cb-faq__buscador input[type="search"]:focus {
	border-color: var(--cb-accent) !important;
	outline: none;
}

body.cb-site .cb-faq__buscador input[type="search"]::placeholder {
	color: var(--cb-text-30);
	opacity: 1;
}

/* El bloque, centrado en la página. */
.cb-faq__lista,
.cb-faq__tools,
.cb-faq__filtros,
.cb-faq__vacio,
.cb-faq__cierre {
	margin-left: auto;
	margin-right: auto;
}

/*
 * Cada pregunta, en su caja.
 *
 * Antes eran líneas sueltas de borde a borde: la pregunta pegada a la izquierda
 * y la marca de abrir en el otro extremo, sin nada que las relacionara. Con una
 * caja con borde y aire por dentro se ve dónde empieza y acaba cada una, y al
 * pasar por encima se entiende que se puede pulsar.
 */
.cb-acc {
	border-top: none;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.cb-acc__item {
	border: 1px solid var(--cb-line-18);
	border-bottom: 1px solid var(--cb-line-18);
	transition: border-color var(--cb-t), background var(--cb-t);
}

.cb-acc__item:hover {
	border-color: var(--cb-line-30);
	background: rgba(255, 255, 255, .02);
}

.cb-acc__item.is-open {
	border-color: var(--cb-line-30);
	background: rgba(255, 255, 255, .03);
}

body.cb-site .cb-acc__head {
	padding: clamp(18px, 2vw, 24px) clamp(20px, 2.4vw, 30px);
	gap: 24px;
}

.cb-acc__inner {
	margin: 0;
	padding: 0 clamp(20px, 2.4vw, 30px) clamp(20px, 2.4vw, 26px);
	max-width: none;
}

/* La marca de abrir, más cerca del texto y con el aire justo. */
.cb-acc__icon {
	width: 26px;
	flex: none;
}

.cb-acc__item.is-open .cb-acc__head {
	padding-bottom: clamp(12px, 1.4vw, 16px);
}

/* El acordeón también se usa en la ficha de servicio y en el bloque de sección.
   Se le da la misma medida de lectura en todos: una caja de 1.900px con una
   pregunta de seis palabras dentro se ve vacía. */
.cb-acc {
	max-width: clamp(820px, 530.345px + 20.690vw, 1040px);
}

/* ==========================================================================
   41. BOTONES SIN FONDO PROPIO
   Astra pinta el color de marca en el :focus de cualquier <button>. Al pulsar
   uno, el foco se queda ahí y aparece un bloque granate donde no toca: pasó
   con la × del modal, con las flechas de los carruseles y con la pregunta
   abierta del acordeón. Aquí se cubren de una vez todos los botones del tema
   que NO llevan fondo por diseño.
   ========================================================================== */

body.cb-site .cb-round:focus,
body.cb-site .cb-round:active,
body.cb-site .cb-obra:focus,
body.cb-site .cb-obra:active,
body.cb-site .cb-hero__bullet:focus,
body.cb-site .cb-hero__bullet:active,
body.cb-site .cb-thumbs button:focus,
body.cb-site .cb-thumbs button:active,
body.cb-site .cb-tabs button:focus,
body.cb-site .cb-tabs button:active {
	background-color: transparent !important;
	box-shadow: none !important;
	outline: none;
}

/* Los circulares y las pestañas sí se rellenan al pasar por encima: eso es del
   diseño y se respeta. Lo que se anula es solo el fondo del foco. */
body.cb-site .cb-round:hover,
body.cb-site .cb-round:focus-visible {
	background-color: var(--cb-accent) !important;
}

body.cb-site .cb-tabs button:hover,
body.cb-site .cb-tabs button.is-active {
	background-color: var(--cb-bg-soft) !important;
}

/* Foco visible por teclado, con filete en vez de bloque de color. */
body.cb-site .cb-obra:focus-visible,
body.cb-site .cb-hero__bullet:focus-visible,
body.cb-site .cb-thumbs button:focus-visible,
body.cb-site .cb-tabs button:focus-visible {
	outline: 1px solid var(--cb-accent);
	outline-offset: 2px;
}

/* ==========================================================================
   42. VISOR DE FOTOS
   ========================================================================== */

.cb-lightbox {
	position: fixed;
	inset: 0;
	/* Por encima del modal de obra (200), que es desde donde también se abre. */
	z-index: 300;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(16px, 4vw, 56px);
	background: rgba(20, 21, 27, .94);
	opacity: 0;
	transition: opacity .2s ease;
}

.cb-lightbox.is-open {
	opacity: 1;
}

.cb-lightbox__veil {
	position: absolute;
	inset: 0;
	cursor: zoom-out;
}

.cb-lightbox__figura {
	position: relative;
	margin: 0;
	max-width: 100%;
	max-height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	pointer-events: none;
}

body.cb-site .cb-lightbox__figura img {
	max-width: 100%;
	/* Se descuenta el pie para que la foto nunca se salga de la pantalla. */
	max-height: calc(100vh - clamp(120px, 16vw, 200px));
	width: auto !important;
	height: auto !important;
	object-fit: contain;
	opacity: 0;
	transition: opacity .25s ease;
	pointer-events: auto;
}

.cb-lightbox__pie {
	display: flex;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
	justify-content: center;
	font-size: var(--cb-fs-md);
	color: var(--cb-text-60);
	text-align: center;
	pointer-events: auto;
}

.cb-lightbox__contador {
	color: var(--cb-text-40);
	font-variant-numeric: tabular-nums;
}

/* Indicador de carga: un aro girando mientras llega la imagen grande. */
.cb-lightbox__cargando {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 34px;
	height: 34px;
	margin: -17px 0 0 -17px;
	border: 2px solid rgba(255, 255, 255, .2);
	border-top-color: var(--cb-accent);
	border-radius: 50%;
	animation: cb-girar .8s linear infinite;
}

@keyframes cb-girar {
	to { transform: rotate(360deg); }
}

/* ------------------------------------------------------------ Controles */

body.cb-site .cb-lightbox__close,
body.cb-site .cb-lightbox__nav {
	position: absolute;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(54, 56, 69, .6) !important;
	border: 1px solid var(--cb-line-24) !important;
	border-radius: 0 !important;
	color: #fff !important;
	cursor: pointer;
	padding: 0 !important;
	box-shadow: none !important;
	transition: background var(--cb-t), border-color var(--cb-t);
}

body.cb-site .cb-lightbox__close:hover,
body.cb-site .cb-lightbox__nav:hover {
	background: var(--cb-accent) !important;
	border-color: var(--cb-accent) !important;
}

body.cb-site .cb-lightbox__close {
	top: clamp(12px, 2vw, 24px);
	right: clamp(12px, 2vw, 24px);
	width: 48px !important;
	height: 48px !important;
	font-size: 30px;
	font-weight: 200;
	line-height: 1;
}

body.cb-site .cb-lightbox__nav {
	top: 50%;
	transform: translateY(-50%);
	width: 56px !important;
	height: 56px !important;
}

body.cb-site .cb-lightbox__nav--prev { left: clamp(8px, 2vw, 24px); }
body.cb-site .cb-lightbox__nav--next { right: clamp(8px, 2vw, 24px); }

/* --------------------------------------------------- Disparador en la ficha */

/*
 * La diapositiva de la galería es ahora un botón. Sin esto heredaría el padding
 * y el fondo que Astra le pone a cualquier <button>.
 */
body.cb-site button.cb-gallery__stage {
	display: block;
	width: 100% !important;
	padding: 0 !important;
	border: none !important;
	background: var(--cb-bg-deep) !important;
	cursor: zoom-in;
	position: relative;
	overflow: hidden;
}

.cb-gallery__zoom {
	position: absolute;
	right: 14px;
	bottom: 14px;
	width: 40px;
	height: 40px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(54, 56, 69, .72);
	border: 1px solid var(--cb-line-24);
	color: #fff;
	opacity: 0;
	transform: translateY(6px);
	transition: opacity var(--cb-t), transform var(--cb-t);
	pointer-events: none;
}

body.cb-site button.cb-gallery__stage:hover .cb-gallery__zoom,
body.cb-site button.cb-gallery__stage:focus-visible .cb-gallery__zoom {
	opacity: 1;
	transform: none;
}

@media (max-width: 700px) {
	/* En el móvil no hay hover: la lupa se ve siempre. */
	.cb-gallery__zoom {
		opacity: 1;
		transform: none;
	}

	body.cb-site .cb-lightbox__nav {
		width: 44px !important;
		height: 44px !important;
	}
}

@media (prefers-reduced-motion: reduce) {
	.cb-lightbox,
	body.cb-site .cb-lightbox__figura img {
		transition: none;
	}

	.cb-lightbox__cargando {
		animation: none;
	}
}

/* La foto del modal de obra, ampliable. */
body.cb-site .cb-obra-modal__foto[data-cb-lightbox] {
	cursor: zoom-in;
}

/* El visor no se imprime. */
@media print {
	.cb-lightbox,
	.cb-gallery__zoom {
		display: none !important;
	}
}

/* ==========================================================================
   43. RESEÑAS DE GOOGLE
   El titular de los testimonios va acompañado de un sello que enlaza a la ficha
   de Google. Las citas son reseñas literales, así que el sello es lo que
   respalda que no están escritas por la casa.
   ========================================================================== */

.cb-testi__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 18px 26px;
	margin-bottom: 44px;
}

body.cb-site a.cb-google {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	padding: 9px 16px;
	border: 1px solid var(--cb-line-30);
	color: #fff;
	font-size: var(--cb-fs-md);
	letter-spacing: .06em;
	transition: border-color var(--cb-t), background var(--cb-t);
}

body.cb-site a.cb-google:hover {
	border-color: rgba(255, 255, 255, .6);
	background: rgba(255, 255, 255, .05);
	color: #fff;
}

.cb-google__estrellas {
	color: var(--cb-accent);
	font-weight: 600;
	letter-spacing: .1em;
}

/* En la cita, el origen se marca junto al autor. */
.cb-quote__fuente {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: var(--cb-fs-sm);
	color: var(--cb-text-45);
}

.cb-quote__fuente::before {
	content: "★";
	color: var(--cb-accent);
}

@media (max-width: 700px) {
	.cb-testi__head {
		gap: 14px;
		margin-bottom: 30px;
	}
}

/* ==========================================================================
   44. TEXTOS LEGALES COMPLETOS
   Los textos pasaron de 600 caracteres de relleno a los reales, de 4.500 a
   10.000. Traen subtítulos de segundo nivel, listas y tablas —la de cookies—
   que el modal no contemplaba.
   ========================================================================== */

.cb-legal h4 {
	margin: 26px 0 10px;
	font-size: var(--cb-fs-xl);
	font-weight: 600;
	line-height: 1.3;
}

.cb-legal h3 + h4 {
	margin-top: 14px;
}

.cb-legal ul,
.cb-legal ol {
	margin: 0 0 18px;
	padding-left: 22px;
	list-style: disc;
	font-size: var(--cb-fs-base);
	line-height: 1.8;
	color: var(--cb-text-70);
}

.cb-legal ol {
	list-style: decimal;
}

.cb-legal li {
	margin-bottom: 8px;
}

.cb-legal strong {
	color: #fff;
	font-weight: 600;
}

.cb-legal em {
	font-style: italic;
	color: var(--cb-text-60);
}

.cb-legal hr {
	margin: 32px 0;
	border-top: 1px solid var(--cb-line);
}

/* La tabla de cookies. En una columna estrecha se sale, así que se le deja
   scroll horizontal propio y se marca para que Lenis no se quede con la rueda. */
.cb-legal table {
	width: 100%;
	margin: 0 0 22px;
	border-collapse: collapse;
	font-size: var(--cb-fs-md);
	display: block;
	overflow-x: auto;
	min-width: 0;
	-webkit-overflow-scrolling: touch;
}

.cb-legal th,
.cb-legal td {
	padding: 10px 14px;
	border: 1px solid var(--cb-line-18);
	text-align: left;
	vertical-align: top;
	line-height: 1.6;
	color: var(--cb-text-74);
}

.cb-legal th {
	background: rgba(255, 255, 255, .04);
	color: #fff;
	font-weight: 600;
	white-space: nowrap;
}

.cb-legal td:first-child {
	white-space: nowrap;
	color: var(--cb-text-55);
}

/* El anexo del formulario de desistimiento: se lee mejor con aire. */
.cb-legal p + p {
	margin-top: 0;
}

@media (max-width: 700px) {
	.cb-legal table {
		font-size: var(--cb-fs-sm);
	}

	.cb-legal th,
	.cb-legal td {
		padding: 8px 10px;
	}
}

/* ==========================================================================
   45. ANTES Y DESPUÉS
   Comparador de dos fotografías con un tirador. La posición vive en la
   variable --cb-ad-x, que escribe el JS: así el arrastre no toca el DOM y no
   provoca recálculos de diseño en cada movimiento del dedo.
   ========================================================================== */

.cb-ad__head {
	display: grid;
	grid-template-columns: 1.05fr 1fr;
	align-items: end;
	gap: clamp(30px, 4.5vw, 60px);
	margin-bottom: clamp(34px, 4vw, 54px);
}

.cb-ad__intro {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.cb-ad__intro p {
	max-width: 520px;
	color: var(--cb-text-72);
}

.cb-ad__nav {
	display: flex;
	align-items: center;
	gap: 14px;
}

.cb-ad__contador {
	margin-left: 8px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .16em;
	color: var(--cb-text-45);
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------- El comparador */

.cb-ad__box {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	border: 1px solid var(--cb-line-18);
	background: var(--cb-bg-deep);
	cursor: ew-resize;
	/* Sin esto, el navegador se queda con el gesto para hacer scroll y el
	   tirador solo responde a la mitad de los movimientos. */
	touch-action: none;
	-webkit-user-select: none;
	user-select: none;
	outline: none;
}

body.cb-site .cb-ad__box:focus-visible {
	outline: 1px solid var(--cb-accent);
	outline-offset: -3px;
}

.cb-ad__par {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity var(--cb-t-slow);
}

.cb-ad__par.is-active {
	opacity: 1;
	visibility: visible;
}

.cb-ad__foto {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	pointer-events: none;
}

/*
 * El recorte es lo que hace el truco: la foto de «antes» se corta por la
 * derecha en la posición del tirador y deja ver la de «después», que está
 * debajo a tamaño completo. Las dos ocupan la misma caja, así que la
 * comparación es exacta.
 */
.cb-ad__recorte {
	position: absolute;
	inset: 0;
	overflow: hidden;
	clip-path: inset(0 calc(100% - var(--cb-ad-x, 50%)) 0 0);
	pointer-events: none;
}

.cb-ad__linea {
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--cb-ad-x, 50%);
	width: 1px;
	background: #fff;
	box-shadow: 0 0 24px rgba(255, 255, 255, .5);
	pointer-events: none;
}

.cb-ad__tirador {
	position: absolute;
	top: 50%;
	left: var(--cb-ad-x, 50%);
	transform: translate(-50%, -50%);
	width: 58px;
	height: 58px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, .85);
	background: rgba(54, 56, 69, .55);
	backdrop-filter: blur(4px);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 4px;
	color: #fff;
	pointer-events: none;
}

.cb-ad__etiqueta {
	position: absolute;
	top: 22px;
	padding: 8px 14px;
	font-size: var(--cb-fs-sm);
	letter-spacing: .18em;
	pointer-events: none;
}

.cb-ad__etiqueta--antes {
	left: 22px;
	background: rgba(54, 56, 69, .82);
	border: 1px solid var(--cb-line-24);
}

.cb-ad__etiqueta--despues {
	right: 22px;
	background: var(--cb-accent);
}

.cb-ad__pie {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: clamp(20px, 3vw, 34px);
	background: linear-gradient(180deg, rgba(54, 56, 69, 0) 0%, rgba(54, 56, 69, .92) 70%);
	pointer-events: none;
}

.cb-ad__servicio {
	font-size: var(--cb-fs-md);
	letter-spacing: .2em;
	color: var(--cb-text-60);
	margin-bottom: 8px;
}

.cb-ad__nombre,
body.cb-site h3.cb-ad__nombre {
	margin: 0;
	font-size: clamp(21px, 2.6vw, 26px);
	font-weight: 400;
	line-height: 1.3;
}

/* ----------------------------------------------------------- Paginador */

.cb-ad__puntos {
	display: flex;
	gap: 10px;
	margin-top: 22px;
	flex-wrap: wrap;
}

body.cb-site .cb-ad__punto {
	flex: 1 1 60px;
	min-width: 44px;
	height: 2px;
	padding: 0 !important;
	border: none !important;
	border-radius: 0 !important;
	background: rgba(255, 255, 255, .22) !important;
	cursor: pointer;
	transition: background var(--cb-t);
}

body.cb-site .cb-ad__punto:hover,
body.cb-site .cb-ad__punto.is-active {
	background: var(--cb-accent) !important;
}

/* La zona de pulsación real es mayor que la raya de 2px. */
body.cb-site .cb-ad__punto {
	position: relative;
}

body.cb-site .cb-ad__punto::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -12px;
	bottom: -12px;
}

@media (max-width: 900px) {
	.cb-ad__head {
		grid-template-columns: 1fr;
		gap: 26px;
	}
}

@media (max-width: 700px) {
	/* En vertical, el 16/9 deja una tira demasiado baja para apreciar nada. */
	.cb-ad__box {
		aspect-ratio: 4 / 3;
	}

	.cb-ad__etiqueta {
		top: 14px;
		padding: 6px 10px;
		font-size: var(--cb-fs-xs);
		letter-spacing: .12em;
	}

	.cb-ad__etiqueta--antes { left: 14px; }
	.cb-ad__etiqueta--despues { right: 14px; }

	.cb-ad__tirador {
		width: 46px;
		height: 46px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.cb-ad__par {
		transition: none;
	}
}

@media print {
	.cb-ad {
		display: none !important;
	}
}
