/* ==========================================================================
   GASCA MONTAJES — base.css
   Design system corporativo: variables, reset, tipografía, utilidades,
   botones, cabecera y pie.

   Tema claro sobre #f5f5f5, tarjetas blancas y azul corporativo #0274be.
   Las secciones de contraste (hero, CTA, pie) van en degradado azul.

   Esta hoja la cargan las 14 páginas: lo que se toque aquí se ve en todas.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Variables
   -------------------------------------------------------------------------- */
:root {
  /* --- Paleta corporativa --- */
  --azul: #0274be;
  --azul-claro: #5a9ad4;
  --azul-suave: #8cbddd;
  --azul-oscuro: #032e4e;   /* cierre del degradado de contraste */
  --gris-fondo: #f5f5f5;
  --negro: #000000;
  --blanco: #ffffff;

  /* --- Neutros de apoyo: bordes, rellenos y texto secundario. Son lo mínimo
     imprescindible; ningún acento sale de la paleta de arriba. --- */
  --gris-100: #ececec;   /* rellenos suaves */
  --gris-400: #9aa4ad;   /* placeholders, iconos apagados */
  --gris-500: #5b6570;   /* texto secundario */

  /* --- Estado ---
     Sólo el error. El verde y el ámbar del tema anterior se han retirado: los
     avisos («consultar disponibilidad») y las confirmaciones van en azul. */
  --error: #c0392b;   /* rojo sobrio: único color fuera de la paleta,
                         y sólo para errores */

  /* --- Semánticos --- */
  --fondo: var(--gris-fondo);
  --fondo-alt: var(--blanco);
  --superficie: var(--blanco);        /* tarjetas */
  --superficie-alta: var(--blanco);
  --texto: var(--negro);              /* cuerpo y titulares: negro corporativo */
  --texto-fuerte: var(--negro);
  --texto-suave: var(--gris-500);     /* texto secundario (leads, pies, ayudas):
                                         único gris de texto, derivado del azul
                                         oscuro para no ensuciar la paleta */
  --borde: #e3e6e9;
  --borde-fuerte: #cfd5da;

  /* --- Degradados ---
     El de contraste ya no es un degradado plano de 135°: lleva encima un foco
     de luz frío (azul-claro) que entra por la esquina superior izquierda y un
     leve oscurecido en la inferior derecha. Da un punto de luz coherente a
     TODAS las superficies azules (cabeceras interiores, bandas CTA, hero de
     respaldo, placeholders) sin salirse de la paleta: un degradado uniforme se
     lee plano y «de plantilla»; con el foco gana volumen. */
  --deg-contraste:
    radial-gradient(120% 135% at 16% -25%, rgba(90, 154, 212, 0.45) 0%, rgba(90, 154, 212, 0) 46%),
    radial-gradient(120% 120% at 100% 115%, rgba(3, 46, 78, 0.55) 0%, rgba(3, 46, 78, 0) 50%),
    linear-gradient(135deg, var(--azul) 0%, var(--azul-oscuro) 100%);
  --deg-azul: linear-gradient(135deg, var(--azul) 0%, var(--azul-claro) 100%);

  /* --- Tipografía --- */
  --fuente: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --fuente-titulo: 'Barlow Condensed', 'Inter', system-ui, sans-serif;

  --txt-xs: 0.75rem;
  --txt-sm: 0.875rem;
  --txt-base: 1rem;
  --txt-lg: 1.125rem;
  --txt-xl: 1.375rem;
  /* Barlow Condensed es estrecha: los titulares piden algo más de cuerpo
     que con una sans normal para pesar lo mismo en pantalla. */
  --txt-2xl: clamp(1.75rem, 1.4rem + 1.6vw, 2.4rem);
  --txt-3xl: clamp(2.1rem, 1.6rem + 2.6vw, 3.2rem);
  --txt-4xl: clamp(2.6rem, 1.7rem + 4vw, 4.4rem);
  /* Bajado de 5.2rem: dentro de la caja del hero, el titular a 5.2rem la
     estiraba casi de lado a lado y el conjunto pesaba demasiado. */
  --txt-hero: clamp(2.4rem, 1.5rem + 4vw, 4rem);

  /* --- Espaciado --- */
  --e-1: 0.25rem;  --e-2: 0.5rem;   --e-3: 0.75rem;  --e-4: 1rem;
  --e-5: 1.5rem;   --e-6: 2rem;     --e-7: 2.5rem;   --e-8: 3rem;
  --e-9: 4rem;     --e-10: 5rem;    --e-11: 6rem;    --e-12: 8rem;

  /* --- Medidas --- */
  --ancho-max: 1200px;
  --ancho-texto: 68ch;
  --header-h: 76px;

  /* --- Radios: moderados, nada de píldoras en las tarjetas --- */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 12px;
  --r-full: 999px;

  /* --- Sombras: sutiles, tema claro --- */
  --sombra-sm: 0 1px 2px rgba(3, 46, 78, 0.06), 0 1px 3px rgba(3, 46, 78, 0.05);
  --sombra-md: 0 4px 12px rgba(3, 46, 78, 0.08), 0 2px 4px rgba(3, 46, 78, 0.04);
  --sombra-lg: 0 12px 32px rgba(3, 46, 78, 0.12), 0 4px 8px rgba(3, 46, 78, 0.05);
  --sombra-azul: 0 6px 18px rgba(2, 116, 190, 0.28);

  /* --- Transiciones --- */
  --t-rapida: 140ms ease;
  --t-media: 240ms cubic-bezier(0.16, 1, 0.3, 1);
  --t-lenta: 520ms cubic-bezier(0.16, 1, 0.3, 1);

  /* --- Capas --- */
  --z-header: 100;
  --z-fab: 90;
  --z-modal: 200;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  min-height: 100vh;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--fuente);
  font-size: var(--txt-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, picture, svg, video {
  display: block;
  max-width: 100%;
}

input, button, textarea, select { font: inherit; color: inherit; }

/* Sin esto, un <button> sin fondo declarado sale con el «buttonface» del
   sistema (#f0f0f0): un gris ajeno a la paleta. Lo sufrían el acordeón de
   Nosotros y el «quitar» del CV. */
button { cursor: pointer; background: none; border: none; }

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

a { color: var(--azul); text-decoration: none; transition: color var(--t-rapida); }
a:hover { color: var(--azul-claro); }

h1, h2, h3, h4 {
  font-family: var(--fuente-titulo);
  font-weight: 700;
  line-height: 1.08;
  color: var(--texto-fuerte);
  text-transform: uppercase;
  letter-spacing: 0.015em;
}

h1 { font-size: var(--txt-4xl); }
h2 { font-size: var(--txt-3xl); }
h3 { font-size: var(--txt-xl); letter-spacing: 0.02em; }
h4 { font-size: var(--txt-lg); letter-spacing: 0.02em; }

/* El navegador oculta [hidden] con display:none desde su hoja de usuario, pero
   cualquier regla nuestra que fije display (.vacio{display:flex},
   .listado__grid>li{display:flex}...) la gana y el elemento se sigue viendo. */
[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   3. Foco visible — accesibilidad
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 3px solid var(--azul);
  outline-offset: 3px;
  border-radius: 2px;
}
/* En fondo azul el contorno azul no se vería */
.seccion--contraste :focus-visible,
.footer :focus-visible,
.hero :focus-visible {
  outline-color: var(--blanco);
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--e-4);
  z-index: calc(var(--z-header) + 10);
  padding: var(--e-3) var(--e-5);
  background: var(--azul);
  color: var(--blanco);
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-weight: 600;
  transition: top var(--t-media);
}
.skip-link:focus { top: 0; color: var(--blanco); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--ancho-max);
  margin-inline: auto;
  padding-inline: var(--e-5);
}

.seccion { padding-block: var(--e-10); }
.seccion--alt { background: var(--fondo-alt); }
.seccion--superficie { background: var(--superficie); }

/* Secciones de contraste: degradado azul y texto blanco */
.seccion--contraste {
  background: var(--deg-contraste);
  color: rgba(255, 255, 255, 0.88);
}
.seccion--contraste h1,
.seccion--contraste h2,
.seccion--contraste h3,
.seccion--contraste h4 { color: var(--blanco); }
.seccion--contraste a { color: var(--azul-suave); }
.seccion--contraste a:hover { color: var(--blanco); }

@media (max-width: 768px) {
  .seccion { padding-block: var(--e-8); }
}

/* --- Cabecera de sección: titular + línea de acento corta debajo --- */
.seccion__cabecera { margin-bottom: var(--e-8); }

.seccion__cabecera h2::after {
  content: '';
  display: block;
  width: 56px;
  height: 4px;
  margin-top: var(--e-4);
  border-radius: var(--r-full);
  /* En fondo azul la línea azul no se vería: cada contexto la redefine */
  background: var(--acento-linea, var(--azul));
}
.seccion__cabecera.txt-centro h2::after { margin-inline: auto; }
.seccion--contraste, .hero, .footer { --acento-linea: var(--azul-suave); }

.antetitulo {
  display: inline-block;
  margin-bottom: var(--e-3);
  color: var(--azul);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.seccion--contraste .antetitulo,
.hero .antetitulo { color: var(--azul-suave); }

.lead {
  font-size: var(--txt-lg);
  line-height: 1.7;
  color: var(--texto-suave);
}
.seccion--contraste .lead { color: rgba(255, 255, 255, 0.85); }

/* --------------------------------------------------------------------------
   5. Tarjetas
   -------------------------------------------------------------------------- */
.tarjeta {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-sm);
  transition: transform var(--t-media), box-shadow var(--t-media),
              border-color var(--t-media);
}
.tarjeta:hover {
  transform: translateY(-4px);
  box-shadow: var(--sombra-lg);
  border-color: var(--azul-suave);
}
.tarjeta__cuerpo { padding: var(--e-6); }

/* --------------------------------------------------------------------------
   6. Botones
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  padding: 0.75rem 1.5rem;
  border: 2px solid transparent;
  border-radius: var(--r-md);
  background: none;
  font-family: var(--fuente-titulo);
  font-size: var(--txt-base);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--t-media), border-color var(--t-media),
              color var(--t-media), transform var(--t-media),
              box-shadow var(--t-media);
}
.btn:disabled, .btn[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

/* Primario: azul sólido */
.btn--primario {
  background: var(--azul);
  border-color: var(--azul);
  color: var(--blanco);
  box-shadow: var(--sombra-sm);
}
.btn--primario:hover:not(:disabled) {
  background: var(--azul-claro);
  border-color: var(--azul-claro);
  color: var(--blanco);
  transform: translateY(-2px);
  box-shadow: var(--sombra-azul);
}

/* Secundario: fantasma con borde azul */
.btn--secundario {
  border-color: var(--azul);
  color: var(--azul);
}
.btn--secundario:hover:not(:disabled) {
  background: var(--azul);
  color: var(--blanco);
  transform: translateY(-2px);
}
/* Sobre fondo azul, el fantasma va en blanco.

   .cta-banda y .cta-final tienen que estar en esta lista aunque no lleven la
   clase .seccion--contraste: su fondo es el degradado azul y sin esto el botón
   quedaba con borde y texto --azul sobre azul, es decir, invisible. Le pasaba
   al teléfono del CTA de Servicios, Proyectos y Nosotros.
   Si añades otra sección de fondo azul, o le pones .seccion--contraste o la
   sumas aquí. */
.seccion--contraste .btn--secundario,
.cta-banda .btn--secundario,
.cta-final .btn--secundario,
.hero .btn--secundario {
  border-color: rgba(255, 255, 255, 0.7);
  color: var(--blanco);
}
.seccion--contraste .btn--secundario:hover:not(:disabled),
.cta-banda .btn--secundario:hover:not(:disabled),
.cta-final .btn--secundario:hover:not(:disabled),
.hero .btn--secundario:hover:not(:disabled) {
  background: var(--blanco);
  border-color: var(--blanco);
  color: var(--azul-oscuro);
}

.btn--grande { padding: 1rem 2rem; font-size: var(--txt-lg); }
.btn--bloque { display: flex; width: 100%; }

/* --------------------------------------------------------------------------
   7. Enlaces y etiquetas
   -------------------------------------------------------------------------- */
.enlace-flecha {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  color: var(--azul);
  font-family: var(--fuente-titulo);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.enlace-flecha::after {
  content: '→';
  transition: transform var(--t-media);
}
.enlace-flecha:hover::after { transform: translateX(5px); }
.seccion--contraste .enlace-flecha { color: var(--azul-suave); }

.etiqueta {
  display: inline-block;
  padding: 0.25rem 0.7rem;
  border-radius: var(--r-full);
  background: rgba(2, 116, 190, 0.1);
  color: var(--azul);
  font-size: var(--txt-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.etiqueta--azul { background: var(--azul); color: var(--blanco); }
.etiqueta--neutra {
  background: var(--gris-100);
  color: var(--texto-suave);
}

/* --------------------------------------------------------------------------
   8. Prosa — bloques de texto largo (legales, detalle de post)
   -------------------------------------------------------------------------- */
.prosa { max-width: var(--ancho-texto); }
.prosa > * + * { margin-top: var(--e-5); }
.prosa h2 { margin-top: var(--e-8); }
.prosa h3 { margin-top: var(--e-6); }
.prosa ul { list-style: disc; padding-left: var(--e-5); }
.prosa li + li { margin-top: var(--e-2); }
.prosa strong { color: var(--texto-fuerte); font-weight: 600; }

/* Tablas de la prosa (la de cookies). El envoltorio con overflow-x es lo que
   impide que una tabla estire el documento entero en móvil: el que se
   desplaza es él, no la página. */
.prosa table {
  display: block;
  overflow-x: auto;
  width: 100%;
  border-collapse: collapse;
  font-size: var(--txt-sm);
}
.prosa th,
.prosa td {
  padding: var(--e-3) var(--e-4);
  border: 1px solid var(--borde);
  text-align: left;
  vertical-align: top;
}
.prosa th {
  background: var(--gris-100);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-base);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.prosa code {
  padding: 0.1em 0.4em;
  border-radius: var(--r-sm);
  background: var(--gris-100);
  font-size: 0.9em;
}

/* --------------------------------------------------------------------------
   9. Cabecera del sitio
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--blanco);
  border-bottom: 1px solid var(--borde);
  /* box-shadow ya no está aquí: lo hace ::after (ver justo debajo) */
  transition: background var(--t-media), border-color var(--t-media);
}
/* La sombra al hacer scroll va en un pseudoelemento que se desvanece, y no en
   el box-shadow de la propia cabecera.

   Cambiar el box-shadow de un elemento «sticky» le cambia el pintado a mitad
   de scroll y el navegador lo convierte en una capa compositada: todo lo que
   hay dentro (el logo) se vuelve a rasterizar en ese momento, y ahí es donde
   aparecía el borrón. Animando la opacidad de una capa aparte, el contenido de
   la cabecera no se vuelve a dibujar. */
.header::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 12px;
  transform: translateY(100%);
  background: linear-gradient(to bottom, rgba(3, 46, 78, 0.10), rgba(3, 46, 78, 0));
  opacity: 0;
  transition: opacity var(--t-media);
  pointer-events: none;
}
.header.is-scroll::after { opacity: 1; }

/* --------------------------------------------------------------------------
   9 bis. Cabecera en overlay (sólo la portada: <body class="con-hero-overlay">)

   Encima de la foto del hero, no delante. fixed y no sticky porque sticky
   ocuparía su hueco en el flujo y empujaría el hero hacia abajo; el hero
   compensa con un padding-top del alto de la cabecera.

   Al hacer scroll, .is-scroll —que ya ponía site.js— la devuelve a blanca y
   todo vuelve a sus colores normales.
   -------------------------------------------------------------------------- */
.con-hero-overlay .header {
  position: fixed;
  left: 0;
  right: 0;
}
.con-hero-overlay .header:not(.is-scroll) {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}
/* Sobre la foto todo pasa a blanco: el negro del menú desaparecería */
.con-hero-overlay .header:not(.is-scroll) .logo__img--color { display: none; }
.con-hero-overlay .header:not(.is-scroll) .logo__img--claro { display: block; }

.con-hero-overlay .header:not(.is-scroll) .nav__enlace {
  color: var(--blanco);
}
/* El activo y el hover se quedan en blanco, no en azul suave: sobre una foto
   azulada el azul suave es casi el mismo color del fondo y el enlace parecía
   apagado justo cuando debe destacar. Lo que marca cuál es la página actual es
   la línea de debajo, no un cambio de color. */
.con-hero-overlay .header:not(.is-scroll) .nav__enlace:hover,
.con-hero-overlay .header:not(.is-scroll) .nav__enlace.is-activo {
  color: var(--blanco);
}
/* La línea también: en azul corporativo (su color normal) se perdía contra la
   foto oscura, así que el subrayado del activo no se veía. */
.con-hero-overlay .header:not(.is-scroll) .nav__enlace::after {
  background: var(--blanco);
  box-shadow: 0 1px 6px rgba(3, 46, 78, 0.6);
}
/* La hamburguesa lleva fondo blanco de serie. Con las barras en blanco del
   overlay quedaba blanco sobre blanco: un cuadrado vacío en la portada por
   debajo de 980px. En overlay va calada, con el borde en blanco. */
.con-hero-overlay .header:not(.is-scroll) .hamburguesa {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.7);
}
.con-hero-overlay .header:not(.is-scroll) .hamburguesa span { background: var(--blanco); }
.con-hero-overlay .header:not(.is-scroll) .nav__desplegar { color: var(--blanco); }
/* El submenú es una tarjeta blanca aparte: dentro de ella se manda el color
   normal, no el blanco del overlay. */
.con-hero-overlay .header:not(.is-scroll) .submenu a { color: var(--negro); text-shadow: none; }
.con-hero-overlay .header:not(.is-scroll) .submenu a:hover { color: var(--azul); }
.con-hero-overlay .header:not(.is-scroll) .submenu__todos a { color: var(--azul); }

/* Un texto blanco fino sobre una foto necesita ayuda: el velo del hero no
   llega hasta arriba del todo. */
.con-hero-overlay .header:not(.is-scroll) .nav__enlace {
  text-shadow: 0 1px 10px rgba(3, 46, 78, 0.55);
}

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--e-5);
  min-height: var(--header-h);
}

/* --- Logo --- */
/* El logo era una «G» dibujada con CSS más el nombre en Barlow Condensed: un
   apaño mientras no había marca. Ahora es el SVG real de Gasca. */
.logo {
  display: inline-flex;
  align-items: center;
  margin-right: auto;
  /* El SVG tiene su propio alto y el enlace no debe añadir el interlineado
     fantasma que deja un elemento en línea. */
  line-height: 0;
}
/* Medidas en píxeles enteros, no «width:auto».

   Con height:44px y la proporción 4,58:1, el ancho salía 201,52px; en móvil,
   155,61px. Un ancho con decimales obliga al navegador a dibujar el logo entre
   píxeles, y eso se ve en cuanto la cabecera pasa a ser una capa aparte (que
   es lo que ocurre al aparecer la sombra al hacer scroll): el SVG se rasteriza
   una vez y queda con el borde sucio, como si fuera un JPG malo.

   202 y 156 son los enteros más cercanos: la desviación es de medio píxel, ni
   se nota en la proporción y en cambio el trazo queda limpio. */
.logo__img {
  display: block;
  width: 202px;
  height: 44px;
  transition: opacity var(--t-rapida);
}
@media (max-width: 900px) {
  .logo__img { width: 156px; height: 34px; }
}
.logo:hover .logo__img { opacity: 0.82; }

/* La variante clara sólo se enseña en la cabecera en overlay (ver 9 bis).
   Esta regla tiene que ir DESPUÉS de «.logo__img { display: block }»: misma
   especificidad, gana la última. Puesta antes, se veían los dos logos
   superpuestos en cuanto la cabecera se volvía blanca. */
.logo__img--claro { display: none; }

/* El pie usa logo-h-claro.svg, que ya viene con el texto en blanco: aquí sólo
   se le da algo más de aire, que es la zona de marca. */
.logo--footer .logo__img { height: 52px; }

/* --- Navegación --- */
.nav__lista { display: flex; align-items: center; gap: var(--e-1); }

/* --- Submenú de Servicios --- */
.nav__item--sub { position: relative; }
.nav__fila { display: flex; align-items: center; }

.nav__desplegar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  margin-left: -6px;
  color: var(--negro);
  border-radius: var(--r-sm);
  transition: transform var(--t-media), color var(--t-rapida);
}
.nav__desplegar svg { width: 14px; height: 14px; }
.nav__desplegar[aria-expanded="true"] { transform: rotate(180deg); }
.nav__item--sub:hover .nav__desplegar,
.nav__desplegar[aria-expanded="true"] { color: var(--azul); }

/* Panel ancho de servicios: lista a la izquierda, vista previa a la derecha.

   left:auto + translateX centra el panel bajo «Servicios» en vez de colgarlo
   por la derecha: con 720px de ancho, anclado a la izquierda se salía de la
   ventana en pantallas de 1280px.

   max-width con calc para que en una ventana estrecha se encoja en lugar de
   provocar scroll horizontal. */
.submenu {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  z-index: 1;
  width: 720px;
  max-width: calc(100vw - var(--e-6) * 2);
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--blanco);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-lg);
  overflow: hidden;
  /* visibility además de opacity: sin ella el submenú seguiría siendo
     clicable e interceptaría el ratón aunque no se viera. */
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-media), transform var(--t-media), visibility var(--t-media);
}
.nav__item--sub:hover .submenu,
.nav__item--sub:focus-within .submenu,
.submenu.is-abierto {
  opacity: 1;
  visibility: visible;
  /* Conserva el centrado: sin el translateX el panel saltaría a la derecha al
     abrirse, porque «none» borra las dos transformaciones. */
  transform: translateX(-50%) translateY(0);
}

/* flex y no block: cada entrada lleva ahora el icono de su servicio delante.
   align-items:center para que icono y texto queden alineados aunque el nombre
   pase a dos líneas en una ventana estrecha. */
/* --- Columna izquierda: la lista --- */
.submenu__lista {
  padding: var(--e-3);
  background: var(--gris-fondo);
  border-right: 1px solid var(--borde);
}

.submenu__lista a {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  /* Menos aire arriba y abajo, más a los lados: se gana altura sin que las
     entradas se toquen entre sí. */
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-sm);
  color: var(--negro);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-lg);
  font-weight: 600;
  letter-spacing: 0.03em;
  transition: background var(--t-rapida), color var(--t-rapida);
}
/* .is-activo lo pone site.js al pasar el ratón o al tabular; el :hover está
   además para que funcione aunque el JS falle. */
.submenu__lista a:hover,
.submenu__lista a.is-activo {
  background: var(--blanco);
  color: var(--azul);
  box-shadow: var(--sombra-sm);
}
.submenu__nombre { line-height: 1.2; }

/* Cuadradito de fondo, como el de las tarjetas pero en pequeño: sin él, el
   icono suelto se lee como una mancha y no como un distintivo.
   flex-shrink para que no lo estruje un nombre largo. */
.submenu__icono {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  color: var(--azul);
  background: rgba(2, 116, 190, 0.1);
  border: 1px solid rgba(2, 116, 190, 0.22);
  border-radius: var(--r-sm);
  transition: background var(--t-rapida), border-color var(--t-rapida);
}
/* 26px en 34px con 1px de borde: 3px de aire por lado, la misma proporción
   generosa que en las tarjetas. */
.submenu__icono .icono-svg { width: 26px; height: 26px; }

.submenu__lista a:hover .submenu__icono,
.submenu__lista a.is-activo .submenu__icono {
  background: rgba(2, 116, 190, 0.18);
  border-color: rgba(2, 116, 190, 0.4);
}

/* --- Columna derecha: la vista previa --- */
.submenu__previa { padding: var(--e-4); }

.submenu__foto {
  /* 16/9 en vez de 16/10: es la parte más alta del panel y en apaisado se
     recorta menos escena de la que parece. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--deg-contraste);
}
.submenu__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--t-media);
}
/* La clase la pone site.js justo antes de cambiar el src, para que la foto
   nueva entre con un fundido en vez de aparecer de golpe. */
.submenu__foto img.is-cambiando { opacity: 0; }

.submenu__previa-titulo {
  margin-top: var(--e-3);
  font-size: var(--txt-xl);
  line-height: 1.1;
}
.submenu__previa-desc {
  margin-top: var(--e-2);
  /* Sube de 14 a 16px, que es el cuerpo normal del sitio: era el texto más
     pequeño del panel y el que hay que leer para elegir. El interlineado baja
     a 1.5 para compensar la altura que suma el cuerpo mayor. */
  font-size: var(--txt-base);
  line-height: 1.5;
  color: var(--texto-suave);
  /* Sitio reservado para 3 líneas (3 × 1.5). Los textos están escritos para
     entrar en tres, pero uno ocupa dos: sin esta reserva el panel encogía
     24px al pasar por encima de ese servicio y volvía a crecer al salir, y
     con el ratón dentro ese salto mueve las entradas bajo el cursor. */
  min-height: 4.5em;
}
.submenu__previa-mas {
  margin-top: var(--e-3);
  color: var(--azul);
  font-size: var(--txt-sm);
  font-weight: 600;
}

/* --- Pie: ocupa las dos columnas --- */
.submenu__pie {
  grid-column: 1 / -1;
  padding: var(--e-3) var(--e-5);
  background: var(--gris-fondo);
  border-top: 1px solid var(--borde);
}
.submenu__pie a {
  color: var(--azul);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-sm);
  font-weight: 600;
  letter-spacing: 0.03em;
}

.nav__enlace {
  position: relative;
  display: block;
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-sm);
  color: var(--negro);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-base);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: color var(--t-rapida);
}
.nav__enlace::after {
  content: '';
  position: absolute;
  left: var(--e-3);
  right: var(--e-3);
  bottom: 2px;
  height: 2px;
  border-radius: var(--r-full);
  background: var(--azul);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-media);
}
.nav__enlace:hover { color: var(--azul); }
.nav__enlace:hover::after { transform: scaleX(1); }
.nav__enlace.is-activo { color: var(--azul); }
.nav__enlace.is-activo::after { transform: scaleX(1); }

/* Los teléfonos dentro del menú: sólo se usan en el desplegable móvil */
.nav__contacto-movil { display: none; }

/* --- Teléfono de la cabecera --- */
/* El segundo número (el móvil 692 477 070) se ha quitado de la cabecera: dos
   teléfonos juntos obligan a elegir y restan fuerza al botón de llamada, que
   es la acción que interesa. Sigue estando en el pie y en Contacto. */
.header__contacto { display: flex; align-items: center; gap: var(--e-4); }

/* Más grande que un botón normal: es la llamada a la acción de toda la
   cabecera y tiene que pesar más que los enlaces del menú. */
.header__tel {
  padding: 0.85rem 1.5rem;
  font-size: var(--txt-base);
  border-radius: var(--r-md);
}
.header__tel-icono { width: 19px; height: 19px; }

/* --- Hamburguesa --- */
.hamburguesa {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0 10px;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--r-sm);
  background: var(--blanco);
  cursor: pointer;
}
.hamburguesa span {
  display: block;
  height: 2px;
  border-radius: var(--r-full);
  background: var(--negro);
  transition: transform var(--t-media), opacity var(--t-rapida);
}
.hamburguesa.is-abierto span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburguesa.is-abierto span:nth-child(2) { opacity: 0; }
.hamburguesa.is-abierto span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Cabecera en móvil --- */
@media (max-width: 980px) {
  .hamburguesa { display: flex; }
  .header__contacto { display: none; }

  /* Panel lateral que ocupa el 80% del ancho. Entra desde la derecha, que es
     donde está la hamburguesa: el menú sale de donde lo has pulsado.
     El 20% que queda a la vista, oscurecido, es lo que hace entender que
     estás en una capa por encima y que tocando fuera se cierra. */
  .nav {
    position: fixed;
    top: var(--header-h);
    right: 0;
    bottom: 0;
    left: auto;
    width: 80%;
    max-width: 420px;      /* en tablet, el 80% de 980px sería una sábana */
    overflow-y: auto;
    overscroll-behavior: contain;  /* al llegar al final no arrastra la página */
    padding: var(--e-5);
    background: var(--blanco);
    border-left: 1px solid var(--borde);
    box-shadow: var(--sombra-lg);
    /* Cerrado: fuera de pantalla por la derecha y sin recibir toques */
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--t-media), visibility var(--t-media);
  }
  .nav.is-abierto {
    transform: translateX(0);
    visibility: visible;
  }

  /* Velo sobre el resto de la pantalla. Va por debajo de la cabecera (que
     lleva z-index 100) para que el panel y la hamburguesa queden encima. */
  body.menu-abierto::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-header) - 1);
    background: rgba(3, 46, 78, 0.45);
  }

  .nav__lista { flex-direction: column; align-items: stretch; gap: 0; }

  /* En móvil el submenú no puede flotar: el menú ya es un panel desplegable y
     un flotante dentro de otro flotante se saldría de pantalla. Aquí va en
     línea, plegado, y lo abre el botón. Sin :hover, que en táctil no existe. */
  .nav__fila { justify-content: space-between; }
  .nav__desplegar { width: 44px; height: 44px; margin-left: 0; }
  .nav__desplegar svg { width: 18px; height: 18px; }

  /* En móvil el panel de dos columnas no cabe: se vuelve una lista plegada
     dentro del menú, sin panel flotante. */
  .submenu {
    position: static;
    width: auto;
    max-width: none;
    min-width: 0;
    /* Sin sangría: los nombres arrancan justo donde arranca «SERVICIOS».
       Lo que los agrupa es la línea vertical de la izquierda, que queda en el
       borde del panel. Los 6px son el hueco entre esa línea y el texto; con
       el borde de 2px suman los 8px de padding que ya tiene .nav__enlace, y
       así los dos textos empiezan en la misma vertical. */
    margin: 0 0 var(--e-2) 0;
    padding: 0 0 0 6px;
    background: none;
    border: none;
    border-left: 2px solid var(--borde);
    border-radius: 0;
    box-shadow: none;
    transform: none;
    /* Plegado de verdad: display:none y no sólo invisible, para que no deje
       un hueco en blanco dentro del menú. */
    display: none;
    opacity: 1;
    visibility: visible;
  }
  /* En móvil el panel NO se abre al pasar por encima: sólo con el botón. Estas
     dos reglas anulan el :hover y :focus-within que valen en escritorio.

     El :not(.is-abierto) es imprescindible. Sin él estas reglas (0,3,0) ganan
     por especificidad a «.submenu.is-abierto» (0,2,0) y dejan el panel cerrado
     aunque el JS haya puesto la clase. Al tocar en un móvil el navegador deja
     el :hover pegado en lo que acabas de tocar, así que tocabas «Servicios» y
     no pasaba nada. Con el :not, abrir gana siempre. */
  .nav__item--sub:hover .submenu:not(.is-abierto),
  .nav__item--sub:focus-within .submenu:not(.is-abierto) { display: none; }

  .submenu.is-abierto { display: block; }

  /* Anular el centrado de escritorio en TODOS sus estados.

     En escritorio el panel se centra bajo «Servicios» con
     translateX(-50%). Esas reglas hay que repetirlas aquí con la MISMA
     especificidad para poder anularlas: un media query no añade peso, así que
     «.submenu { transform: none }» (0,1,0) no puede con
     «.nav__item--sub:hover .submenu» (0,3,0).

     Se nota sobre todo al tocar: el navegador deja el :hover pegado en lo que
     acabas de tocar, se reaplicaba el translate y la lista se iba media
     anchura a la izquierda, fuera de la pantalla (medido: el primer enlace en
     left = −97px). */
  .nav__item--sub:hover .submenu,
  .nav__item--sub:focus-within .submenu,
  .submenu.is-abierto { transform: none; }

  /* La vista previa es un lujo de escritorio: en móvil el dedo no «pasa por
     encima», así que nunca cambiaría, y ocuparía media pantalla mostrando
     siempre el primer servicio. */
  .submenu__previa { display: none; }

  .submenu__lista {
    padding: 0;
    background: none;
    border-right: none;
  }
  /* Los servicios son lo que más se busca en el menú y eran la letra más
     pequeña de todo él. Van al mismo cuerpo que los apartados principales,
     con una raya delante que los marca como parte de «Servicios» y con
     sangría a la izquierda para que se lea la jerarquía de un vistazo.

     El icono se queda fuera en móvil: entre raya, icono y texto a 18px no
     cabe «Prefabricación de tubería» en una línea, y partir los nombres en
     dos se lee peor que perder el dibujo. En escritorio siguen estando. */
  .submenu__lista a {
    gap: 0;
    min-height: 52px;
    padding: var(--e-2) var(--e-2) var(--e-2) 0;
    font-size: var(--txt-lg);
    font-weight: 500;
    color: var(--texto);
  }
  .submenu__icono { display: none; }
  .submenu__lista a:hover,
  .submenu__lista a.is-activo { box-shadow: none; background: none; }

  .submenu__pie {
    /* Alineado con los servicios que tiene encima */
    padding: var(--e-3) var(--e-2) var(--e-3) 0;
    background: none;
  }
  .submenu__pie a { min-height: 44px; display: inline-flex; align-items: center; }

  /* --------------------------------------------------------------------
     PORTADA: el menú abierto es un panel BLANCO, no la cabecera transparente

     En la portada la cabecera va sobre la foto del hero, así que sus enlaces
     se pintan en blanco. Al abrir el menú por debajo de 980px, ese blanco se
     heredaba dentro del panel —que es blanco— y el menú salía en blanco sobre
     blanco: se veían las rayas separadoras y ni una palabra.

     Hay que repetir la cadena entera «.con-hero-overlay .header:not(.is-scroll)»
     para ganar: aquella regla pesa (0,4,0) y un media query no añade nada.
     Con «.nav.is-abierto» en medio queda en (0,5,0) y manda ésta.
     -------------------------------------------------------------------- */
  .con-hero-overlay .header:not(.is-scroll) .nav.is-abierto .nav__enlace {
    color: var(--texto);
    text-shadow: none;
  }
  .con-hero-overlay .header:not(.is-scroll) .nav.is-abierto .nav__enlace.is-activo {
    color: var(--azul);
  }
  .con-hero-overlay .header:not(.is-scroll) .nav.is-abierto .nav__desplegar {
    color: var(--texto);
  }
  .con-hero-overlay .header:not(.is-scroll) .nav.is-abierto .submenu__lista a {
    color: var(--texto);
  }
  .nav__enlace {
    padding: var(--e-4) var(--e-2);
    border-bottom: 1px solid var(--borde);
    font-size: var(--txt-lg);
  }
  .nav__enlace::after { display: none; }
  .nav__enlace.is-activo {
    border-left: 3px solid var(--azul);
    padding-left: var(--e-4);
  }

  .nav__contacto-movil {
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
    margin-top: var(--e-5);
  }
  .nav__contacto-movil a {
    padding: var(--e-3);
    border-radius: var(--r-md);
    background: var(--azul);
    color: var(--blanco);
    font-family: var(--fuente-titulo);
    font-size: var(--txt-lg);
    font-weight: 600;
    text-align: center;
    letter-spacing: 0.04em;
  }
  .nav__contacto-movil a:hover { background: var(--azul-claro); color: var(--blanco); }
}

/* --------------------------------------------------------------------------
   10. Pie
   -------------------------------------------------------------------------- */
.footer {
  padding-top: var(--e-9);
  /* Foco de luz frío en la esquina superior, sobre el azul oscuro sólido: el
     pie es el campo azul más grande del sitio y en plano se leía apagado. */
  background:
    radial-gradient(90% 120% at 82% -10%, rgba(2, 116, 190, 0.42) 0%, rgba(2, 116, 190, 0) 55%),
    var(--azul-oscuro);
  color: rgba(255, 255, 255, 0.78);
  font-size: var(--txt-sm);
}
.footer a { color: var(--azul-suave); }
.footer a:hover { color: var(--blanco); }
.footer .logo { margin-right: 0; }

.footer__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1.3fr 1.4fr;
  gap: var(--e-8) var(--e-6);
  padding-bottom: var(--e-8);
}
/* Los items de grid tienen min-width:auto: sin esto una columna no puede
   encoger por debajo del min-content de lo que lleva dentro. */
.footer__grid > * { min-width: 0; }

.footer__titulo {
  margin-bottom: var(--e-4);
  color: var(--blanco);
  font-size: var(--txt-base);
  letter-spacing: 0.12em;
}

.footer__claim { margin-top: var(--e-4); max-width: 34ch; }

.footer__lista { display: flex; flex-direction: column; gap: var(--e-2); }
.footer__lista--contacto { gap: var(--e-1); margin-bottom: var(--e-5); }
.footer__lista--contacto strong {
  font-family: var(--fuente-titulo);
  font-size: var(--txt-lg);
  letter-spacing: 0.03em;
}

.footer__filosofia-titulo {
  margin-top: var(--e-6);
  margin-bottom: var(--e-2);
  color: var(--blanco);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-xs);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.footer__filosofia {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
}
.footer__filosofia li {
  padding: 0.2rem 0.7rem;
  border: 1px solid rgba(140, 189, 221, 0.4);
  border-radius: var(--r-full);
  font-size: var(--txt-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--azul-suave);
}

/* .footer__lema es flex: el texto suelto se convertiría en otro item y se
   partiría en una columna aparte. Por eso va envuelto en un span. */
.footer__lema {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  margin-top: var(--e-5);
  color: var(--blanco);
  font-weight: 600;
}

.footer__isos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  margin-top: var(--e-5);
}
.footer__isos li {
  padding: 0.3rem 0.75rem;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.08);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
}

.footer__sede {
  margin-bottom: var(--e-4);
  font-style: normal;
  line-height: 1.5;
}
.footer__sede-nombre {
  display: block;
  color: var(--blanco);
  font-family: var(--fuente-titulo);
  font-size: var(--txt-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.footer__legal {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--e-3);
  padding-block: var(--e-5);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--txt-xs);
}
.footer__legal-enlaces { display: flex; flex-wrap: wrap; gap: var(--e-4); }

@media (max-width: 900px) {
  .footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .footer__grid { grid-template-columns: 1fr; gap: var(--e-6); }
  .footer__legal { justify-content: center; text-align: center; }
}

/* --------------------------------------------------------------------------
   11. Botón flotante de llamada (sólo móvil)
   -------------------------------------------------------------------------- */
.fab-llamar {
  position: fixed;
  right: var(--e-4);
  bottom: var(--e-4);
  z-index: var(--z-fab);
  display: none;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-4) var(--e-5);
  border-radius: var(--r-full);
  background: var(--azul);
  color: var(--blanco);
  font-family: var(--fuente-titulo);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  box-shadow: var(--sombra-azul);
  transition: transform var(--t-media), opacity var(--t-media);
}
.fab-llamar svg { width: 20px; height: 20px; }
.fab-llamar:hover { color: var(--blanco); }
.fab-llamar.is-oculto {
  transform: translateY(120%);
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 768px) {
  .fab-llamar { display: inline-flex; }
}

/* --------------------------------------------------------------------------
   12. Cabecera de página interior
   -------------------------------------------------------------------------- */
.pagina-cabecera {
  padding-block: var(--e-9) var(--e-8);
  background: var(--deg-contraste);
  color: rgba(255, 255, 255, 0.88);
  --acento-linea: var(--azul-suave);
}
.pagina-cabecera h1 { color: var(--blanco); }
.pagina-cabecera__lead {
  max-width: var(--ancho-texto);
  margin-top: var(--e-4);
  font-size: var(--txt-lg);
  color: rgba(255, 255, 255, 0.85);
}
.pagina-cabecera .antetitulo { color: var(--azul-suave); }

/* --------------------------------------------------------------------------
   12 bis. Hero fotográfico — tres capas independientes
   Foto a sangre + velo azul oscuro + caja azul translúcida con el titular.

   Las tres capas son elementos separados a propósito: la foto entra y sale
   sin tocar el velo ni la caja. Si falta la <img>, la sección se queda con
   su degradado azul de fondo y sigue siendo legible: la foto es un extra,
   nunca un requisito.
   -------------------------------------------------------------------------- */
.hero-foto {
  position: absolute;
  /* Colchón arriba y abajo para el parallax (site.js mueve la foto): sin él,
     al desplazarse asomaría el borde. La sección lleva overflow:hidden. En la
     portada, .hero__carrusel .hero-foto vuelve a top:0/height:100% porque allí
     quien se mueve es el wrapper, no la foto. */
  top: -10%;
  left: 0;
  right: 0;
  z-index: -2;
  width: 100%;
  height: 120%;
  object-fit: cover;
  /* Las fotos industriales llegan con dominantes cálidas u ocres que pelean
     con el azul corporativo. Bajarles la saturación las lleva al terreno frío
     de la paleta, y oscurecerlas deja sitio al texto blanco de encima. */
  filter: saturate(0.45) contrast(1.06) brightness(0.78);
}

/* Sin el velo, el titular blanco se pierde en las zonas claras de la foto
   (cielos, chapa reflectante). Es lo que garantiza el contraste, no la caja. */
.hero-velo {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to bottom, rgba(3, 46, 78, 0.55) 0%, rgba(3, 46, 78, 0.35) 45%, rgba(3, 46, 78, 0.75) 100%),
    linear-gradient(to right, rgba(3, 46, 78, 0.6) 0%, transparent 65%);
}

/* La caja del titular. inline-block y no bloque: se ajusta al texto, que es
   lo que le da el aire de sello estampado sobre la foto.

   El azul va al 32% para que la foto se vea a través. Lo que salva el
   contraste del blanco no es la opacidad del azul, sino el backdrop-filter:
   oscurece y desatura lo que hay DETRÁS de la caja, así que da igual que ahí
   caiga un cielo claro o una chapa reflectante — el blanco siempre tiene un
   fondo oscuro debajo. Sin él, a este nivel de azul el titular sería ilegible
   sobre cualquier zona clara. */
/* Caja translúcida del titular en los heros interiores.

   Antes llevaba brightness(0.42), que oscurece al 42% TODO lo que hay detrás.
   Sumado al velo del hero y al filter de la propia foto, el resultado medido en
   pantalla era rgb(17,63,94): un azul prácticamente macizo. No se veía la foto
   a través, que es justo lo contrario de lo que debe hacer una caja translúcida.

   Y provocaba el salto que se apreciaba al cargar: la animación de entrada
   (int-entrada) sube la opacidad de 0 a 1 en 800ms, así que la caja empezaba
   transparente —porque todo estaba a medio aparecer— y terminaba en ese azul
   sólido. Parecía que cambiaba de estilo a mitad de carga.

   Ahora sólo desenfoca y satura un punto: la foto se ve a través de verdad.
   El contraste del titular lo sostienen el velo del hero y la sombra del texto
   (.hero-int__titulo en interior.css), no el oscurecido de la caja. */
.hero-caja {
  display: inline-block;
  max-width: 100%;
  padding: var(--e-3) var(--e-4);
  background: rgba(2, 116, 190, 0.16);
  backdrop-filter: blur(4px) saturate(1.15);
  -webkit-backdrop-filter: blur(4px) saturate(1.15);
  border-radius: var(--r-md);
  box-shadow: 0 10px 40px rgba(3, 46, 78, 0.28);
}

/* Sin backdrop-filter la caja se queda en un tinte plano. Se sube un poco la
   opacidad para que siga leyéndose como caja, pero sin llegar al azul macizo
   de antes: la legibilidad ya no depende de ella. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero-caja { background: rgba(2, 116, 190, 0.34); }
}
@media (min-width: 768px) {
  .hero-caja { padding: var(--e-4) var(--e-5); }
}

.hero-caja > :last-child { margin-bottom: 0; }

/* Filo de acento a la izquierda: ancla la caja y repite el gesto de la línea
   de acento que llevan los titulares de sección. */
.hero-caja--filo {
  border-left: 5px solid var(--azul-suave);
}

/* --------------------------------------------------------------------------
   13. Placeholders de imagen
   TODO: imagen real — sustituir por <img> cuando Fran aporte las fotos
   -------------------------------------------------------------------------- */
.placeholder-img {
  position: relative;
  background: var(--deg-contraste);
  overflow: hidden;
}
.placeholder-img::after {
  /* Rejilla técnica sutil */
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.09) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.09) 1px, transparent 1px);
  background-size: 26px 26px;
}
/* Foto real subida desde el panel. Va dentro del mismo contenedor que usaría
   el placeholder, para que los distintivos (año, «destacado») sigan encima. */
.foto-cubre {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Un tinte por categoría para que no parezcan todas la misma foto. Cada una
   toma como dominante un color distinto de la paleta, sin salirse de ella. */
.placeholder-img--paradas {
  background: linear-gradient(135deg, var(--azul) 0%, var(--azul-oscuro) 100%);
}
.placeholder-img--prefabricacion {
  background: linear-gradient(135deg, var(--azul-claro) 0%, var(--azul) 100%);
}
.placeholder-img--llave-en-mano {
  background: linear-gradient(135deg, var(--azul-suave) 0%, var(--azul-claro) 100%);
}
.placeholder-img--mantenimiento {
  background: linear-gradient(135deg, var(--azul-oscuro) 0%, var(--azul-claro) 100%);
}

/* --------------------------------------------------------------------------
   14. Estado de carga
   -------------------------------------------------------------------------- */
.cargando {
  padding: var(--e-8) 0;
  color: var(--texto-suave);
  text-align: center;
}
.cargando::after {
  content: '';
  display: inline-block;
  width: 14px; height: 14px;
  margin-left: var(--e-2);
  vertical-align: -2px;
  border: 2px solid var(--borde-fuerte);
  border-top-color: var(--azul);
  border-radius: 50%;
  animation: girar 700ms linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------------------
   15. Animaciones al aparecer
   -------------------------------------------------------------------------- */
/* El estado oculto de partida SÓLO se aplica si hay JavaScript: la clase «js»
   la pone un <script> inline en el <head> de cada página, antes de pintar. Sin
   JS (rastreadores, JS caído o desactivado) el .reveal nunca se esconde y el
   contenido se ve tal cual —igual que el JSON-LD, que está en el <head> por lo
   mismo—. Con JS, site.js le añade .is-visible al entrar en pantalla. */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--t-lenta), transform var(--t-lenta);
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal--d1 { transition-delay: 90ms; }
.reveal--d2 { transition-delay: 180ms; }
.reveal--d3 { transition-delay: 270ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  /* Misma especificidad que «.js .reveal» y posterior en el código: gana ésta,
     así que con reduced-motion el contenido aparece sin desplazamiento. */
  .js .reveal { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   16. Utilidades
   -------------------------------------------------------------------------- */
.flex { display: flex; }
.flex--centro { align-items: center; }
.flex--entre { justify-content: space-between; }
.flex--wrap { flex-wrap: wrap; gap: var(--e-4); }

.grid { display: grid; gap: var(--e-6); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid > * { min-width: 0; }

@media (max-width: 900px) {
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
}

.txt-centro { text-align: center; }
.txt-medida { max-width: var(--ancho-texto); }
.txt-azul { color: var(--azul); }
.txt-suave { color: var(--texto-suave); }

.mt-0 { margin-top: 0; }
.mt-2 { margin-top: var(--e-2); }
.mt-4 { margin-top: var(--e-4); }
.mt-5 { margin-top: var(--e-5); }
.mt-6 { margin-top: var(--e-6); }
.mt-8 { margin-top: var(--e-8); }
.mb-4 { margin-bottom: var(--e-4); }
.mb-6 { margin-bottom: var(--e-6); }

/* --------------------------------------------------------------------------
   17. Nota sobre el tema anterior

   La etapa anterior era oscura (grafito + naranja). Al reescribir esta hoja
   se migró también el color de las otras (interior, dinamicas, contacto,
   formularios): ninguna usa ya --naranja ni --grafito-*, así que esos nombres
   no existen y no hace falta ningún puente de compatibilidad.

   Si al tocar una hoja apareciera una var() de aquella etapa, el síntoma no
   es «se ve raro» sino que la propiedad se queda en su valor inicial (texto
   negro, bordes invisibles). En ese caso, traducir a la paleta de arriba.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Iconos de servicio (los SVG que entrega el cliente)

   Los ficheros de /img/iconos/ vienen en blanco macizo y sin fondo. Puestos
   con <img> sólo valdrían sobre fondo oscuro: en la caja azul clara de las
   páginas de servicio serían invisibles.

   Por eso van como MÁSCARA y no como imagen: el SVG recorta la silueta y el
   color lo pone background-color, que hereda de currentColor. Así el mismo
   fichero sale blanco sobre la insignia azul de la portada y azul sobre la
   caja clara de las interiores, sin duplicar ficheros ni tocar su código.

   Cada icono se elige con un modificador para que las rutas vivan aquí y no
   repartidas por el HTML.
   -------------------------------------------------------------------------- */
.icono-svg {
  display: block;
  width: 100%;
  height: 100%;
  background-color: currentColor;
  -webkit-mask: var(--icono) center / contain no-repeat;
          mask: var(--icono) center / contain no-repeat;
}

/* Sin soporte de máscara saldría un cuadrado de color macizo, que es peor que
   no ver nada. En ese caso se esconde: el nombre del servicio ya está al lado. */
@supports not ((-webkit-mask-image: url('#')) or (mask-image: url('#'))) {
  .icono-svg { display: none; }
}

/* IMPORTANTE: todo icono que se use en el HTML necesita su línea aquí. Si falta,
   var(--icono) queda sin valor, la propiedad mask entera se vuelve inválida y
   el elemento se pinta como un CUADRADO MACIZO del color de currentColor. No da
   error en consola: simplemente sale un cuadrado azul. */

/* Servicios */
.icono-svg--paradas        { --icono: url('/img/iconos/paradas.svg'); }
.icono-svg--mantenimiento  { --icono: url('/img/iconos/mantenimiento.svg'); }
.icono-svg--construccion   { --icono: url('/img/iconos/construccion.svg'); }
.icono-svg--prefabricacion { --icono: url('/img/iconos/prefabricacion.svg'); }
.icono-svg--reparacion     { --icono: url('/img/iconos/reparacion.svg'); }
.icono-svg--llave-en-mano  { --icono: url('/img/iconos/llave-en-mano.svg'); }

/* RRHH */
.icono-svg--incentivos       { --icono: url('/img/iconos/incentivos.svg'); }
.icono-svg--proyectos-espana { --icono: url('/img/iconos/proyectos-espana.svg'); }
.icono-svg--cero-accidentes  { --icono: url('/img/iconos/cero-accidentes.svg'); }
.icono-svg--formacion        { --icono: url('/img/iconos/formacion.svg'); }

/* Nosotros: habilitaciones */
.icono-svg--equipos-presion { --icono: url('/img/iconos/equipos-presion.svg'); }
.icono-svg--gas             { --icono: url('/img/iconos/gas.svg'); }
.icono-svg--frigorificas    { --icono: url('/img/iconos/frigorificas.svg'); }
.icono-svg--petroliferas    { --icono: url('/img/iconos/petroliferas.svg'); }
.icono-svg--pci             { --icono: url('/img/iconos/pci.svg'); }

/* Nosotros: misión y visión */
.icono-svg--mision { --icono: url('/img/iconos/mision.svg'); }
.icono-svg--vision { --icono: url('/img/iconos/vision.svg'); }

/* Contacto: las tres sedes. Estos SVG vienen rellenos de azul y no de blanco,
   pero da igual: la máscara sólo mira el canal alfa, no el color. */
.icono-svg--oficinas             { --icono: url('/img/iconos/oficinas.svg'); }
.icono-svg--almacen-taller       { --icono: url('/img/iconos/almacen-taller.svg'); }
.icono-svg--taller-prefabricados { --icono: url('/img/iconos/taller-prefabricados.svg'); }

/* Las cajas que los contienen daban tamaño al <svg> hijo. Ahora el hijo es un
   <span>, así que hay que decírselo también a él.

   Van al máximo que cabe sin rozar el borde. Las cuentas, porque box-sizing es
   border-box y el borde descuenta del ancho declarado:

     .servicio__icono     56px − 2×2px de borde = 52px libres → 44px (4px por lado)
     .bloque-serv__icono  60px − 2×1px de borde = 58px libres → 48px (5px por lado)

   Ese aire hace falta por las esquinas redondeadas: con radio interior de 8px,
   un icono que llenara los 52px tocaría la curva aunque no toque el lado recto.

   Medido antes de subirlos: los seis SVG ocupan entre el 94% y el 100% de su
   viewBox, así que igualar la caja los deja también iguales a la vista. Si algún
   icono nuevo trajera más margen interno, se vería más pequeño que el resto y
   habría que recortarle el viewBox, no agrandarle la caja. */
.servicio__icono .icono-svg    { width: 44px; height: 44px; }
.bloque-serv__icono .icono-svg { width: 48px; height: 48px; }

/* Los demás sitios donde van iconos del cliente. Mismo criterio: el máximo que
   cabe descontando el borde, dejando 3-4px de aire por las esquinas curvas.
     .ventaja__icono    52px − 2×1 = 50 libres → 42
     .aut-card__icono   44px − 2×1 = 42 libres → 34
     .mv-card__marca    56px − 2×1 = 54 libres → 44
     .submenu__icono    34px − 2×1 = 32 libres → 26  (arriba, junto al submenú) */
.ventaja__icono .icono-svg  { width: 42px; height: 42px; }
.aut-card__icono .icono-svg { width: 34px; height: 34px; }
.mv-card__marca .icono-svg  { width: 44px; height: 44px; }

/* ==========================================================================
   AJUSTES DE MÓVIL
   Bloque al final a propósito: son correcciones sobre reglas de escritorio ya
   escritas y necesitan ganar por orden, no por !important.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tablas anchas
   Una tabla de cuatro columnas no cabe en 390px. En vez de encogerla hasta que
   no se lea, se le deja desplazamiento propio. El tabindex="0" del envoltorio
   es necesario para que también se pueda desplazar con el teclado.
   -------------------------------------------------------------------------- */
.tabla-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain; /* que no arrastre la página al llegar al final */
}
.tabla-scroll:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }
.tabla-scroll > table { min-width: 34rem; } /* por debajo de esto las celdas se vuelven ilegibles */

@media (max-width: 768px) {
  /* Aviso de que hay más tabla a la derecha: sin esto no se adivina */
  .tabla-scroll { position: relative; }
  .tabla-scroll::after {
    content: 'Desliza para ver el resto de la tabla →';
    display: block;
    padding-top: var(--e-2);
    font-size: var(--txt-xs);
    color: var(--texto-suave);
  }
}

/* --------------------------------------------------------------------------
   Objetivos táctiles
   La guía es 44x44px reales. Se consigue con padding vertical y un área
   pinchable mínima, no agrandando la letra.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* Enlaces del pie: iban a 17-20px de alto, imposibles de acertar con el dedo */
  .footer__lista a,
  .footer__legal a {
    display: inline-block;
    padding-block: 0.55rem;
  }

  /* Enlaces con flecha dentro del contenido */
  .enlace-flecha {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* El logo es el enlace a inicio y medía 34px de alto. No se agranda el
     dibujo: se le da altura al enlace y se centra dentro. */
  .logo {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Migas de pan: son enlaces de 20px seguidos de un separador, así que
     tampoco se les puede dar alto sin descuadrar la línea. */
  .miga a {
    display: inline-block;
    padding-block: 0.6rem;
  }

  /* Enlaces sueltos dentro de texto largo (teléfonos, correos, políticas):
     no se les puede dar 44px de alto sin romper el interlineado del párrafo,
     así que se amplía sólo el área pinchable con un pseudoelemento. */
  .prosa a,
  .sede__datos a,
  .formulario__aviso a {
    position: relative;
  }
  .prosa a::after,
  .sede__datos a::after,
  .formulario__aviso a::after {
    content: '';
    position: absolute;
    inset: -0.7rem -0.3rem;
    /* Sólo amplía el área de pulsación; no se ve nada */
  }
}

/* --------------------------------------------------------------------------
   17. Barra «Volver al formulario»
   Sale en la política de privacidad cuando se llega desde un formulario
   (?volver=/…). Fija abajo para no pelear con la cabecera sticky.
   -------------------------------------------------------------------------- */
.volver-form {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-fab);
  background: var(--deg-contraste);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  box-shadow: 0 -6px 20px rgba(3, 46, 78, 0.28);
}
.volver-form__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--e-3) var(--e-5);
  padding-block: var(--e-3);
}
.volver-form__texto {
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--txt-sm);
  font-weight: 500;
}
/* Botón blanco sobre el azul de la barra: el primario azul no se vería */
.volver-form__btn {
  flex-shrink: 0;
  background: var(--blanco);
  border-color: var(--blanco);
  color: var(--azul-oscuro);
}
.volver-form__btn:hover {
  background: var(--azul-suave);
  border-color: var(--azul-suave);
  color: var(--azul-oscuro);
  transform: translateY(-2px);
}
/* Deja aire al final para que la barra no tape el pie */
.con-volver-form { padding-bottom: 84px; }
