/* =====================================================================
   CARGA Y TRANSPORTES OMEGA, S.A. DE C.V.
   Estilo: industrial y geométrico — hexágonos, cortes diagonales.
   Paleta e tipografía de marca (permanentes):
     #373333 (carbón) · #59b3a6 (verde agua) · #124c7a (azul petróleo)
     Libre Baskerville — Light para texto, Bold para títulos.
   ===================================================================== */

:root {
    /* Paleta de marca */
    --azul:         #124c7a;  /* azul petróleo — acento de la división Construcción */
    --azul-claro:   #1E6FA8;  /* azul de apoyo para hover/acentos sobre oscuro */
    --azul-oscuro:  #0C3557;
    --verde:        #59b3a6;  /* verde agua — acento de la división Transporte */
    --verde-oscuro: #2F6B61;  /* sombra del verde con contraste AA sobre las secciones claras translúcidas */
    --verde-claro:  #7DC6BB;  /* verde de apoyo para hover */
    --negro:        #242121;  /* fondo oscuro principal (a partir de #373333) */
    --carbon:       #3E3A3A;  /* paneles sobre fondo oscuro */
    --blanco:       #FFFFFF;
    --azul-tinte:   #8FB8D8;  /* tinte claro del azul: cifras, números y enlaces de Construcción sobre oscuro */
    --gris:         #C2BBBB;  /* texto secundario sobre oscuro (aclarado: los fondos oscuros son translúcidos) */
    --gris-calido:  #7a7171;  /* tinte más claro y cálido del carbón — arranque del patrón diagonal */
    --tinta:        #373333;  /* texto principal sobre claro; también el "carbón" con el que cierra el patrón diagonal */
    --gris-medio:   #5A5353;  /* texto secundario sobre claro (oscurecido: los fondos claros son translúcidos) */
    --fondo-claro:  #F5F3F2;
    --linea-clara:  #E2DEDD;

    /* Capas translúcidas: dejan ver el patrón diagonal del fondo (body::before).
       Las opacidades están calculadas para que el texto conserve contraste AA
       incluso donde el patrón es más oscuro (secciones claras) o más claro
       (secciones oscuras). */
    --claro-translucido:  rgba(245, 243, 242, 0.82);  /* secciones claras */
    --panel-translucido:  rgba(255, 255, 255, 0.72);  /* tarjetas y formulario sobre claro */
    --oscuro-translucido: rgba(36, 33, 33, 0.80);     /* secciones oscuras y hero */
    --carbon-translucido: rgba(78, 72, 72, 0.60);     /* tarjetas sobre oscuro */
    --borde-claro:        rgba(55, 51, 51, 0.10);     /* bordes de tarjetas claras */
    --borde-oscuro:       rgba(255, 255, 255, 0.10);  /* bordes de tarjetas oscuras */
    --footer-fondo:       rgba(28, 26, 26, 0.84);     /* pie de página */
    --menu-fondo-clara:   rgba(245, 243, 242, 0.55);  /* velo del menú sobre una sección clara: translúcido, no sólido */
    --menu-fondo-oscura:  rgba(36, 33, 33, 0.55);     /* velo del menú sobre una sección oscura (o por omisión) */

    /* Tipografía de marca */
    --font-display: 'Libre Baskerville', Georgia, serif; /* títulos — bold */
    --font-body:    'Libre Baskerville', Georgia, serif; /* texto — light */

    /* Geometría */
    --corte: 14px;                       /* tamaño del corte angular de botones */
    --corte-diag: 3.2vw;                 /* altura del corte diagonal entre secciones (se redondea a píxel más abajo) */
    --hex-clip: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
    --ancho-max: 1200px;
}

/* El corte se redondea a píxel entero para que las tres capas de fondo de las
   secciones cortadas encajen sin costura subpíxel. round() es reciente
   (Chrome 125, Safari 15.4, Firefox 118): en navegadores sin soporte queda el
   valor fraccionario, que funciona igual salvo por una posible línea tenue. */
@supports (width: round(1px, 1px)) {
    :root { --corte-diag: round(3.2vw, 1px); }
}

/* Sin round() el corte se fija en píxeles enteros (pierde la fluidez, no la costura). */
@supports not (width: round(1px, 1px)) {
    :root { --corte-diag: 46px; }
}

/* ---------- Reset básico ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font-body);
    font-weight: 400; /* peso más ligero disponible de Libre Baskerville ("light") */
    font-size: 1rem;
    line-height: 1.65;
    color: var(--tinta);
    background-color: var(--negro);
    overflow-x: hidden;
}

/* ---------- Patrón diagonal de fondo ----------
   Una sola capa FIJA al viewport, detrás de todo el contenido, con el
   degradado de marca en diagonal: gris cálido → verde agua → azul → carbón,
   más la trama de hexágonos. Como está fija, el header (también fijo) y las
   secciones que se desplazan por encima comparten exactamente el mismo
   patrón: por eso el menú puede ser transparente y fundirse con la página sin
   que se note dónde termina. Las secciones llevan fondos translúcidos para
   que el patrón se transparente en toda la página.
   Cuatro colores con un tramo sólido cada uno (15–20% del ancho) y una
   transición de 15–20% entre cada par: lo bastante ancha para que la
   diagonal se vea difuminada y no como una línea recta, pero sin diluir el
   color en tonos intermedios muy parecidos entre sí (el degradado anterior
   tenía nueve paradas y varias eran variaciones de gris muy próximas, lo que
   apagaba el conjunto). Con cuatro bloques anchos y bien diferenciados el
   patrón se nota mucho más. */
body::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 100vh;
    height: 100lvh;   /* móvil: cubre también la franja de la barra del navegador */
    z-index: -1;
    pointer-events: none;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='84' viewBox='0 0 96 84'%3E%3Cpath d='M25 2h46l23 40-23 40H25L2 42z' fill='none' stroke='%23FFFFFF' stroke-opacity='0.05' stroke-width='1.5'/%3E%3C/svg%3E"),
        linear-gradient(110deg,
            var(--gris-calido) 0%,
            var(--gris-calido) 20%,
            var(--verde) 40%,
            var(--verde) 55%,
            var(--azul) 70%,
            var(--azul) 85%,
            var(--tinta) 100%);
    background-size: 96px 84px, 100% 100%;
    background-repeat: repeat, no-repeat;
}

img { max-width: 100%; height: auto; display: block; }

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

ul, ol { list-style: none; }

/* Fuera de la pantalla pero presente: lo usa la trampa para robots del
   formulario de contacto. No se usa display:none a proposito, porque
   algunos bots lo detectan y saltan el campo. */
.oculto-visual {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ---------- Foco visible por teclado ----------
   El verde de marca mide 2.2:1 sobre las superficies claras translúcidas y
   no llega al 3:1 que pide el nivel AA, así que el color del anillo viaja
   en una custom property que cada tipo de fondo redefine: --verde-oscuro
   sobre lo claro, --verde-claro sobre lo oscuro. */
:root { --foco: var(--verde-oscuro); }
.seccion--oscura, .cta, .footer, .header { --foco: var(--verde-claro); }

:focus-visible {
    outline: 3px solid var(--foco);
    outline-offset: 2px;
}

::selection { background: var(--verde); color: var(--negro); }

/* ---------- Utilidades ---------- */
.contenedor {
    width: 100%;
    max-width: var(--ancho-max);
    margin-inline: auto;
    padding-inline: 20px;
}

/* Libre Baskerville es bastante más ancha que una condensada: palabras largas
   ("INFRAESTRUCTURA") pueden superar el ancho del contenedor en pantallas
   angostas y forzar desbordamiento horizontal. Permitimos partirlas. */
.titulo-seccion,
.division__titulo,
.servicio__titulo,
.paso__titulo,
.cta__titulo,
.footer__titulo,
.footer__lema,
.kicker {
    overflow-wrap: break-word;
}

/* Los datos de contacto son el otro caso sin puntos de corte naturales: un
   correo ("contacto@omega.mx", y antes el más largo
   "contacto@transportesomega.mx") puede no caber en la columna del pie ni en
   la ficha de contacto a anchos intermedios y empujaba la página hacia los
   lados. La red se deja puesta aunque el correo actual sea corto, porque el
   valor se edita en datos.php y el siguiente puede volver a ser largo.
   Aquí hace falta "anywhere" y no "break-word": ambos parten la
   palabra, pero sólo "anywhere" reduce además el tamaño mínimo intrínseco, y
   estas listas son rejillas cuyo ancho lo fija justamente ese mínimo — con
   "break-word" la columna seguiría midiendo lo que mide el correo entero. */
.footer__grid ul,
.contacto__datos,
.contacto__tarjetas {
    overflow-wrap: anywhere;
}

.txt-verde        { color: var(--verde); }
.txt-verde-oscuro { color: var(--verde-oscuro); }
.txt-azul         { color: var(--azul); }
.txt-azul-claro   { color: #6FA0C8; }  /* tinte del azul legible (3:1) sobre las secciones oscuras translúcidas */

/* .hex-fondo: la trama de hexágonos vive ahora en la capa fija body::before,
   así no se duplica (desalineada) sobre las secciones translúcidas. La clase
   sigue en el HTML por compatibilidad pero ya no tiene regla propia. */

/* ---------- Secciones ---------- */
.seccion {
    padding: 96px 0;
    scroll-margin-top: 92px;
}

/* Fondos translúcidos: el patrón diagonal de body::before se ve a través de
   todas las secciones, claras y oscuras. */
.seccion--clara {
    background-color: var(--claro-translucido);
    color: var(--tinta);
}

.seccion--oscura {
    background-color: var(--oscuro-translucido);
    color: var(--blanco);
}

/* ---------- Corte diagonal entre secciones ----------
   Dos técnicas según la sección sea translúcida u opaca:

   a) Secciones oscuras translúcidas (.seccion--oscura.seccion--corte): las
      cuñas se PINTAN dentro de la propia caja con tres capas de fondo (franja
      superior con degradado diagonal, cuerpo, franja inferior con degradado
      diagonal). El triángulo que "cede" cada franja lleva el color de la
      sección vecina (--cuna-arriba / --cuna-abajo), así la unión es continua
      sin que las cajas se monten: si se montaran (clip-path + margen
      negativo) las dos capas translúcidas se sumarían en la franja solapada y
      se vería una banda de otro tono, y si además se recortan ambas vecinas
      por la misma línea, el suavizado deja una línea fina. El degradado usa
      "to top right" (su línea del 50% une las esquinas superior-izquierda e
      inferior-derecha) con una transición de 1px para un borde suave.

   b) La banda CTA, que es opaca (foto + degradado), conserva el recorte
      clásico con clip-path y se monta sobre sus vecinas con margen negativo:
      al ser opaca no hay suma de capas y un solo borde recortado no deja
      costura. */
.seccion--oscura.seccion--corte {
    --cuna-arriba: var(--claro-translucido);   /* lo normal: sección clara antes */
    --cuna-abajo:  var(--claro-translucido);   /* y sección clara después */
    background-color: transparent;
    background-image:
        linear-gradient(to top right,
            var(--oscuro-translucido) calc(50% - 0.5px),
            var(--cuna-arriba)        calc(50% + 0.5px)),
        linear-gradient(to top right,
            var(--cuna-abajo)         calc(50% - 0.5px),
            var(--oscuro-translucido) calc(50% + 0.5px)),
        linear-gradient(var(--oscuro-translucido), var(--oscuro-translucido));
    background-size:
        100% var(--corte-diag),
        100% var(--corte-diag),
        100% calc(100% - 2 * var(--corte-diag));
    background-position: left top, left bottom, left var(--corte-diag);
    background-repeat: no-repeat;
}

/* Vecina anterior oscura (encabezado de página interior en servicios.php):
   la cuña superior toma su mismo color y la unión queda continua. */
.seccion--oscura + .seccion--oscura.seccion--corte { --cuna-arriba: var(--oscuro-translucido); }

/* Última sección de <main> seguida del pie (contacto.php): la cuña inferior
   toma el color del pie. */
main > .seccion--oscura.seccion--corte:last-child { --cuna-abajo: var(--footer-fondo); }

/* Seguida del CTA opaco (proceso.php): la cuña queda tapada, pero el
   suavizado del recorte del CTA dejaría asomar 1px de cuña clara; se pinta
   del color base del CTA. */
.seccion--oscura.seccion--corte:has(+ .cta) { --cuna-abajo: var(--negro); }

.cta.seccion--corte {
    position: relative;
    z-index: 1;
    clip-path: polygon(0 0, 100% var(--corte-diag), 100% 100%, 0 calc(100% - var(--corte-diag)));
    margin-block: calc(-1 * var(--corte-diag));
}

.encabezado-seccion {
    max-width: 720px;
    margin-bottom: 56px;
}

.encabezado-seccion__texto { color: var(--gris-medio); }
/* Subrayado obligatorio: son los unicos enlaces embebidos en prosa del
   sitio y el color solo no basta para distinguirlos (WCAG 1.4.1). */
.encabezado-seccion__texto a { text-decoration: underline; text-underline-offset: 0.18em; }
.seccion--oscura .encabezado-seccion__texto { color: var(--gris); }

.kicker {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

.kicker::before {
    content: "";
    width: 34px;
    height: 12px;
    clip-path: var(--hex-clip);
    flex-shrink: 0;
}

.kicker--verde { color: var(--verde-claro); }  /* tinte claro: AA sobre el fondo oscuro translúcido */
.kicker--verde::before { background: var(--verde); }
.kicker--azul { color: var(--azul); }
.kicker--azul::before { background: var(--azul); }

.titulo-seccion {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2.1rem, 4.5vw, 3.1rem);
    line-height: 1.06;
    text-transform: uppercase;
    letter-spacing: 0.015em;
    color: var(--tinta);
    margin-bottom: 18px;
}

.titulo-seccion--claro { color: var(--blanco); }

/* ---------- Botones angulares ---------- */
.btn {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 15px 34px;
    border: 0;
    cursor: pointer;
    clip-path: polygon(var(--corte) 0, 100% 0, 100% calc(100% - var(--corte)), calc(100% - var(--corte)) 100%, 0 100%, 0 var(--corte));
    transition: background-color .2s ease, color .2s ease, transform .15s ease;
    text-align: center;
}

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--verde { background: var(--verde); color: var(--negro); }
.btn--verde:hover { background: var(--verde-claro); color: var(--negro); }

.btn--azul { background: var(--azul); color: var(--blanco); }
.btn--azul:hover { background: var(--azul-claro); color: var(--blanco); }

.btn--linea {
    background: transparent;
    color: var(--blanco);
    box-shadow: inset 0 0 0 2px var(--verde);
}
.btn--linea:hover { background: rgba(89, 179, 166, 0.12); color: var(--verde); }

.btn--grande { font-size: 1.3rem; padding: 18px 44px; }
.btn--chico  { font-size: 1rem; padding: 10px 22px; }

/* ---------- Foco por teclado en los botones ----------
   El clip-path de .btn recorta dos esquinas, y recorta con ellas TODO lo
   que se pinte fuera de la caja: con outline-offset: 2px el anillo caía
   entero fuera del polígono y no se dibujaba ni un píxel en ninguno de los
   botones del sitio, incluido el de enviar el formulario. Por eso aquí el
   anillo tiene que ser interior (inset), no exterior.
   .btn--linea necesita regla propia porque ya usa box-shadow como borde y
   una sombra nueva lo sustituiría. */
.btn:focus-visible        { outline: none; }
.btn--azul:focus-visible  { box-shadow: inset 0 0 0 3px var(--blanco); }
.btn--verde:focus-visible { box-shadow: inset 0 0 0 3px var(--negro); }
.btn--linea:focus-visible { box-shadow: inset 0 0 0 2px var(--verde), inset 0 0 0 5px var(--blanco); }

/* ---------- Etiquetas de división ---------- */
/* ---------- Header ----------
   El header es transparente: deja ver el patrón diagonal fijo de body::before
   (gris cálido → verde agua → azul → carbón), el mismo que se transparenta en
   las secciones, así que no hay una franja de otro color ni una línea que
   marque dónde termina el menú. Dos pseudo-elementos, prolongados 10px por
   debajo de la barra (justo lo que hace falta para que el desvanecido no
   termine EN el borde de la barra) y con una máscara que se desvanece de
   arriba hacia abajo, resuelven la legibilidad:
   ::before → desenfoque (backdrop-filter) de lo que pasa por debajo.
   ::after  → un velo SIEMPRE translúcido (nunca un color sólido) que va
              cambiando de claro a oscuro según qué sección está pasando en
              ese momento justo bajo la barra: main.js mide en cada scroll
              qué bloque de <main> (o el pie) cae bajo el header y marca
              header[data-tono="clara"|"oscura"] — así el menú "compagina"
              con cada sección en vez de fijarse en un único color.
   Ninguno de los dos pinta una zona distinta bajo el logotipo: el rótulo se
   resuelve cambiando entre su versión blanca y la de tinta según ese mismo
   data-tono (ver .header .marca__logo), no con una placa ni con un
   rectángulo claro detrás. */
.header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 100;
    background: transparent;
    border-bottom: 0;
}

.header::before,
.header::after {
    content: "";
    position: absolute;
    inset: 0 0 -10px 0;
    z-index: -1;
    pointer-events: none;
    /* La zona difuminada queda del tamaño de la barra y su logotipo (86px:
       76px de barra + 10px de margen), no del doble como antes (116px). Pleno
       hasta ~65px, un poco más abajo de donde termina el logotipo (~66px a
       168px de ancho), y apagado del todo a los 86px: la caída mide 21px en
       vez de 58px, así que el efecto no se nota más allá del propio menú.
       Cuatro paradas y no dos: una rampa lineal llega al final con pendiente
       distinta de cero y el ojo lee ese quiebre como una raya tenue de lado a
       lado (banda de Mach) — justo la línea de división que no debe existir.
       Con las paradas intermedias la opacidad y su pendiente llegan las dos a
       cero y el borde inferior se disuelve del todo. */
    -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 75%, rgba(0, 0, 0, 0.6) 87%, rgba(0, 0, 0, 0.2) 95%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0, #000 75%, rgba(0, 0, 0, 0.6) 87%, rgba(0, 0, 0, 0.2) 95%, transparent 100%);
}

/* Desenfoque puro: no pinta ningún color propio, sólo difumina el patrón y el
   contenido que pasan por debajo. Es lo único que actúa en lo alto de la
   página, así que ahí el menú no tiene ni color ni línea que lo separe del
   hero: literalmente es la misma imagen, desenfocada. */
/* El desenfoque va condicionado a que el navegador sepa enmascarar: sin
   máscara, un backdrop-filter recortado a la caja deja un rectángulo
   desenfocado con un corte recto a 86px de alto — una división mucho más
   visible que la que se quiere evitar. Donde no hay máscara, mejor sin
   desenfoque: el menú se apoya entonces sólo en el velo de ::after. */
@supports ((-webkit-mask-image: linear-gradient(#000, transparent)) or (mask-image: linear-gradient(#000, transparent))) {
    .header::before {
        -webkit-backdrop-filter: blur(14px);
        backdrop-filter: blur(14px);
    }
}

/* Velo SIEMPRE translúcido (0.55 de opacidad, nunca sólido) de lado a lado
   —uniforme, sin degradado horizontal: cualquier cambio de tono a lo ancho
   de la barra vuelve a dibujar una "zona del logotipo" y una "zona del
   menú", que es justo la división que se quiere evitar—. No se apaga nunca
   (por eso no hay opacity:0/1 aquí: el que cambia es el color de fondo, no
   su presencia), así que sobre el hero oscuro de lo alto de la página se ve
   igual de discreto que antes, pero deja de depender de un umbral de
   scroll: basta con que main.js detecte una sección distinta bajo la barra.
   Por omisión usa el tono oscuro (correcto para el hero, los encabezados de
   página, el CTA y el pie, que son oscuros); header[data-tono="clara"] lo
   cambia al claro en cuanto una .seccion--clara pasa por debajo. */
.header::after {
    background: var(--menu-fondo-oscura);
    transition: background-color .3s ease;
}

.header[data-tono="clara"]::after {
    background: var(--menu-fondo-clara);
}

/* Blanco y verde agua leen bien sobre el velo oscuro (el fondo real detrás
   —hero, encabezados, CTA, pie— también lo es), pero sobre el velo claro su
   contraste cae a ~1.5:1 — prácticamente invisibles. Con
   header[data-tono="clara"] el menú se invierte a tinta oscura y azul, que
   sí ofrecen contraste (>5:1) sobre ese mismo claro. Estas reglas llegan
   tanto a los enlaces de la barra como a los del panel móvil, porque
   .nav__enlace vive dentro de .header en los dos casos. */
.header[data-tono="clara"] .nav__enlace {
    color: var(--tinta);
}

.header[data-tono="clara"] .nav__enlace::after {
    background: var(--azul);
}

.header[data-tono="clara"] .nav__enlace:hover,
.header[data-tono="clara"] .nav__enlace--activo {
    color: var(--azul);
}

.header[data-tono="clara"] .nav-toggle {
    border-color: var(--azul);
}

.header[data-tono="clara"] .nav-toggle span {
    background: var(--azul);
}

.header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    min-height: 76px;
}

/* flex-shrink: 0 — el logotipo nunca se comprime por culpa del nav */
.marca { display: inline-flex; align-items: center; flex-shrink: 0; }

.marca__placa {
    display: inline-block;
    flex-shrink: 0;
    background: var(--blanco);
    padding: 7px 12px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%);
}

/* En el header el logotipo va suelto, sin placa y sin ninguna zona clara
   detrás: el contraste lo da la propia tinta del rótulo, cambiando de versión
   según lo que pase por debajo. Antes había una sola versión —el rótulo casi
   negro— y su legibilidad sobre las secciones oscuras se resolvía con un halo
   blanco de drop-shadow(); con las dos variantes reales ese apaño sobra, y
   quitarlo deja el logotipo con su trazo limpio.

   Las dos van superpuestas en la misma celda de rejilla (grid-area 1/1) en vez
   de alternar display:none, para que puedan cruzarse por opacidad al mismo
   ritmo que el velo de la barra y los enlaces; con display no habría nada que
   animar y el cambio saldría a saltos en mitad del desplazamiento. */
.header .marca__placa {
    background: none;
    border: none;
    padding: 0;
    clip-path: none;
    display: grid;
}

.header .marca__logo {
    grid-area: 1 / 1;
    transition: opacity .3s ease;
}

/* Por omisión manda la blanca: el hero, los encabezados de página, el CTA y
   el pie son oscuros, y main.js sólo marca data-tono="clara" cuando una
   sección clara cruza la barra. Así lo alto de cada página ya sale bien
   incluso antes de que el script llegue a correr. */
.header .marca__logo--tinta { opacity: 0; }
.header[data-tono="clara"] .marca__logo--blanco { opacity: 0; }
.header[data-tono="clara"] .marca__logo--tinta { opacity: 1; }

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

.marca__placa img { width: 168px; height: auto; }

.nav__lista {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Tamaño y espaciado ajustados a Libre Baskerville, más ancha que una
   condensada: así los 6 enlaces y el CTA caben sin comprimir el logotipo. */
.nav__enlace {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.86rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--blanco);
    padding: 10px 9px;
    position: relative;
}

.nav__enlace::after {
    content: "";
    position: absolute;
    left: 9px;
    right: 9px;
    bottom: 4px;
    height: 3px;
    background: var(--verde);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .2s ease;
}

.nav__enlace:hover { color: var(--verde-claro); }
.nav__enlace:hover::after { transform: scaleX(1); }

/* Enlace de la página en curso (lo marca includes/header.php) */
.nav__enlace--activo { color: var(--verde-claro); }
.nav__enlace--activo::after { transform: scaleX(1); }

.nav__cta-item { margin-left: 10px; }
.nav__cta-item .btn { white-space: nowrap; font-size: 0.86rem; padding: 10px 18px; }

/* Botón hamburguesa */
.nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    width: 48px;
    height: 48px;
    padding: 10px;
    background: transparent;
    border: 2px solid var(--verde);
    cursor: pointer;
}

.nav-toggle span {
    display: block;
    height: 3px;
    width: 100%;
    background: var(--verde);
    transition: transform .25s ease, opacity .2s ease;
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

/* ---------- Fondo fotográfico de sección ----------
   Capa de foto a sangre completa para el hero de la portada y los
   encabezados de páginas interiores. La foto es opaca (tapa el patrón fijo
   del body en esa franja) y lleva encima un velo diagonal a 110deg —el
   mismo ángulo Y el mismo orden que el patrón fijo (gris cálido → verde
   agua → azul → carbón), con las mismas posiciones de parada (0/20%,
   40/55%, 70/85%, 100%) para que la transición entre la foto de cabecera y
   la sección translúcida que viene justo debajo sea consistente en toda la
   página. Los cuatro tonos van oscurecidos frente a los que usa el patrón:
   el título (blanco) y el texto introductorio (--gris) se apoyan en
   .pagina-hero__inner, que ocupa más o menos el 55–65% izquierdo del
   contenedor, así que el velo tiene que seguir siendo oscuro ahí aunque el
   patrón, en ese mismo tramo, use ahora un gris cálido y un verde agua
   bastante más claros — el gris cálido puro, por ejemplo, ni siquiera
   opaco al 100% pasa de 2.5:1 de contraste contra el texto introductorio
   (--gris), muy por debajo del 4.5:1 que pide un párrafo. Con estos tonos
   oscurecidos el texto conserva un contraste holgado (>5:1) en cualquier
   punto del encabezado. El header transparente difumina la foto en su franja
   superior, así que la fusión barra/página se conserva. El <img> usa
   srcset (960/1920) y va marcado aria-hidden desde el HTML: es decorativo. */
.seccion-fondo {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.seccion-fondo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Duotono suave: unifica fotos de origen distinto bajo el mismo velo */
    filter: grayscale(0.2) contrast(1.03) brightness(0.92);
}

.seccion-fondo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg,
        rgba(52, 47, 47, 0.90) 0%,
        rgba(52, 47, 47, 0.90) 20%,
        rgba(35, 70, 64, 0.85) 40%,
        rgba(35, 70, 64, 0.85) 55%,
        rgba(14, 61, 98, 0.70) 70%,
        rgba(14, 61, 98, 0.70) 85%,
        rgba(55, 51, 51, 0.55) 100%);
}

/* ---------- Hero ---------- */
/* ---------- Encabezado de páginas interiores ----------
   Banda oscura compacta que usan nosotros/servicios/proceso/contacto en
   lugar del hero grande. El padding superior deja libre el header fijo
   (76px). Ver includes/pagina-hero.php */
.pagina-hero {
    position: relative;
    padding: 150px 0 72px;
    overflow: hidden;
}

.pagina-hero__inner {
    position: relative;
    z-index: 1; /* por encima de .seccion-fondo */
    max-width: 820px;
}

.pagina-hero__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.55rem, 3.6vw, 2.6rem);
    line-height: 1.12;
    text-transform: uppercase;
    color: var(--blanco);
    margin-bottom: 18px;
    overflow-wrap: break-word;
}

.pagina-hero__texto {
    color: #F2F0F0;
    font-size: 1.06rem;
    max-width: 620px;
}

/* En servicios el titular es un solo enunciado corto, así que el encabezado
   gana cuerpo: tipografía mayor y columna de texto más ancha. */
#servicios .pagina-hero { padding: 165px 0 88px; }
#servicios .pagina-hero__inner { max-width: 900px; }

#servicios .pagina-hero__titulo {
    font-size: clamp(1.75rem, 4.4vw, 3.1rem);
    margin-bottom: 22px;
}

#servicios .pagina-hero__texto {
    font-size: 1.19rem;
    max-width: 700px;
    line-height: 1.7;
}

/* ---------- Contraste del texto sobre las fotos de los encabezados ----------
   El velo se calibró para el título en blanco, pero las palabras de acento
   y el antetítulo se quedaron fuera de ese cálculo: medidos sobre la foto
   compuesta bajaban a 1.86:1 ("MOVEMOS" en servicios) y a 2.40:1
   ("PROYECTO" en contacto), muy por debajo del 3:1 que pide el nivel AA
   para texto grande. Los tintes de abajo se midieron uno a uno contra el
   peor píxel de cada encabezado, en móvil (390px), que es el peor caso:
   ahí el texto cruza toda la diagonal, no sólo su tramo izquierdo.
   Estos selectores NO alcanzan los h2 sobre las secciones translúcidas,
   que ya cumplen con los colores de marca. */
.pagina-hero .kicker--verde,
.hero .kicker--verde { color: #9FDCD2; }

.pagina-hero__titulo .txt-verde,
.hero__titulo .txt-verde { color: #9FDCD2; }

.pagina-hero__titulo .txt-azul-claro,
.hero__titulo .txt-azul-claro { color: #B4D3EA; }

/* La causa de fondo no son las bandas del velo sino los detalles claros de
   la propia foto, así que se oscurece la foto, igual que ya hace la portada
   con brightness(0.68). */
.pagina-hero .seccion-fondo img { filter: grayscale(0.2) contrast(1.03) brightness(0.78); }

.hero {
    position: relative;
    padding: 170px 0 110px;
    min-height: 92vh;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.hero__grid {
    position: relative;
    z-index: 1; /* por encima de .seccion-fondo */
    display: grid;
    /* Reparto medido al píxel: a 1131px de ventana (el escritorio más
       angosto) "INFRAESTRUCTURA." necesita ~551px y esta pista de texto le
       deja ~586px; la segunda pista sólo reserva el aire donde emerge el
       panel de foto (.hero__foto, absoluto sobre el section). Si se le
       quita ancho a la pista de texto, la palabra se parte a media línea
       antes de romper nada más: medir antes de tocar. */
    grid-template-columns: minmax(0, 1.13fr) minmax(0, 0.87fr);
    gap: 24px;
    align-items: center;
}

.hero__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    /* El mínimo (1.65rem) está calculado para que "INFRAESTRUCTURA" quepa
       completa a 375px sin partirse a media palabra; la pendiente (4.05vw)
       para que quepa con holgura entre 1000 y 1200px con la pista de texto
       reducida a favor del panal. */
    font-size: clamp(1.65rem, 3.95vw, 3rem);
    line-height: 1.08;
    text-transform: uppercase;
    color: var(--blanco);
    margin-bottom: 22px;
    overflow-wrap: break-word;
}

.hero__texto {
    color: #F2F0F0;
    font-size: 1.06rem;
    max-width: 560px;
    margin-bottom: 32px;
}

.hero__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 34px;
}

/* ---------- Foto principal del hero ----------
   Panel a sangre por la derecha que se difumina en diagonal — el mismo
   ángulo (110deg) del patrón del sitio: una máscara desvanece sus dos
   costados, apenas por la izquierda y por completo hacia la derecha, para
   que la foto emerja del fondo sin ningún borde recto. Encima, ::after
   repone el degradado de los CUATRO colores del patrón (gris cálido →
   verde agua → azul → carbón, mismas paradas que body::before) fundido en
   modo overlay: tiñe sombras y medios tonos sin apagar las luces. El
   camión queda en la zona más nítida (izquierda del panel) y el sol cae
   dentro del difuminado derecho. */
.hero__foto {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 58%;
    /* Aísla la fusión del ::after: los 4 colores se funden SOLO con la
       foto, nunca con el fondo que asoma detrás del panel */
    isolation: isolate;
    /* GEOMETRÍA DE LA MÁSCARA: en un degradado inclinado la posición
       avanza también al BAJAR, así que el borde izquierdo del panel no
       está todo en la posición 0: su esquina inferior llega hasta
       drift/L (con 100deg y el panel más angosto —~901px de ventana—
       ronda el 21%). La parada transparente (23%) debe cubrir ese máximo
       o la foto aparece opaca pegada al borde y se ve una LÍNEA vertical
       (defecto que el usuario marcó). Si se cambia el ángulo o el ancho
       del panel, recalcular: drift = cos(ángulo−90°)... × alto. */
    -webkit-mask-image: linear-gradient(100deg, transparent 23%, #000 40%, #000 88%, transparent 100%);
    mask-image: linear-gradient(100deg, transparent 23%, #000 40%, #000 88%, transparent 100%);
}

.hero__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Ancla el recorte a la izquierda: deja al camión dentro de la zona
       opaca de la máscara y manda el sol al tramo que se disuelve */
    object-position: left center;
    /* Más luz y color que el resto de las fotos: este panel debe RESALTAR
       sobre el fondo de flota, que además se oscurece abajo */
    filter: contrast(1.07) brightness(1.07);
}

/* Filtro de los cuatro colores del patrón sobre la foto, en modo overlay:
   a diferencia de un velo translúcido normal (que actúa como niebla y
   hundía la foto "al fondo"), overlay multiplica las sombras hacia el
   color y aviva los medios tonos, así que el tinte SE VE y la foto no
   pierde luz ni contraste. Por eso las opacidades pueden ser altas sin
   opacar. La foto necesita este filtro propio porque flota POR ENCIMA
   del velo de 4 colores del fondo (.seccion-fondo::after) y no lo hereda. */
.hero__foto::after {
    content: "";
    position: absolute;
    inset: 0;
    mix-blend-mode: overlay;
    background: linear-gradient(110deg,
        rgba(122, 113, 113, 0.75) 0%,
        rgba(122, 113, 113, 0.75) 20%,
        rgba(89, 179, 166, 0.75) 40%,
        rgba(89, 179, 166, 0.75) 55%,
        rgba(18, 76, 122, 0.8) 70%,
        rgba(18, 76, 122, 0.8) 85%,
        rgba(55, 51, 51, 0.8) 100%);
}

/* Sólo en la portada: el fondo de la flota baja de luz para ceder el
   protagonismo al panel del camión (contraste = resalte) */
#inicio .hero .seccion-fondo img {
    filter: grayscale(0.25) contrast(1.02) brightness(0.68);
}

/* ---------- Nosotros ---------- */
.nosotros__grid {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: 64px;
    align-items: center;
}

.nosotros__media { position: relative; }

.nosotros__contenido p { margin-bottom: 16px; color: var(--gris-medio); }

.nosotros__contenido .btn { margin-top: 26px; }

/* Tratamiento duotono de imágenes genéricas */
.img-duo { position: relative; overflow: hidden; }

.img-duo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Duotono suavizado: unifica fotos de origen distinto con la paleta */
    filter: grayscale(0.15) contrast(1.04) brightness(0.97);
}

.img-duo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(160deg, rgba(18, 76, 122, 0.42), rgba(36, 33, 33, 0.12) 60%, rgba(89, 179, 166, 0.3));
    mix-blend-mode: multiply;
    pointer-events: none;
}

.img-duo--corte {
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 56px), calc(100% - 56px) 100%, 0 100%);
}

.nosotros__sello {
    position: absolute;
    right: -18px;
    bottom: 34px;
    background: var(--negro);
    color: var(--blanco);
    padding: 18px 26px;
    clip-path: polygon(12px 0, 100% 0, 100% 100%, 0 100%, 0 12px);
    display: grid;
    gap: 2px;
    box-shadow: 0 14px 30px rgba(36, 33, 33, 0.35);
}

.nosotros__sello-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 2.4rem;
    line-height: 1;
    color: var(--verde);
}

.nosotros__sello-txt {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-size: 0.95rem;
    color: var(--gris);
}

.lista-check { display: grid; gap: 12px; margin-top: 10px; }

.lista-check li {
    position: relative;
    padding-left: 34px;
    color: var(--tinta);
    font-weight: 500;
}

.lista-check li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 5px;
    width: 18px;
    height: 16px;
    clip-path: var(--hex-clip);
    background: var(--verde);
}

.lista-check li::after {
    content: "";
    position: absolute;
    left: 5px;
    top: 9px;
    width: 8px;
    height: 5px;
    border-left: 2px solid var(--negro);
    border-bottom: 2px solid var(--negro);
    transform: rotate(-45deg);
}

/* ---------- Divisiones ---------- */
.divisiones__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px;
}

.division {
    background: var(--carbon-translucido);
    border: 1px solid var(--borde-oscuro);
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%);
    display: flex;
    flex-direction: column;
    transition: transform .25s ease, border-color .25s ease;
}

/* Los enlaces del pie (servicios.php#division-…) aterrizan en el <article>,
   no en una .seccion: sin este margen de scroll el header fijo taparía el
   arranque de la tarjeta al llegar desde otra página. */
.division[id] { scroll-margin-top: 100px; }

.division:hover { transform: translateY(-6px); }
.division--construccion:hover { border-color: var(--azul-claro); }
.division--transporte:hover   { border-color: var(--verde); }

.division__media { aspect-ratio: 1000 / 520; }

.division__media img { height: 100%; }

.division__num {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.5rem;
    line-height: 1;
    padding: 12px 18px;
    background: var(--negro);
    color: var(--verde);
    clip-path: polygon(0 0, 100% 0, calc(100% - 14px) 100%, 0 100%);
}

.division--construccion .division__num { color: var(--azul-tinte); }

.division__cuerpo { padding: 30px 32px 36px; display: flex; flex-direction: column; flex: 1; }

.division__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    /* Fluido: a 375px "INFRAESTRUCTURA" cabe entera dentro de la tarjeta */
    font-size: clamp(1.35rem, 4.5vw, 1.9rem);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--blanco);
    margin-bottom: 12px;
    position: relative;
    padding-bottom: 14px;
}

.division__titulo::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 64px;
    height: 4px;
}

.division--construccion .division__titulo::after { background: var(--azul-claro); }
.division--transporte .division__titulo::after   { background: var(--verde); }

.division__resumen { color: var(--gris); margin-bottom: 20px; }

.division__lista { display: grid; gap: 10px; margin-bottom: 26px; }

.division__lista li {
    position: relative;
    padding-left: 26px;
    color: #D6D1D0;
    font-size: 0.97rem;
}

.division__lista li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 7px;
    width: 13px;
    height: 11px;
    clip-path: var(--hex-clip);
}

.division--construccion .division__lista li::before { background: var(--azul-claro); }
.division--transporte .division__lista li::before   { background: var(--verde); }

.division__enlace {
    margin-top: auto;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.1rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--verde-claro);
}

.division--construccion .division__enlace { color: var(--azul-tinte); }
.division__enlace:hover { color: var(--blanco); }

/* ---------- Divisiones ampliadas (servicios.php) ----------
   En la página de servicios cada división se tiende en horizontal: una
   columna de dos fotos apiladas y una columna de contenido, alternando el
   lado de las fotos en la segunda tarjeta para dar ritmo a la página. */
.divisiones--lista { display: grid; gap: 44px; }

.division--amplia {
    display: grid;
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
}

.division--amplia .division__media-col {
    position: relative;
    display: grid;
    grid-template-rows: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: 14px;
    min-height: 100%;
}

/* La segunda división alterna el lado de las fotos. El order mueve la
   columna de fotos a la derecha, y la plantilla se invierte junto con él:
   sin esa inversión, el texto caería en la pista angosta de las fotos. */
.division--amplia:nth-child(even) { grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr); }
.division--amplia:nth-child(even) .division__media-col { order: 2; }

.division--amplia .division__media {
    aspect-ratio: auto;
    height: 100%;
    min-height: 0;
}

.division--amplia .division__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Con dos fotos y texto largo, las capacidades caben en dos columnas */
.division--amplia .division__lista {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 24px;
}

.division--amplia .division__cuerpo { padding: 36px 40px 40px; }

/* ---------- Servicios ---------- */
.servicios__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 26px;
}

.servicio {
    background: var(--panel-translucido);
    border: 1px solid var(--borde-claro);
    border-top: 4px solid transparent;
    padding: 30px 28px 32px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%);
    transition: transform .22s ease, box-shadow .22s ease;
}

.servicio--construccion { border-top-color: var(--azul); }
.servicio--transporte   { border-top-color: var(--verde); }

.servicio:hover {
    transform: translateY(-6px);
    box-shadow: 0 18px 34px rgba(36, 33, 33, 0.12);
}

.servicio__icono {
    width: 64px;
    height: 56px;
    clip-path: var(--hex-clip);
    display: grid;
    place-items: center;
    margin-bottom: 18px;
}

.servicio__icono svg { width: 30px; height: 30px; }

.servicio--construccion .servicio__icono { background: rgba(18, 76, 122, 0.12); color: var(--azul); }
.servicio--transporte .servicio__icono   { background: rgba(89, 179, 166, 0.18); color: var(--verde-oscuro); }

.servicio__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    /* Fluido: en la rejilla de 2 columnas la tarjeta se queda en ~216px de
       ancho útil y palabras como "INFRAESTRUCTURA" o "TRANSFRONTERIZA" se
       partían a media palabra con el tamaño fijo de 1.45rem. */
    font-size: clamp(1.08rem, 1.9vw, 1.45rem);
    line-height: 1.1;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin-bottom: 10px;
    color: var(--tinta);
}

/* En el catálogo interactivo (servicios.php) .servicio__titulo es un <h4>
   que sólo envuelve el botón de resumen —la etiqueta de encabezado real,
   como pide el patrón de acordeón accesible (un <button> no puede contener
   un <h4> directamente)—, así que no necesita su propio margen: el
   espaciado lo da el padding de .servicio__resumen. */
.servicio__titulo:has(.servicio__resumen) { margin-bottom: 0; }

.servicio__texto { color: var(--gris-medio); font-size: 0.97rem; }

/* Actividades principales de la línea de servicio */
.servicio__lista {
    display: grid;
    gap: 9px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--borde-claro);
}

.servicio__lista li {
    position: relative;
    padding-left: 22px;
    color: var(--gris-medio);
    font-size: 0.95rem;
}

.servicio__lista li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 12px;
    height: 2px;
    transition: width .22s ease;
}

.servicio--construccion .servicio__lista li::before { background: var(--azul); }
.servicio--transporte .servicio__lista li::before   { background: var(--verde-oscuro); }

/* Dinamismo al pasar el cursor: el guión de cada actividad se alarga y el
   icono hexagonal intensifica su fondo */
.servicio:hover .servicio__lista li::before { width: 17px; }

.servicio__icono { transition: background-color .22s ease; }
.servicio--construccion:hover .servicio__icono { background: rgba(18, 76, 122, 0.2); }
.servicio--transporte:hover .servicio__icono   { background: rgba(89, 179, 166, 0.3); }

/* ---------- Servicios: catálogo interactivo (servicios.php) ----------
   Las tarjetas se agrupan bajo un título por división
   (.servicios__grupo-titulo) y arrancan colapsadas: sólo ícono + título
   (.servicio__resumen). El ratón al entrar en la tarjeta, o el teclado y el
   toque al activar el resumen, revelan el texto y las actividades
   (.servicio__detalle); assets/js/main.js pone/quita .servicio--abierto en
   la tarjeta y calcula el alto real del panel (scrollHeight), así la
   animación no depende de un max-height adivinado. Dentro del panel,
   .servicio__cerrar deja volver a subirlo sin esperar a que el mouse salga
   de la tarjeta — por eso todo el mecanismo vive en JS y no en un simple
   :hover de CSS: un :hover puro reabriría el panel de inmediato en cuanto
   ese botón lo cerrara, mientras el cursor siguiera encima. */
/* Sin align-items:start los items se estiran a la altura de su fila: al
   desplegar una tarjeta, las vecinas de la misma fila crecían con ella y
   quedaban como cajas de 450px con sólo un título dentro. */
.servicios__grid--interactivo { align-items: start; }

.servicios__grid--interactivo .servicio { padding: 0; overflow: hidden; }

/* El propio despliegue ya es respuesta suficiente al cursor. El salto de
   -6px que usa la tarjeta estática movería el borde superior de la tarjeta
   justo cuando el panel empieza a crecer y, con el puntero sobre esa franja,
   provocaría un parpadeo de abrir/cerrar. */
.servicios__grid--interactivo .servicio:hover { transform: none; }

.servicio__resumen {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    /* min-height iguala las tarjetas colapsadas de una misma fila. Ya no
       pueden estirarse entre sí (align-items:start), así que sin esto un
       título de una línea y otro de tres dejaban escalones de 30px en la
       fila. 98px es la altura de un resumen de dos líneas, que es lo que
       ocupan casi todos los títulos con la caja de abajo; a 1440px, donde
       "URBANIZACIÓN Y DESARROLLO INMOBILIARIO" llega a tres, 106px las
       mantiene parejas igualmente. */
    min-height: 106px;
    padding: 22px 24px;
    background: none;
    border: none;
    /* Un <button> no hereda tipografía por omisión: sin esto el título se
       vería con la fuente del sistema en vez de Libre Baskerville. Y el
       atajo `font` no cubre todo: la hoja del navegador fuerza además
       text-transform:none y letter-spacing:normal en los controles de
       formulario, así que sin heredarlos a mano estos nueve títulos salían
       en caja baja y sin interletraje, los únicos del sitio así — y justo
       debajo de los títulos de grupo, que sí van en versales. */
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

/* El anillo de foco global (:focus-visible, outline-offset: 2px) se dibuja
   FUERA de la caja del botón, y como el resumen ocupa exactamente la caja de
   relleno de la tarjeta, el overflow:hidden y el clip-path de .servicio se lo
   comían entero: al tabular por el catálogo no se veía en cuál de las nueve
   tarjetas estaba el foco. Un box-shadow interior se pinta por dentro, así
   que ni el recorte ni la esquina cortada lo tocan. */
.servicio__resumen:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 3px var(--foco);
}

/* Colapsada, la tarjeta es sólo esta fila, así que el título necesita el
   ancho que en la tarjeta estática se reparte con el texto. Con el hexágono
   a 64px y el cuerpo a 1.45rem, "CARGA INTERNACIONAL Y TRANSFRONTERIZA" caía
   en cuatro renglones dentro de una columna de 203px. */
.servicios__grid--interactivo .servicio__icono { width: 50px; height: 44px; }
.servicios__grid--interactivo .servicio__icono svg { width: 24px; height: 24px; }
.servicios__grid--interactivo .servicio__titulo { font-size: clamp(0.95rem, 1.22vw, 1.1rem); }

.servicio__resumen .servicio__icono { margin-bottom: 0; flex-shrink: 0; }

.servicio__titulo-texto { flex: 1 1 auto; }

.servicio__chevron {
    flex-shrink: 0;
    color: var(--gris-medio);
    transition: transform .25s ease;
}

.servicio__resumen[aria-expanded="true"] .servicio__chevron { transform: rotate(180deg); }

/* Sin JavaScript el panel queda abierto: el catálogo se lee entero, que es
   lo que importa, en vez de mostrar nueve títulos que no despliegan nada. */
.servicio__detalle { overflow: hidden; }

.js .servicio__detalle {
    max-height: 0;
    opacity: 0;
    /* visibility, y no sólo max-height:0, es lo que saca del recorrido de
       tabulación y del lector de pantalla el botón de flecha de cada panel
       cerrado: con nueve tarjetas eran nueve botones invisibles que el
       teclado visitaba antes de llegar al siguiente servicio. El retardo de
       .32s la mantiene visible mientras dura el plegado; al abrir, la regla
       de .servicio--abierto la pone en visible sin retardo. */
    visibility: hidden;
    transition: max-height .32s ease, opacity .25s ease, visibility 0s linear .32s;
}

/* Todo el relleno del panel vive aquí y NUNCA se anima. Cuando el relleno
   estaba en .servicio__detalle —que sí transiciona— main.js leía scrollHeight
   en el mismo instante en que añadía la clase, cuando la transición todavía
   devuelve el valor inicial (0), así que fijaba un max-height 32px más corto
   que el contenido real y recortaba justo el botón de flecha del final. */
.servicio__detalle-inner { padding: 4px 26px 28px; }

/* En la portada la tarjeta no lleva el párrafo de descripción: el panel
   empieza directamente por las actividades, y entonces el filete superior de
   .servicio__lista —que allí separa el texto de la lista— quedaría colgando
   solo, justo debajo del título, como si fuera un subrayado suelto. */
.servicio__detalle-inner > .servicio__lista:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.servicio--abierto .servicio__detalle {
    opacity: 1;
    visibility: visible;
    /* El alto real lo fija main.js (scrollHeight) en la misma llamada que
       añade la clase; este valor sólo cubre ese instante intermedio y el
       caso de que la medida fallara. No es un respaldo "sin JavaScript": sin
       JS nadie añade .servicio--abierto y la regla no llega a aplicarse
       nunca. 560px deja margen sobre el panel más alto medido, 416px a
       320px de ancho de ventana. */
    max-height: 560px;
    transition: max-height .32s ease, opacity .25s ease, visibility 0s;
}

.servicio__cerrar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    margin: 18px auto 0;
    border-radius: 50%;
    border: 1px solid var(--borde-claro);
    background: var(--claro-translucido);
    color: var(--gris-medio);
    cursor: pointer;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

.servicio--construccion .servicio__cerrar:hover { color: var(--azul); border-color: var(--azul); }
.servicio--transporte .servicio__cerrar:hover   { color: var(--verde-oscuro); border-color: var(--verde-oscuro); }

/* Título de cada grupo de división dentro del catálogo: separa visualmente
   "sepáralo por el título" sin volver a poner una etiqueta de color en cada
   tarjeta (ya se quitó antes por pedido del usuario). grid-column: 1 / -1
   para que ocupe toda la fila sin importar cuántas columnas tenga la
   rejilla en cada ancho de pantalla. */
.servicios__grupo-titulo {
    grid-column: 1 / -1;
    font-family: var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: clamp(1.15rem, 2vw, 1.4rem);
    padding-bottom: 12px;
    margin-top: 14px;
    border-bottom: 2px solid currentColor;
}

.servicios__grupo-titulo:first-child { margin-top: 0; }

.servicios__grupo-titulo--construccion { color: var(--azul); }
.servicios__grupo-titulo--transporte   { color: var(--verde-oscuro); }

/* ---------- Cifras ---------- */
.cifras__grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 26px;
}

.cifra {
    background: var(--carbon-translucido);
    border: 1px solid var(--borde-oscuro);
    border-left: 4px solid var(--verde);
    padding: 30px 26px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
    /* La cifra se dimensiona contra el ANCHO DE LA TARJETA, no contra el de la
       ventana (ver .cifra__valor). */
    container-type: inline-size;
}

.cifra:nth-child(even) { border-left-color: var(--azul-claro); }

/* El valor se mide en cqi (1% del ancho interior de la tarjeta) y no en vw.
   Con cuatro columnas la tarjeta mide ~214px por dentro, y "36,000,000+" en
   Libre Baskerville Bold ocupa 6.875 em: a 3rem pedía 330px y se salía de la
   tarjeta, invadiendo la vecina y, en la última, el borde de la página. Los
   dígitos no ofrecen ningún punto de corte, así que la única salida es que el
   cuerpo siga al contenedor: 14cqi = 6.875 em cabe con holgura en cualquier
   número de columnas, y el tope de 3rem conserva el tamaño original cuando la
   rejilla baja a dos columnas o a una y las tarjetas se ensanchan. */
.cifra__valor {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.45rem, 14cqi, 3rem);
    line-height: 1;
    color: var(--verde);
    margin-bottom: 10px;
    font-variant-numeric: tabular-nums;
}

/* Sin consultas de contenedor (navegadores anteriores a Chrome 105 / Safari
   16 / Firefox 110) se vuelve a vw, con un tope calculado para que la cifra
   más larga siga cabiendo en la columna más estrecha. */
@supports not (container-type: inline-size) {
    .cifra__valor { font-size: clamp(1.45rem, 2.1vw, 1.9rem); }
}

.cifra:nth-child(even) .cifra__valor { color: var(--azul-tinte); }

.cifra__label {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-size: 1rem;
    color: var(--gris);
}

/* ---------- Proceso ---------- */
/* Sólo lo usa el resumen de la portada: proceso.php arma sus cuatro etapas con
   .divisiones__grid, porque ahí cada una lleva foto, detalle y entregable y
   necesita el par de columnas anchas. Por eso aquí no van columnas —las fija
   .resumen-proceso más abajo, junto con el resto de su maquetación—: dejarlas
   sería letra muerta, sobrescrita en el único sitio donde la clase se usa. */
.proceso__grid {
    display: grid;
    gap: 26px;
    counter-reset: paso;
}

.paso {
    background: var(--panel-translucido);
    border: 1px solid var(--borde-claro);
    padding: 30px 26px 32px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
    position: relative;
}

/* Foto de la etapa (solo proceso.php): sangra hasta los bordes de la
   tarjeta anulando el padding de .paso; el recorte de esquina de la
   tarjeta queda abajo, así que arriba no hay conflicto con el clip-path. */
.paso__media {
    margin: -30px -26px 24px;
    aspect-ratio: 1080 / 562;
}

.paso__media img { width: 100%; }

/* Los cuatro pasos llevan el MISMO hexágono azul. Antes alternaban azul y
   verde agua según la posición (.paso:nth-child(even)); el usuario pidió un
   solo estilo para estos números, así que la variante turquesa se retiró. */
.paso__num {
    display: grid;
    place-items: center;
    width: 52px;
    height: 46px;
    clip-path: var(--hex-clip);
    background: linear-gradient(135deg, var(--azul), var(--azul-claro));
    color: var(--blanco);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.5rem;
    margin-bottom: 18px;
}

.paso__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.4rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin-bottom: 8px;
    color: var(--tinta);
}

.paso__texto { color: var(--gris-medio); font-size: 0.96rem; }

/* El resumen de "Cómo trabajamos" en la portada NO usa las cuatro columnas de
   proceso.php. Ahí cada tarjeta se quedaba en 268px, con sólo 206px de ancho
   de texto, y a ese ancho la maquetación se rompía por los dos lados:

     · el título a 1.55rem no cabía ni en una palabra, así que la red de
       seguridad `overflow-wrap: break-word` entraba a partirlo — "DIAGNÓSTIC /
       O Y / PROPUESTA" — y en el paso 2 la "y" se quedaba sola en su renglón;
     · el párrafo caía a unos 24 caracteres por línea (la medida cómoda son
       45–75) y se estiraba a cinco, seis o siete renglones distintos en cada
       tarjeta;
     · como los títulos ocupaban dos o tres líneas según el paso, los párrafos
       arrancaban a alturas distintas y nada quedaba alineado de una tarjeta a
       la siguiente.

   Ahora son dos columnas de dos, y dentro de cada tarjeta el hexágono pasa al
   costado del título en vez de ir encima. Eso da unos 440px de texto: el
   título entra completo en un renglón y el párrafo en dos, iguales en las
   cuatro. La secuencia se sigue leyendo por los números, de izquierda a
   derecha y de arriba abajo. proceso.php se queda con sus cuatro columnas,
   que ahí sí funcionan porque la tarjeta lleva foto y el texto va debajo, a
   todo el ancho de la tarjeta. */
.resumen-proceso .proceso__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 26px;
}

.resumen-proceso .paso {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 22px;
    row-gap: 12px;
    padding: 34px 36px 36px;
}

/* Fila 1: hexágono y título, uno al lado del otro y centrados entre sí.
   Fila 2: el párrafo, alineado con el título y no con el hexágono. */
.resumen-proceso .paso__num {
    grid-column: 1;
    grid-row: 1;
    align-self: center;
    width: 60px;
    height: 54px;
    font-size: 1.65rem;
    margin-bottom: 0;
}

.resumen-proceso .paso__titulo {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
    font-size: 1.4rem;
    margin-bottom: 0;
}

.resumen-proceso .paso__texto {
    grid-column: 2;
    grid-row: 2;
    font-size: 1.02rem;
    /* Tope de medida: a una sola columna la tarjeta se va por encima de los
       700px y la línea pasaría de los 90 caracteres. */
    max-width: 62ch;
}

/* Los dos cortes de abajo salen de una sola medida: "DIAGNÓSTICO Y PROPUESTA",
   el título más largo, pide 386px en un renglón a 1.4rem en versales. Con el
   hexágono al costado la tarjeta le resta 154px (72 de relleno más 60 del
   hexágono y 22 de separación), así que la tarjeta necesita 540px para que el
   título no se parta.
     · Dos columnas: el corte se pone en 1200px, es decir sólo por encima de
       ese ancho. Medido: a 1201px de ventana el título dispone de 404px y a
       1440px de 411px, siempre por encima de los 386 que pide. Se probó en
       1160px y quedaba corto por 2px —el título del primer paso se partía en
       dos renglones—, así que el corte quedó donde el margen es holgado.
     · Una columna con el hexágono al lado: la tarjeta es el contenedor
       entero, así que basta con 580px de ventana. El corte se pone en 680px,
       y por debajo el hexágono vuelve arriba del título como en proceso.php:
       eso le devuelve al título los 82px del hexágono y su separación. */
@media (max-width: 1200px) {
    .resumen-proceso .proceso__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 680px) {
    .resumen-proceso .paso {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0;
        padding: 30px 26px 32px;
    }

    .resumen-proceso .paso__num {
        grid-column: 1;
        grid-row: 1;
        margin-bottom: 18px;
    }

    .resumen-proceso .paso__titulo {
        grid-column: 1;
        grid-row: 2;
        margin-bottom: 8px;
    }

    .resumen-proceso .paso__texto {
        grid-column: 1;
        grid-row: 3;
    }
}

/* ---------- Por qué Omega (nosotros.php) ---------- */
.porque__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: 64px;
    align-items: center;
}

.porque__grid .encabezado-seccion__texto { margin-bottom: 20px; }

/* Par de fotos escalonadas: cada una cede un margen del lado contrario
   para que la columna no se lea como un bloque rígido. */
.porque__fotos { display: grid; gap: 22px; }

.porque__fotos .img-duo {
    aspect-ratio: 16 / 10;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
}

.porque__fotos .img-duo:nth-child(1) { margin-left: 46px; }
.porque__fotos .img-duo:nth-child(2) { margin-right: 46px; }

/* ---------- CTA ---------- */
.cta {
    position: relative;
    padding: 120px 0;
    background: var(--negro);
    color: var(--blanco);
    overflow: hidden;
    text-align: center;
}

.cta__fondo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* La foto (1920x820, 2.34:1) es mucho más ancha que su franja de fondo,
       así que object-fit la recorta arriba y abajo en casi todos los anchos
       de escritorio (a partir de ~1410px de ventana la caja ya es más ancha
       que 2.34:1). Con la posición por omisión (centro) ese recorte es
       simétrico y, cuanto más ancha la ventana, más carretera se pierde por
       abajo — en monitores anchos llega a desaparecer del todo, dejando sólo
       cielo. Anclado abajo, el recorte siempre quita cielo por arriba y deja
       la carretera completa, sea cual sea el ancho. */
    object-position: center bottom;
    /* Suavizado de la foto; el degradado ::before mantiene la legibilidad */
    filter: grayscale(0.2) brightness(0.75) contrast(1.03);
}

.cta::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(120deg, rgba(12, 53, 87, 0.88), rgba(36, 33, 33, 0.82) 55%, rgba(60, 132, 120, 0.5));
    z-index: 1;
}

.cta__inner { position: relative; z-index: 2; }

.cta__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2.2rem, 5vw, 3.6rem);
    line-height: 1.05;
    text-transform: uppercase;
    margin-bottom: 18px;
}

.cta__texto {
    color: #D6D1D0;
    max-width: 560px;
    margin: 0 auto 34px;
    font-size: 1.08rem;
}

/* ---------- Contacto ---------- */
.contacto__grid {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 64px;
    align-items: start;
}

.contacto__info > p { color: var(--gris-medio); margin-bottom: 28px; }

.contacto__datos { display: grid; gap: 20px; }

/* Foto de apoyo bajo los datos de contacto (solo contacto.php) */
.contacto__foto {
    margin-top: 32px;
    aspect-ratio: 16 / 10;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
}

.contacto__datos li {
    display: grid;
    gap: 2px;
    padding-left: 20px;
    border-left: 4px solid var(--verde);
}

.contacto__datos li:nth-child(even) { border-left-color: var(--azul); }

/* ---------- Resumen de contacto (portada) ----------
   En contacto.php esta rejilla da 0.85fr a los datos y 1.15fr al formulario, y
   ahí está bien. La portada heredó ese reparto sin tener formulario: la
   columna ANCHA se quedaba con una lista de dos renglones de texto suelto y
   media sección vacía a su derecha. Aquí las columnas van parejas y cada
   contacto pasa a ser una tarjeta con su ícono hexagonal, del mismo material
   translúcido y con el mismo corte angular que el resto de las tarjetas del
   sitio, así que la columna se llena y el dato se lee de lejos. */
.contacto-resumen .contacto__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 48px;
}

.contacto__tarjetas { display: grid; gap: 20px; align-content: start; }

.contacto__tarjeta {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 20px;
    row-gap: 3px;
    align-items: center;
    background: var(--panel-translucido);
    border: 1px solid var(--borde-claro);
    border-left: 4px solid var(--verde);
    padding: 26px 30px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
}

.contacto__tarjeta:nth-child(even) { border-left-color: var(--azul); }

/* El ícono ocupa la primera columna a lo alto de los tres renglones; el
   align-items: center de la tarjeta lo centra contra ellos. */
.contacto__tarjeta-icono {
    grid-column: 1;
    grid-row: 1 / span 3;
    width: 58px;
    height: 51px;
    clip-path: var(--hex-clip);
    display: grid;
    place-items: center;
    background: rgba(89, 179, 166, 0.18);
    color: var(--verde-oscuro);
}

.contacto__tarjeta:nth-child(even) .contacto__tarjeta-icono {
    background: rgba(18, 76, 122, 0.12);
    color: var(--azul);
}

.contacto__tarjeta-icono svg { width: 26px; height: 26px; }

.contacto__tarjeta > .contacto__dato-label,
.contacto__tarjeta > .contacto__dato-nota { grid-column: 2; }

.contacto__tarjeta-valor {
    grid-column: 2;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.3rem, 2.4vw, 1.8rem);
    line-height: 1.15;
    color: var(--tinta);
}

.contacto__tarjeta-valor:hover { color: var(--azul); }

/* El correo es mucho más largo que el teléfono —35 caracteres contra 14— y
   nunca va a caber de un tirón en la tarjeta: a 1280px la columna da 413px y
   el correo completo pide 607px. Se parte después de la arroba (ver
   correo_partible() en datos.php), así que lo que tiene que caber en un
   renglón es el dominio, "cargaytransportesomega.com", que pide unos 15.5px
   de ancho por cada píxel de cuerpo. De ahí sale este tope más bajo que el
   del teléfono: a 1280px son 25px de cuerpo y 387px de dominio, dentro de los
   413 disponibles. Sin él el dominio tampoco cabía y aparecía un TERCER
   renglón partido a media palabra ("...omega.c / om"). La diferencia con el
   teléfono es del 11%, así que las dos tarjetas siguen leyéndose parejas. */
.contacto__tarjeta-valor--correo { font-size: clamp(1.15rem, 1.95vw, 1.6rem); }

/* La regla general de 900px apila .contacto__grid, pero la de arriba le gana
   por especificidad (0,2,0), así que hay que repetir el corte aquí.
   Y el corte se sube de 900 a 1000px por el correo: a dos columnas la tarjeta
   se queda con 256px de texto a 901px de ventana y el dominio pide 285px, así
   que aparecía un tercer renglón partido a media palabra. Medido: a 1001px la
   columna da 318px y el dominio 305px, que entra; a 1000px o menos la tarjeta
   pasa a ocupar el contenedor entero y le sobra sitio. */
@media (max-width: 1000px) {
    .contacto-resumen .contacto__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 40px;
    }
}

/* En móvil angosto el ícono al costado se lleva 78px de los ~290 que tiene la
   tarjeta, y con eso "CORREO ELECTRÓNICO" y "contacto@omega.mx" se quedaban
   sin sitio: medido a 359px, la tinta del correo se salía 85px de la tarjeta.
   Aquí el ícono sube arriba de la etiqueta y le devuelve al texto el ancho
   completo. El corte va en 480px porque la etiqueta pide 248px y la columna
   sólo los alcanza con el ícono al lado a partir de ~430px de ventana. */
@media (max-width: 480px) {
    .contacto__tarjeta {
        grid-template-columns: minmax(0, 1fr);
        padding: 24px 22px;
    }

    .contacto__tarjeta-icono {
        grid-row: 1;
        margin-bottom: 14px;
    }

    .contacto__tarjeta > .contacto__dato-label,
    .contacto__tarjeta > .contacto__dato-nota,
    .contacto__tarjeta-valor { grid-column: 1; }
}

/* En los teléfonos más angostos la tarjeta deja 239px de texto y el dominio
   pide 285px al cuerpo mínimo del clamp, así que ahí baja un paso más para
   que siga cabiendo de un renglón en vez de partirse. El corte va en 380px:
   el dominio deja de caber en cuanto la ventana baja de unos 366px, y a 381px
   la columna da 300px contra los 285 que pide. */
@media (max-width: 380px) {
    .contacto__tarjeta-valor--correo { font-size: 0.95rem; }
}

.contacto__dato-label {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gris-medio);
}

.contacto__datos a { font-weight: 700; color: var(--tinta); }
.contacto__datos a:hover { color: var(--azul); }

/* Disponibilidad de cada vía de contacto, debajo del número o del correo.
   Antes el horario era una fila más de la lista, común a las dos; ahora cada
   una lleva la suya, así que va como nota secundaria dentro de su propia
   fila. El li ya es una rejilla con 2px de separación, así que basta con
   bajarle el cuerpo y el tono. */
.contacto__dato-nota {
    font-size: 0.88rem;
    color: var(--gris-medio);
}

/* Formulario */
.formulario {
    background: var(--panel-translucido);
    border: 1px solid var(--borde-claro);
    padding: 36px 34px 40px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%);
}

.formulario__fila {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
}

.campo { margin-bottom: 20px; }

.campo label {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.02rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    margin-bottom: 7px;
    color: var(--tinta);
}

.campo input,
.campo select,
.campo textarea {
    width: 100%;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--tinta);
    background: rgba(245, 243, 242, 0.85);
    border: 2px solid rgba(55, 51, 51, 0.55);  /* tinte del carbón: el campo se distingue del panel (3:1 o más) */
    border-radius: 0;               /* botones y campos angulares */
    padding: 12px 14px;
    transition: border-color .2s ease, background-color .2s ease;
    appearance: none;
    -webkit-appearance: none;
}

.campo select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%23373333' stroke-width='2'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 40px;
}

.campo textarea { resize: vertical; min-height: 130px; }

.campo input:focus,
.campo select:focus,
.campo textarea:focus {
    border-color: var(--azul);
    background: var(--blanco);
}

/* El anillo vuelve a los campos: antes un outline:none los dejaba sin
   ninguna marca de foco por teclado. Va sin offset positivo porque el
   clip-path de .formulario muerde la esquina y se lo comeria. */
.campo input:focus-visible,
.campo select:focus-visible,
.campo textarea:focus-visible {
    outline: 3px solid var(--negro);
    outline-offset: 0;
}

.campo input::placeholder,
.campo textarea::placeholder { color: #6F6969; }

.formulario__nota {
    margin-top: 16px;
    font-size: 0.85rem;
    color: var(--gris-medio);
}

/* Alertas del formulario */
.alerta {
    padding: 18px 22px;
    margin-bottom: 22px;
    clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
    font-size: 0.97rem;
}

.alerta ul { margin-top: 8px; display: grid; gap: 4px; padding-left: 18px; list-style: square; }

.alerta--exito {
    background: rgba(60, 132, 120, 0.14);
    border-left: 5px solid var(--verde-oscuro);
    color: #1F4841;
}

.alerta--error {
    background: rgba(190, 32, 46, 0.1);
    border-left: 5px solid #BE202E;
    color: #8E1622;
}

/* ---------- Footer ---------- */
.footer {
    background: var(--footer-fondo);
    color: var(--gris);
    padding-top: 72px;
}

.footer__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.8fr) minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 40px;
    padding-bottom: 56px;
}

/* La variante del logo que usa el pie (oglb-logo.webp) ya lleva el rótulo en
   blanco, pensado para ir directo sobre el fondo oscuro del pie — sin la
   placa clara que sí necesita la versión de tinta oscura del header. */
.marca__placa--footer {
    align-self: start;
    background: none;
    padding: 0;
    clip-path: none;
}

.marca__placa--footer img { width: 190px; }

.footer__lema {
    margin-top: 18px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--blanco);
    max-width: 260px;
}

.footer__titulo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--verde);
    margin-bottom: 16px;
}

.footer__grid ul { display: grid; gap: 9px; }

/* En el pie, cada dato de contacto lleva su nota de disponibilidad debajo. El
   li tiene que ser rejilla propia: un <span> suelto es en línea y la nota se
   pegaría al lado del enlace en vez de caer a su renglón. El tono es el mismo
   gris apagado del aviso legal, más bajo que el --gris de los enlaces para que
   la nota no compita con el número. */
.footer__contacto li { display: grid; gap: 2px; }

.footer__nota { font-size: 0.85rem; color: #B0A9A9; }

.footer__grid a { color: var(--gris); }
.footer__grid a:hover { color: var(--verde); }

.footer__legal {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    padding: 20px 0;
    font-size: 0.88rem;
    color: #B0A9A9;
}

/* ---------- Animaciones de aparición ----------
   El contenido está VISIBLE por omisión y sólo se oculta para animarlo
   cuando la clase .js está puesta (la pone una línea en el <head> de
   includes/header.php). La dependencia va en ese sentido a propósito: la
   versión anterior arrancaba en opacity 0 y sólo el JavaScript la
   encendía, así que si el JS no llegaba —bloqueado, un FTP incompleto,
   al imprimir la página— el cuerpo entero quedaba en blanco: en cuatro
   de las cinco páginas no sobrevivía ni el <h1>. */
.reveal { opacity: 1; transform: none; }

.js .reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .7s ease, transform .7s ease;
}

.js .reveal--tarde { transition-delay: .18s; }

.js .reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    /* Los selectores llevan .js porque ahora .js .reveal (0,2,0) es quien
       oculta; un .reveal a secas (0,1,0) perdería y el contenido seguiría
       invisible hasta que corriera el JavaScript. */
    .js .reveal, .js .reveal--tarde {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .btn, .division, .servicio, .header::after { transition: none; }
    /* .servicio--abierto .servicio__detalle también declara su propia
       transition y gana por especificidad (0,2,0) aunque esta regla vaya
       después, así que hay que repetir el selector completo o el panel
       seguiría animándose con la preferencia activada. El despliegue en sí
       sigue funcionando: pasa a instantáneo, no desaparece. */
    .servicio__detalle,
    .servicio--abierto .servicio__detalle,
    .servicio__chevron { transition: none; }
}

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
/* Las cifras pasan a dos columnas antes que el resto (1199px en vez de
   1024px): con cuatro columnas por debajo del contenedor completo la tarjeta
   se queda tan estrecha que "36,000,000+" tendría que bajar a ~23px y la
   banda perdería toda su fuerza. A dos columnas recupera el cuerpo máximo. */
@media (max-width: 1199px) {
    .cifras__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1024px) {
    .servicios__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .nosotros__grid,
    .contacto__grid { gap: 44px; }
}

/* Las tarjetas de servicio pasan a una sola columna antes que el resto de las
   rejillas (680px en vez de 560px): a 2 columnas por debajo de ese ancho la
   tarjeta se queda demasiado estrecha para los títulos largos de esta serif. */
@media (max-width: 680px) {
    .servicios__grid { grid-template-columns: minmax(0, 1fr); }
}

/* Menú móvil: colapsa a hamburguesa antes que el resto del layout (1130px en
   vez de 900px) porque el nav en Libre Baskerville necesita más ancho.
   Medido a 1131px de ventana (el ancho más angosto con el menú de escritorio
   todavía activo): logotipo 168px + gap 24px + nav 737px = 929px de
   contenedor, es decir un viewport mínimo de unos 969px. El corte en 1130px
   deja margen de sobra; el primer enlace arranca a 354px del borde interior
   del contenedor, que es el espacio libre disponible a la izquierda. */
@media (max-width: 1130px) {
    .nav-toggle { display: flex; }

    /* El panel desplegable usa el MISMO material que la barra: el mismo velo
       translúcido, con el mismo tono (claro u oscuro según la sección que
       haya quedado bajo el header al abrir el menú) más el mismo desenfoque.
       Si fuese de otro tono se vería un escalón justo donde termina la
       barra, que es la división que se quiere evitar; así barra y panel leen
       como una sola lámina. El desenfoque se activa sólo con el panel
       abierto: cerrado no hay nada que difuminar. */
    .nav {
        position: fixed;
        top: 76px;
        left: 0;
        right: 0;
        background: var(--menu-fondo-oscura);
        transform: translateY(-130%);
        /* visibility, además del transform: un elemento desplazado fuera de
           la pantalla SIGUE siendo enfocable y anunciable. Sin esto, con el
           menú cerrado el teclado caía en los seis enlaces del panel, que
           están a −425px y que el navegador no puede traer a la vista por
           ser position:fixed. El retardo mantiene el panel visible mientras
           dura el cierre; .nav--abierto lo revierte sin retardo. */
        visibility: hidden;
        transition: transform .3s ease, background-color .3s ease, visibility 0s linear .3s;
        max-height: calc(100vh - 76px);
        /* En iOS 100vh es más alto que la pantalla visible y el último
           enlace queda bajo la barra del navegador. */
        max-height: calc(100dvh - 76px);
        overflow-y: auto;
    }

    .header[data-tono="clara"] .nav {
        background: var(--menu-fondo-clara);
    }

    .nav--abierto {
        transform: translateY(0);
        visibility: visible;
        transition: transform .3s ease, background-color .3s ease, visibility 0s;
        -webkit-backdrop-filter: blur(14px);
        backdrop-filter: blur(14px);
    }

    .nav__lista {
        flex-direction: column;
        align-items: stretch;
        padding: 18px 20px 26px;
        gap: 2px;
    }

    .nav__enlace {
        padding: 13px 10px;
        /* Línea divisoria clara sobre el panel oscuro (por omisión) y oscura
           sobre el panel claro: como el tono del panel ahora cambia con la
           sección, el divisor necesita las dos variantes. */
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        font-size: 1.15rem;
        letter-spacing: 0.06em;
    }

    .header[data-tono="clara"] .nav__enlace {
        border-bottom-color: rgba(55, 51, 51, 0.10);
    }

    .nav__enlace::after { display: none; }

    .nav__cta-item { margin: 16px 0 0; }
    .nav__cta-item .btn { display: block; }
}

@media (max-width: 900px) {
    .pagina-hero,
    /* Repetir el selector con id es obligatorio: una media query NO aporta
       especificidad, asi que #servicios .pagina-hero (1,1,0) ganaba siempre
       y servicios.php abria con 165px de banda vacia en un telefono. */
    #servicios .pagina-hero { padding: 120px 0 56px; }

    /* Hero apilado: la foto pasa de panel lateral absoluto a banda en
       flujo arriba del titular (el section es flex, por eso la columna) */
    .hero { padding: 130px 0 90px; min-height: 0; flex-direction: column; justify-content: center; }
    .hero__grid { grid-template-columns: minmax(0, 1fr); }

    .hero__foto {
        position: relative;
        width: 100%;
        height: min(60vw, 320px);
        margin-bottom: 26px;
        /* La parada transparente (11%) cubre la deriva vertical del
           degradado en la banda (~10%), igual que en el panel de
           escritorio: sin eso, el borde izquierdo dibuja una línea. */
        -webkit-mask-image: linear-gradient(100deg, transparent 11%, #000 28%, #000 82%, transparent 100%);
        mask-image: linear-gradient(100deg, transparent 11%, #000 28%, #000 82%, transparent 100%);
    }

    /* minmax(0, 1fr) y no 1fr: un 1fr tiene mínimo auto (min-content) y una
       palabra larga podría abrir la columna más que el contenedor. */
    .nosotros__grid,
    .divisiones__grid,
    .contacto__grid,
    .porque__grid { grid-template-columns: minmax(0, 1fr); }

    /* División ampliada apilada: las dos fotos pasan a convivir lado a lado.
       El selector repite el :nth-child(even) del escritorio porque esa regla
       tiene mayor especificidad que .division--amplia a secas: sin él, la
       segunda división conservaría sus dos columnas en móvil. */
    .division--amplia,
    .division--amplia:nth-child(even) { grid-template-columns: minmax(0, 1fr); }
    .division--amplia .division__media-col {
        order: 0;
        grid-template-rows: none;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .division--amplia:nth-child(even) .division__media-col { order: 0; }
    /* height:auto anula el height:100% del escritorio: con la altura suelta,
       el aspect-ratio tomaría la altura libre y dispararía el ancho. */
    .division--amplia .division__media { aspect-ratio: 4 / 3; height: auto; }
    .division--amplia .division__cuerpo { padding: 30px 32px 36px; }

    /* Las fotos escalonadas de "Por qué Omega" pierden el escalón y se
       acomodan en fila bajo el texto */
    .porque__fotos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
    .porque__fotos .img-duo:nth-child(1) { margin-left: 0; }
    .porque__fotos .img-duo:nth-child(2) { margin-right: 0; }

    .nosotros__sello { right: 10px; }

    .seccion { padding: 72px 0; }

    :root { --corte-diag: 5vw; }

    @supports (width: round(1px, 1px)) {
        :root { --corte-diag: round(5vw, 1px); }
    }

    @supports not (width: round(1px, 1px)) {
        :root { --corte-diag: 20px; }
    }
}

@media (max-width: 560px) {
    .marca__placa img { width: 138px; }

    /* La serif con letter-spacing amplio resulta muy voluminosa en móvil */
    .kicker { font-size: 0.9rem; letter-spacing: 0.08em; }

    .servicios__grid,
    .cifras__grid,
    .formulario__fila,
    .porque__fotos,
    .footer__grid { grid-template-columns: minmax(0, 1fr); }

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

    .hero__acciones .btn { flex: 1 1 100%; }

    .formulario { padding: 28px 20px 34px; }

    .contenedor { padding-inline: 16px; }
}

/* ---------- Prosa legal (aviso-privacidad.php) ----------
   Columna estrecha para que la línea de texto no pase de unos 70
   caracteres: un aviso legal es texto seguido y a todo el ancho del
   contenedor se vuelve ilegible. Los h2 reutilizan .titulo-seccion pero
   con un cuerpo menor, porque aquí son apartados, no títulos de sección. */
.prosa-legal {
    max-width: 760px;
    margin: 0 auto;
}

.prosa-legal .titulo-seccion {
    font-size: clamp(1.2rem, 2.2vw, 1.5rem);
    margin-top: 44px;
    margin-bottom: 14px;
}

.prosa-legal > .titulo-seccion:first-child { margin-top: 0; }

.prosa-legal p { margin-bottom: 16px; }

.prosa-legal .lista-check { margin-bottom: 22px; }

.prosa-legal a { text-decoration: underline; text-underline-offset: 0.18em; }
