/* ==========================================================================
   LUCESAT RASTREO SATELITAL — Hoja de estilos principal
   --------------------------------------------------------------------------
   Orden del archivo:
     1. Tipografías (se cargan desde includes/header.php, no acá)
     2. Variables del sistema de diseño (:root) con la paleta oficial
     3. Reset moderno
     4. Utilidades base (container, grid, espaciado, superficies, reveals)
     5. Componentes (header, hero, tarjetas, formulario, footer, flotantes)
     6. Responsive — breakpoints 480 · 768 · 1024 · 1280

   --------------------------------------------------------------------------
   PRODUCCIÓN
   Este archivo se sirve SIN minificar a propósito: el proyecto no tiene build
   y así queda legible y editable en el hosting. Para minificarlo al desplegar:

       npx clean-css-cli -O2 -o assets/css/styles.min.css assets/css/styles.css

   y apuntar lucase_asset('css/styles.min.css') en includes/header.php.
   ⚠️ Subir LUCESAT_VERSION en config/config.php después de minificar: es lo
   que invalida la caché (lucase_asset lo agrega como ?v=).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TIPOGRAFÍAS
   Space Grotesk → títulos y números grandes
   Inter         → cuerpo de texto e interfaz

   Se enlazan con <link> en includes/header.php. Antes se importaban acá con
   @import, pero eso encadena dos viajes de red —el navegador tiene que bajar y
   parsear esta hoja para recién después descubrir la tipografía—. Con el <link>
   en el HTML, ambas descargas arrancan en paralelo.
   -------------------------------------------------------------------------- */


/* ==========================================================================
   2. VARIABLES DEL SISTEMA DE DISEÑO
   Espejo en CSS de LUCESAT_PALETA (config/config.php). Si se cambia un color
   en un lado, actualizar el otro.
   ========================================================================== */
:root {
    /* --- Paleta oficial ------------------------------------------------- */
    --blanco:            #FFFFFF;
    --blanco-humo:       #F5F8FC;
    --blanco-borde:      #E2E8F0;

    --celeste:           #38BDF8;
    --celeste-fuerte:    #0EA5E9;
    --celeste-suave:     #BAE6FD;

    --marino:            #0A1A33;
    --marino-profundo:   #0F172A;
    --marino-medio:      #132B4D;
    --marino-borde:      #1E3A5F;

    /* --- Barra clara: cabecera y pie -------------------------------------
       El logotipo de la marca es arte en azul marino y azul. Sobre el azul
       marino del cuerpo el azul marino del logo desaparecía (prácticamente
       el mismo brillo que el fondo), así que la cabecera y el pie van en
       claro y el cuerpo del sitio sigue oscuro. Estos tonos NO reemplazan
       la paleta: visten únicamente la barra superior (y su drawer) y el pie.
       Los contrastes sobre --barra están verificados: texto 15.8:1,
       secundario 5.3:1, acento 5.4:1 (todos AA o mejor). */
    --barra:              #F4F5F7;
    --barra-alta:         #FFFFFF;
    --barra-texto:        #1B2430;
    --barra-suave:        #5A6779;
    --barra-borde:        rgba(16, 26, 40, 0.12);
    --barra-borde-fuerte: rgba(16, 26, 40, 0.22);
    --barra-acento:       #0060D0;  /* azul de la marca, versión legible sobre claro */
    --barra-acento-osc:   #00479B;

    /* --- Roles semánticos (usar estos, no los colores crudos) ---------- */
    --color-fondo:            var(--marino);
    --color-fondo-alt:        var(--marino-profundo);
    --color-superficie:       rgba(255, 255, 255, 0.04);
    --color-superficie-alta:  rgba(255, 255, 255, 0.07);
    --color-borde:            rgba(148, 187, 233, 0.16);
    --color-borde-fuerte:     rgba(56, 189, 248, 0.38);

    --color-texto:            #EAF2FB;
    --color-texto-suave:      #A9BED6;
    /* ⚠️ --color-texto-tenue NO sirve para texto sobre el fondo del sitio.
       Medido sobre el gradiente radial del body —que aclara el azul marino
       hasta rgb(20,62,94) en su punto más intenso— da 2.98:1, por debajo del
       4.5:1 que exige AA. --color-texto-suave da 5.87:1 en ese mismo punto.
       Usarlo sólo para bordes, divisores y controles deshabilitados, que WCAG
       exceptúa de la exigencia de contraste. */
    --color-texto-tenue:      #6F86A3;
    --color-titulo:           var(--blanco);

    --color-acento:           var(--celeste);
    --color-acento-hover:     var(--celeste-fuerte);
    --color-acento-texto:     #04121F; /* texto sobre botón celeste */

    /* --- Estados de formulario ------------------------------------------
       Fuera de la paleta de marca: el rojo y el verde se usan sólo para
       comunicar error y éxito, nunca como color decorativo. */
    --error:        #FF7B72;   /* 6.8:1 sobre azul marino (AA) */
    --error-fondo:  rgba(255, 123, 114, 0.08);
    --error-borde:  rgba(255, 123, 114, 0.45);
    --exito:        #6EE7B7;   /* 10.9:1 sobre azul marino (AAA) */
    --exito-fondo:  rgba(110, 231, 183, 0.08);
    --exito-borde:  rgba(110, 231, 183, 0.4);

    /* --- Gradientes radiales decorativos -------------------------------- */
    --grad-aurora: radial-gradient(
        60% 55% at 12% 8%,
        rgba(56, 189, 248, 0.22) 0%,
        rgba(56, 189, 248, 0) 62%
    );
    --grad-aurora-2: radial-gradient(
        50% 50% at 88% 4%,
        rgba(14, 165, 233, 0.18) 0%,
        rgba(14, 165, 233, 0) 60%
    );
    --grad-superficie: linear-gradient(
        160deg,
        rgba(255, 255, 255, 0.08) 0%,
        rgba(255, 255, 255, 0.02) 100%
    );
    --grad-acento: linear-gradient(100deg, var(--celeste) 0%, var(--celeste-fuerte) 100%);

    /* --- Glassmorphism sutil -------------------------------------------- */
    --glass-blur:       14px;
    --glass-fondo:      rgba(255, 255, 255, 0.045);
    --glass-borde:      1px solid rgba(255, 255, 255, 0.09);
    --glass-sombra:     0 18px 50px -22px rgba(3, 10, 22, 0.85);

    /* --- Elevación ------------------------------------------------------ */
    --sombra-sm:  0 2px 8px -3px rgba(3, 10, 22, 0.5);
    --sombra-md:  0 12px 32px -14px rgba(3, 10, 22, 0.7);
    --sombra-lg:  0 28px 70px -30px rgba(3, 10, 22, 0.9);
    --glow-acento: 0 0 0 1px rgba(56, 189, 248, 0.28),
                   0 12px 38px -14px rgba(56, 189, 248, 0.55);

    /* --- Tipografía ----------------------------------------------------- */
    --font-display: 'Space Grotesk', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-body:    'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-mono:    ui-monospace, 'SFMono-Regular', 'Menlo', monospace;

    --fs-xs:   0.75rem;    /* 12px */
    --fs-sm:   0.875rem;   /* 14px */
    --fs-base: 1rem;       /* 16px */
    --fs-md:   1.125rem;   /* 18px */
    --fs-lg:   clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
    --fs-xl:   clamp(1.5rem, 1.25rem + 1.3vw, 2rem);
    --fs-2xl:  clamp(1.9rem, 1.4rem + 2.4vw, 2.85rem);
    --fs-3xl:  clamp(2.3rem, 1.5rem + 4vw, 4rem);
    --fs-4xl:  clamp(2.8rem, 1.6rem + 6vw, 5.25rem);

    --lh-tight: 1.08;
    --lh-snug:  1.25;
    --lh-base:  1.65;

    --ls-tight:  -0.025em;
    --ls-wide:    0.14em;

    /* --- Espaciado (escala fluida) -------------------------------------- */
    --sp-1:  0.25rem;
    --sp-2:  0.5rem;
    --sp-3:  0.75rem;
    --sp-4:  1rem;
    --sp-5:  1.5rem;
    --sp-6:  2rem;
    --sp-7:  2.5rem;
    --sp-8:  3rem;
    --sp-9:  4rem;
    --sp-10: 5rem;
    --sp-11: 6.5rem;
    --sp-12: 8rem;

    /* --- Layout --------------------------------------------------------- */
    --container-max:      1200px;
    --container-narrow:    760px;
    --container-wide:     1440px;
    --container-pad:      clamp(1.15rem, 4vw, 2.5rem);

    --radio-xs:   6px;
    --radio-sm:  10px;
    --radio-md:  16px;
    --radio-lg:  24px;
    --radio-xl:  32px;
    --radio-pill: 999px;

    /* --- Movimiento ----------------------------------------------------- */
    --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --dur-fast:   160ms;
    --dur-base:   280ms;
    --dur-slow:   620ms;

    /* --- Capas ---------------------------------------------------------- */
    --z-fondo:    0;
    --z-contenido: 10;
    --z-header:   100;
    --z-flotante: 200;
    --z-overlay:  300;

    /* --- Altura del header (la usa el JS y el scroll-padding) -----------
       Valor de partida mobile-first; a partir de 1024px se amplía y, además,
       main.js lo sincroniza con la altura real medida del header. */
    --header-h: 68px;
}

/* Breakpoints de referencia (documentados para JS y para futuras @media):
   sm 480px · md 768px · lg 1024px · xl 1280px                      */


/* ==========================================================================
   3. RESET MODERNO
   ========================================================================== */

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

* {
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Compensa el header sticky al saltar a un ancla. */
    scroll-padding-top: calc(var(--header-h) + var(--sp-4));
    /* Reserva la gutter de la scrollbar: al abrir el drawer se bloquea el
       scroll del body y sin esto el layout saltaría. */
    scrollbar-gutter: stable;
    tab-size: 4;
}

html,
body {
    max-width: 100%;
    overflow-x: clip;
}

body {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-body);
    font-size: var(--fs-base);
    font-weight: 400;
    line-height: var(--lh-base);
    color: var(--color-texto);
    background-color: var(--color-fondo);
    /* Halo radial de fondo: base de la identidad visual. */
    background-image: var(--grad-aurora), var(--grad-aurora-2);
    background-repeat: no-repeat;
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    font-synthesis-weight: none;
}

/* Tipografía de titulares */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: var(--lh-snug);
    letter-spacing: var(--ls-tight);
    color: var(--color-titulo);
    text-wrap: balance;
}

h1 { font-size: var(--fs-3xl); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }
h5, h6 { font-size: var(--fs-md); }

p { text-wrap: pretty; }

a {
    color: var(--color-acento);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out),
                opacity var(--dur-fast) var(--ease-out);
}

a:hover { color: var(--celeste-suave); }

ul, ol { list-style: none; }

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

svg { fill: currentColor; }

input, button, textarea, select {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
}

button { cursor: pointer; }

address { font-style: normal; }

table {
    border-collapse: collapse;
    border-spacing: 0;
}

hr {
    border: 0;
    border-top: 1px solid var(--color-borde);
}

/* Evita que textos largos sin espacios rompan el layout. */
p, li, h1, h2, h3, h4, a, span { overflow-wrap: break-word; }

/* Foco visible y accesible (nunca outline: none sin reemplazo). */
:focus-visible {
    outline: 2px solid var(--color-acento);
    outline-offset: 3px;
    border-radius: var(--radio-xs);
}

::selection {
    background-color: var(--celeste);
    color: var(--marino);
}

/* Scrollbar discreta (WebKit + Firefox) */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--marino-borde) transparent;
}

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background-color: var(--marino-borde);
    border-radius: var(--radio-pill);
    border: 2px solid transparent;
    background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--celeste-fuerte); }

/* Respeta la preferencia de movimiento reducido */
@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;
        scroll-behavior: auto !important;
    }
}

/* Respeta el contraste forzado de Windows */
@media (forced-colors: active) {
    * { border-color: currentColor; }
}


/* ==========================================================================
   4. UTILIDADES BASE
   ========================================================================== */

/* --- 4.1 Contenedores ---------------------------------------------------- */
.container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

.container--narrow { max-width: var(--container-narrow); }
.container--wide   { max-width: var(--container-wide); }
.container--full   { max-width: none; }

/* --- 4.2 Secciones y ritmo vertical --------------------------------------
   El padding se calibró con el contenido real de cada sección. */
.section {
    position: relative;
    padding-block: clamp(3.5rem, 9vw, 7rem);
    z-index: var(--z-contenido);
}

.section--tight  { padding-block: clamp(2.25rem, 5vw, 4rem); }
.section--alt    { background-color: var(--color-fondo-alt); }

/* --- 4.3 Grid ------------------------------------------------------------ */
.grid {
    display: grid;
    gap: var(--sp-6);
    grid-template-columns: 1fr;
}

.grid--2 { --grid-cols: 2; }
.grid--3 { --grid-cols: 3; }
.grid--4 { --grid-cols: 4; }

@media (min-width: 640px) {
    .grid--2, .grid--3, .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
    .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Grillas semánticas reutilizables */
.grid--auto      { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.grid--auto-wide { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }

/* Ubicación explícita en la grilla */
.col-span-2 { grid-column: span 2; }
.col-span-full { grid-column: 1 / -1; }

/* --- 4.4 Espaciado utilitario -------------------------------------------- */
.mt-0 { margin-top: 0; }      .mb-0 { margin-bottom: 0; }
.mt-2 { margin-top: var(--sp-2); } .mb-2 { margin-bottom: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); } .mb-3 { margin-bottom: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); } .mb-4 { margin-bottom: var(--sp-4); }
.mt-5 { margin-top: var(--sp-5); } .mb-5 { margin-bottom: var(--sp-5); }
.mt-6 { margin-top: var(--sp-6); } .mb-6 { margin-bottom: var(--sp-6); }
.mt-8 { margin-top: var(--sp-8); } .mb-8 { margin-bottom: var(--sp-8); }

.pt-6 { padding-top: var(--sp-6); } .pb-6 { padding-bottom: var(--sp-6); }
.pt-8 { padding-top: var(--sp-8); } .pb-8 { padding-bottom: var(--sp-8); }

/* Padding en bloque y ejes (usado por .surface en tarjetas y avisos) */
.p-4 { padding: var(--sp-4); }
.p-5 { padding: var(--sp-5); }
.p-6 { padding: var(--sp-6); }
.p-8 { padding: var(--sp-8); }

.px-4 { padding-inline: var(--sp-4); }
.px-5 { padding-inline: var(--sp-5); }
.px-6 { padding-inline: var(--sp-6); }

.py-4 { padding-block: var(--sp-4); }
.py-5 { padding-block: var(--sp-5); }
.py-6 { padding-block: var(--sp-6); }

.gap-2 { gap: var(--sp-2); } .gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); } .gap-5 { gap: var(--sp-5); }
.gap-6 { gap: var(--sp-6); } .gap-8 { gap: var(--sp-8); }

/* --- 4.5 Alineación y flujo --------------------------------------------- */
.flex     { display: flex; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center   { align-items: center; }
.items-start    { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-center  { justify-content: center; }

.text-center { text-align: center; }
.text-left   { text-align: left; }
.mx-auto     { margin-inline: auto; }

/* --- 4.6 Tipografía utilitaria ------------------------------------------ */
.display   { font-family: var(--font-display); }
.text-muted { color: var(--color-texto-suave); }
/* Alias de .text-muted: un tono más apagado no puede bajar de --color-texto-suave
   sin incumplir AA sobre el gradiente de fondo (ver el :root). */
.text-dim   { color: var(--color-texto-suave); }
.text-accent { color: var(--color-acento); }

.eyebrow {
    display: inline-block;
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-acento);
}

.lead {
    font-size: var(--fs-md);
    line-height: 1.7;
    color: var(--color-texto-suave);
}

/* Tamaño de reserva para un ícono sin contexto propio. Cada componente pasa
   su clase a lucase_icon() y define su medida (.card__icon-svg, .social__svg,
   etc.); esto sólo evita que uno suelto se dibuje al tamaño intrínseco del
   SVG. No afecta a los demás: lucase_icon() reemplaza la clase por defecto. */
.icon {
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
}

.gradient-text {
    background: var(--grad-acento);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* --- 4.7 Superficies glass -------------------------------------------------
   Primitiva reutilizable: la usan las tarjetas, el formulario y los avisos. */
.surface {
    position: relative;
    background-color: var(--glass-fondo);
    background-image: var(--grad-superficie);
    border: var(--glass-borde);
    border-radius: var(--radio-lg);
    box-shadow: var(--glass-sombra);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
    backdrop-filter: blur(var(--glass-blur)) saturate(140%);
}

/* Fallback para navegadores sin backdrop-filter */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .surface { background-color: rgba(19, 43, 77, 0.92); }
}

/* --- 4.8 Accesibilidad -------------------------------------------------- */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    top: -100px;
    left: var(--sp-4);
    z-index: calc(var(--z-overlay) + 1);
    padding: var(--sp-3) var(--sp-5);
    background-color: var(--celeste);
    color: var(--color-acento-texto);
    font-weight: 600;
    border-radius: 0 0 var(--radio-sm) var(--radio-sm);
    transition: top var(--dur-base) var(--ease-out);
}

.skip-link:focus {
    top: 0;
    color: var(--color-acento-texto);
}

/* --- 4.9 Animaciones on-scroll (Intersection Observer) --------------------
   El JS agrega .is-visible cuando el elemento entra en viewport.
   Sin JS (html.no-js) todo se muestra siempre, sin animación.            */
.reveal {
    opacity: 0;
    transform: translate3d(0, 26px, 0);
    transition: opacity var(--dur-slow) var(--ease-out),
                transform var(--dur-slow) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
}

.reveal--left  { transform: translate3d(-28px, 0, 0); }
.reveal--right { transform: translate3d(28px, 0, 0); }
.reveal--zoom  { transform: scale(0.96); }

.reveal.is-visible {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* Sin JS o con movimiento reducido: contenido siempre visible. */
.no-js .reveal,
.reveal.is-visible {
    opacity: 1;
}

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

/* Animación de pulso, compartida por el marcador del hero y otros detalles
   decorativos. Las animaciones de flotación y marquesina que existían acá se
   eliminaron en la etapa 7: no las usaba ninguna regla. */
@keyframes lucase-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.5); }
    70%  { box-shadow: 0 0 0 14px rgba(56, 189, 248, 0); }
    100% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); }
}


/* ==========================================================================
   5. COMPONENTES
   --------------------------------------------------------------------------
   Etapa 2: botones, header sticky con blur, navegación (barra + drawer),
   hero con canvas y sus animaciones de entrada.

   Ya construidos: .card, .site-footer, .float-wa, .coverage-*, el formulario
   ========================================================================== */

/* --------------------------------------------------------------------------
   5.1 LAYOUT RAÍZ
   -------------------------------------------------------------------------- */
.site-main {
    flex: 1 0 auto;
}

/* Bloqueo de scroll mientras el drawer está abierto. La clase la pone main.js
   en <body>. `overflow: hidden` conserva la posición de scroll. */
body.nav-abierto {
    overflow: hidden;
}


/* --------------------------------------------------------------------------
   5.2 BOTONES
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: 0.8rem 1.5rem;
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.01em;
    text-align: center;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: var(--radio-pill);
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

.btn:active {
    transform: translateY(1px);
}

/* Sólido celeste — 8.8:1 de contraste con el texto azul marino (AAA) */
.btn--primary {
    background-image: var(--grad-acento);
    background-color: var(--celeste);
    color: var(--color-acento-texto);
    box-shadow: 0 10px 26px -14px rgba(56, 189, 248, 0.85);
}

.btn--primary:hover {
    color: var(--color-acento-texto);
    box-shadow: 0 14px 34px -12px rgba(56, 189, 248, 1);
    filter: brightness(1.06);
}

/* Contorno blanco translúcido */
.btn--outline {
    background-color: rgba(255, 255, 255, 0.02);
    border-color: rgba(255, 255, 255, 0.42);
    color: var(--color-titulo);
}

.btn--outline:hover {
    background-color: rgba(255, 255, 255, 0.1);
    border-color: var(--blanco);
    color: var(--color-titulo);
}

/* Secundario discreto */
.btn--ghost {
    border-color: var(--color-borde);
    color: var(--color-texto-suave);
}

.btn--ghost:hover {
    background-color: var(--color-superficie);
    border-color: var(--color-borde-fuerte);
    color: var(--color-titulo);
}

.btn--lg {
    padding: 1rem 1.9rem;
    font-size: var(--fs-base);
}

.btn--sm {
    padding: 0.55rem 1.05rem;
    font-size: var(--fs-xs);
}

.btn__icon {
    flex: none;
    width: 1.15em;
    height: 1.15em;
}


/* --------------------------------------------------------------------------
   5.3 HEADER STICKY
   --------------------------------------------------------------------------
   El backdrop-blur vive en el ::before, NO en .site-header: un ancestro con
   filter/backdrop-filter se convierte en containing block y rompería el
   position:fixed del drawer.
   -------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   Ámbito de la barra clara
   ---------------------------------------------------------------------------
   Al redefinir los tokens semánticos dentro de la cabecera, su drawer y el
   pie, todos sus componentes (navegación, botones, redes, enlaces legales)
   se recolorean solos, sin tocar una sola regla. Es la ventaja de que desde
   la etapa 1 todo se pinte con tokens y no con colores crudos.
   ------------------------------------------------------------------------- */
.site-header,
.nav,
.site-footer {
    --color-titulo:          var(--barra-texto);
    --color-texto:           var(--barra-texto);
    --color-texto-suave:     var(--barra-suave);
    --color-texto-tenue:     var(--barra-suave);
    --color-acento:          var(--barra-acento);
    --color-acento-hover:    var(--barra-acento-osc);
    --color-acento-texto:    #FFFFFF;
    --color-borde:           var(--barra-borde);
    --color-borde-fuerte:    var(--barra-borde-fuerte);
    --color-superficie:      rgba(16, 26, 40, 0.04);
    --color-superficie-alta: rgba(16, 26, 40, 0.08);
    --grad-acento:           linear-gradient(100deg, var(--barra-acento) 0%, var(--barra-acento-osc) 100%);
    --grad-superficie:       linear-gradient(160deg, var(--barra-alta) 0%, var(--barra) 100%);
}

.site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    display: flex;
    align-items: center;
    min-height: var(--header-h);
}

/* Barra de la cabecera en gris neutro. Se ve desde el primer píxel (antes era
   transparente y sólo aparecía al scrollear): así el logo blanco apoya siempre
   sobre el mismo fondo y no sobre el azul marino del hero. */
.site-header::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: rgba(244, 245, 247, 0.94);
    border-bottom: 1px solid var(--barra-borde);
    -webkit-backdrop-filter: blur(10px) saturate(120%);
    backdrop-filter: blur(10px) saturate(120%);
    transition: background-color var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

/* Al scrollear se opaca y se intensifica el blur (main.js agrega .is-scrolled) */
.site-header.is-scrolled::before {
    background-color: rgba(244, 245, 247, 0.99);
    border-bottom-color: var(--barra-borde-fuerte);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    box-shadow: 0 12px 36px -24px rgba(16, 26, 40, 0.28);
}

.site-header__inner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    width: 100%;
    min-height: var(--header-h);
}


/* --------------------------------------------------------------------------
   5.4 MARCA
   -------------------------------------------------------------------------- */
.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    flex: none;
    color: var(--color-titulo);
    border-radius: var(--radio-sm);
}

.brand:hover {
    color: var(--color-titulo);
}

/* Logo: arte en azul marino y azul sobre transparente, recortado al logotipo.
   Quedaron fuera la bajada "RASTREO SATELITAL & GESTIÓN DE FLOTAS" (mediría
   2 px y sería un manchón ilegible) y el arco de la órbita (suelto se leía
   como un paréntesis después de la T).

   El archivo mide 1200x156 (~7.7:1), así que se fija la altura y el ancho
   sale solo. El `max-width` es la red de seguridad: si el ancho resultante no
   entra, el logo se achica proporcionalmente en lugar de desbordar.

   Los tamaños están calculados sobre el espacio REAL disponible en cada
   ancho, que lo limita distinto según el breakpoint:
     · en mobile, la hamburguesa (46px) más la separación;
     · en escritorio, la navegación centrada — a 1024px sólo quedan 278px
       para la marca y a 1280px, 324px.
   Por eso el logo crece hasta 480px, se mantiene y recién vuelve a crecer a
   partir de 1280px, cuando la barra tiene aire de nuevo.

   El pie usa exactamente los mismos tamaños (ver .footer-col--marca), así que
   las dos piezas quedan siempre a la par. */
.brand__logo {
    width: auto;
    height: 29px;
    max-width: 210px;
    object-fit: contain;
}

@media (min-width: 360px) {
    .brand__logo {
        height: 34px;
        max-width: 250px;
    }
}

@media (min-width: 480px) {
    .brand__logo {
        height: 36px;
        max-width: 264px;
    }
}

/* Desde 1024px la navegación centrada entra en escena y es la que pone el
   límite: medida, ocupa 368px a 1024px y 433px a 1280px. A 1024px el menú
   empieza en x=328, así que con la marca arrancando en x=40 el logo no puede
   pasar de ~268px si queremos dejar aire. Por eso se mantiene en 264px hasta
   1279px en lugar de crecer y tener que encogerse justo al aparecer el menú. */
@media (min-width: 1280px) {
    .brand__logo {
        height: 41px;
        max-width: 300px;
    }
}

/* Si logo.png no existe, main.js agrega .brand--sin-logo y se muestra el
   logotipo tipográfico de respaldo. */
.brand__fallback {
    display: none;
    align-items: center;
    gap: 0.6rem;
}

.brand--sin-logo .brand__logo { display: none; }
.brand--sin-logo .brand__fallback { display: inline-flex; }

.brand__mark {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background-image: var(--grad-acento);
    box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.35),
                0 8px 22px -10px rgba(56, 189, 248, 0.9);
}

.brand__text {
    display: flex;
    flex-direction: column;
    line-height: 1;
}

.brand__name {
    font-family: var(--font-display);
    font-size: 1.16rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.brand__claim {
    margin-top: 3px;
    font-size: 0.6rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    /* La marca está justo en la zona más clara del gradiente de fondo: con
       --color-texto-tenue daba 3.20:1 y no pasaba AA. */
    color: var(--color-texto-suave);
}


/* --------------------------------------------------------------------------
   5.5 NAVEGACIÓN — MOBILE: drawer lateral
   -------------------------------------------------------------------------- */
.nav {
    position: fixed;
    top: var(--header-h);
    right: 0;
    bottom: 0;
    z-index: calc(var(--z-header) + 60);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    width: min(86vw, 340px);
    padding: var(--sp-5) var(--sp-6) calc(var(--sp-6) + env(safe-area-inset-bottom, 0px));
    /* El drawer es la navegación de la cabecera en mobile: mismo gris que la
       barra, para que no se vea un panel azul saliendo de una barra gris. */
    background-color: var(--barra);
    background-image: var(--grad-superficie);
    border-left: 1px solid var(--barra-borde);
    box-shadow: -30px 0 70px -34px rgba(0, 0, 0, 0.9);
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--dur-base) var(--ease-out),
                visibility 0s linear var(--dur-base);
}

.nav.is-open {
    transform: none;
    visibility: visible;
    transition-delay: 0s, 0s;
}

/* Cabecera del drawer */
.nav__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
}

.nav__title {
    font-family: var(--font-display);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-texto-suave);
}

.nav__close {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex: none;
    color: var(--color-texto-suave);
    border: 1px solid var(--barra-borde);
    border-radius: var(--radio-sm);
    transition: color var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out);
}

.nav__close:hover {
    color: var(--color-titulo);
    border-color: var(--barra-borde-fuerte);
    background-color: var(--color-superficie);
}

.nav__list {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
}

.nav__link {
    display: block;
    padding: 0.85rem 0.25rem;
    font-family: var(--font-display);
    font-size: var(--fs-md);
    font-weight: 500;
    color: var(--color-texto-suave);
    border-bottom: 1px solid var(--barra-borde);
    transition: color var(--dur-fast) var(--ease-out),
                padding-left var(--dur-base) var(--ease-out);
}

.nav__link:hover {
    color: var(--color-titulo);
    padding-left: 0.6rem;
}

.nav__link.is-active {
    color: var(--color-acento);
    padding-left: 0.6rem;
}

.nav__actions {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    margin-top: auto;
}

.nav__cta {
    width: 100%;
}

/* Velo del drawer */
.nav-overlay {
    position: fixed;
    inset: 0;
    /* Por debajo del header (z-index 100): el drawer vive dentro del header,
       así que quedaría tapado si el velo se apilara más arriba. */
    z-index: calc(var(--z-header) - 10);
    background-color: rgba(4, 10, 20, 0.62);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out),
                visibility 0s linear var(--dur-base);
}

.nav-overlay.is-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s, 0s;
}


/* --------------------------------------------------------------------------
   5.6 HAMBURGUESA ANIMADA (3 barras → X)
   -------------------------------------------------------------------------- */
.nav-toggle {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    flex: none;
    color: var(--color-titulo);
    background-color: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--barra-borde);
    border-radius: var(--radio-sm);
    transition: border-color var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out);
}

.nav-toggle:hover {
    border-color: var(--barra-borde-fuerte);
    background-color: rgba(255, 255, 255, 0.1);
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
    display: block;
    width: 20px;
    height: 2px;
    border-radius: 2px;
    background-color: currentColor;
    transition: transform var(--dur-base) var(--ease-out),
                opacity var(--dur-fast) linear,
                background-color var(--dur-fast) linear;
}

.nav-toggle__bars {
    position: relative;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
    content: '';
    position: absolute;
    left: 0;
}

.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after  { top: 6px; }

/* Estado abierto: la barra central desaparece y las otras rotan a X.
   Se engancha de la clase del <body> para no depender de JS extra. */
body.nav-abierto .nav-toggle__bars {
    background-color: transparent;
}

body.nav-abierto .nav-toggle__bars::before {
    transform: translateY(6px) rotate(45deg);
    background-color: var(--celeste);
}

body.nav-abierto .nav-toggle__bars::after {
    transform: translateY(-6px) rotate(-45deg);
    background-color: var(--celeste);
}


/* ---------------------------------------------------------------------------
   5.7 HERO · Foto a sangre completa con el contenido por encima
   ---------------------------------------------------------------------------
   La foto llena el ancho y el alto libre de la ventana. El texto va abajo a
   la izquierda, sobre un velo oscuro que asegura el contraste, y las
   capacidades en una franja al pie.
   ------------------------------------------------------------------------- */
.hero {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 560px;
    min-height: max(560px, calc(100svh - var(--header-h)));
    /* El padding inferior reserva el alto del indicador de scroll, que va
       absoluto sobre la base: así no se monta sobre la franja. */
    padding-block: var(--sp-7) clamp(5rem, 7vw, 6rem);
    overflow: hidden;
}

/* --- Capa de fondo -------------------------------------------------------- */
.hero__fondo {
    position: absolute;
    inset: 0;
    z-index: -2;
}

.hero__fondo-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Los camiones están a la izquierda del encuadre: se ancla ahí para no
       perderlos cuando la pantalla es angosta. */
    object-position: 40% 50%;
}

/* Respaldo mientras no exista la foto: un degradado digno en su lugar. */
.hero__fondo-slot {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--font-body);
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-texto-tenue);
    background-color: var(--color-fondo);
    background-image: var(--grad-aurora);
}

/* Estados que aplica main.js según cargue o no la imagen. */
.hero__fondo.is-loaded .hero__fondo-slot { display: none; }
.hero__fondo.is-missing .hero__fondo-img { display: none; }

/* Velo: carga el oscuro sobre la izquierda (donde va el texto) y sobre la
   base, y deja respirar el cielo del centro-derecha. */
.hero__velo {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(
            100deg,
            rgba(4, 11, 24, 0.95) 0%,
            rgba(4, 11, 24, 0.84) 32%,
            rgba(4, 11, 24, 0.44) 62%,
            rgba(4, 11, 24, 0.24) 100%
        ),
        linear-gradient(
            to top,
            rgba(4, 11, 24, 0.92) 0%,
            rgba(4, 11, 24, 0.35) 26%,
            rgba(4, 11, 24, 0) 52%
        );
}

/* --- Contenido ------------------------------------------------------------ */
.hero__inner {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--sp-7);
    width: 100%;
    margin-top: auto;
}

.hero__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-4);
    max-width: 42rem;
}

.hero__eyebrow {
    color: var(--celeste-suave);
}

.hero__title {
    font-family: var(--font-display);
    font-size: var(--fs-3xl);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.03em;
    color: var(--blanco);
    text-wrap: balance;
    text-shadow: 0 2px 32px rgba(4, 11, 24, 0.6);
}

/* Fragmento del título pintado con el celeste de la marca. */
.hero__destaque {
    color: var(--celeste);
}

.hero__subtitle {
    max-width: 34rem;
    font-size: var(--fs-md);
    line-height: 1.6;
    color: var(--celeste-suave);
    text-shadow: 0 1px 18px rgba(4, 11, 24, 0.65);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-top: var(--sp-2);
}

.hero__cta-flecha {
    width: 1.05em;
    height: 1.05em;
    transition: transform var(--dur-base) var(--ease-out);
}

.hero__cta:hover .hero__cta-flecha {
    transform: translateX(3px);
}

/* --- Franja de capacidades ------------------------------------------------ */
.hero__franja {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-4) var(--sp-5);
    padding-top: var(--sp-5);
    border-top: 1px solid rgba(255, 255, 255, 0.16);
}

.hero__franja-item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    min-width: 0;
}

.hero__franja-icono {
    display: grid;
    place-items: center;
    flex: none;
    width: 38px;
    height: 38px;
    color: var(--celeste);
    background-color: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 11px;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.hero__franja-svg {
    width: 20px;
    height: 20px;
}

.hero__franja-label {
    font-size: var(--fs-sm);
    font-weight: 500;
    line-height: 1.3;
    color: var(--color-texto);
}

/* Remate: la frase de cierre, como sello en la esquina inferior derecha.
   Va absoluto y alineado al padding del contenedor para quedar pegado al
   borde del sitio, no al de la ventana. */
.hero__remate {
    display: none;
    position: absolute;
    right: clamp(1.15rem, 4vw, 2.5rem);
    bottom: clamp(1.6rem, 3.4vw, 2.4rem);
    z-index: 3;
    max-width: 16rem;
    margin: 0;
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    text-align: right;
    color: var(--color-texto-suave);
}

/* Se muestra recién cuando hay ancho para que conviva con el indicador de
   scroll sin pisarlo. */
@media (min-width: 768px) {
    .hero__remate {
        display: block;
    }
}


/* --------------------------------------------------------------------------
   5.8 INDICADOR DE SCROLL
   -------------------------------------------------------------------------- */
.scroll-cue {
    position: absolute;
    left: 50%;
    bottom: clamp(1.1rem, 3vw, 2rem);
    z-index: 3;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    transform: translateX(-50%);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    /* --color-texto-suave da 9.1:1 sobre el azul marino (AAA) */
    color: var(--color-texto-suave);
    transition: color var(--dur-base) var(--ease-out);
}

.scroll-cue:hover {
    color: var(--color-acento);
}

.scroll-cue__mouse {
    display: grid;
    justify-items: center;
    width: 26px;
    height: 42px;
    padding-top: 7px;
    border: 1.5px solid currentColor;
    border-radius: var(--radio-pill);
}

.scroll-cue__wheel {
    width: 3px;
    height: 8px;
    border-radius: 2px;
    background-color: currentColor;
    animation: lucase-wheel 1.9s var(--ease-in-out) infinite;
}


/* --------------------------------------------------------------------------
   5.9 ANIMACIONES
   -------------------------------------------------------------------------- */
@keyframes lucase-hero-in {
    from {
        opacity: 0;
        transform: translate3d(0, 26px, 0);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes lucase-glow {
    0%, 100% { opacity: 0.72; transform: scale(0.96); }
    50%      { opacity: 1;    transform: scale(1.05); }
}

@keyframes lucase-wheel {
    0%   { opacity: 0; transform: translateY(0); }
    25%  { opacity: 1; }
    75%  { opacity: 1; transform: translateY(11px); }
    100% { opacity: 0; transform: translateY(13px); }
}

/* Entrada del hero: fade + slide escalonado por hijo de .hero__content.
   El `both` mantiene el estado inicial durante el retardo. */
.hero__content > *,
.hero__franja,
.hero__remate {
    animation: lucase-hero-in 900ms var(--ease-out) both;
}

.hero__content > *:nth-child(1) { animation-delay: 80ms; }
.hero__content > *:nth-child(2) { animation-delay: 200ms; }
.hero__content > *:nth-child(3) { animation-delay: 340ms; }
.hero__content > *:nth-child(4) { animation-delay: 470ms; }
.hero__franja { animation-delay: 560ms; }
.hero__remate { animation-delay: 660ms; }

@media (prefers-reduced-motion: reduce) {
    .hero__content > *,
    .hero__franja,
    .hero__remate {
        animation: none;
        opacity: 1;
        transform: none;
    }

    .scroll-cue__wheel {
        animation: none;
    }
}

/* Sin JavaScript el drawer no se puede abrir: se muestra la navegación
   en línea para no dejar el menú inaccesible. */
.no-js .nav {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-5);
    width: auto;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    overflow: visible;
    transform: none;
    visibility: visible;
}

.no-js .nav__head,
.no-js .nav__close,
.no-js .nav-toggle { display: none; }

.no-js .nav__list {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--sp-4);
}

.no-js .nav__link {
    padding: 0.35rem 0.2rem;
    font-size: var(--fs-sm);
    border-bottom: 0;
}

.no-js .nav__actions {
    flex-direction: row;
    margin-top: 0;
}

.no-js .nav__cta { width: auto; }
.no-js .nav-overlay { display: none; }


/* --------------------------------------------------------------------------
   5.10 CABECERA DE SECCIÓN + CHIP
   -------------------------------------------------------------------------- */

/* Más aire vertical que una sección estándar (espacio negativo). */
.section--spacious {
    padding-block: clamp(4.5rem, 11vw, 8.5rem);
}

.section--glow {
    position: relative;
}

/* Halo radial muy suave en la parte superior de la sección. */
.section--glow::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: radial-gradient(
        62% 52% at 50% 0%,
        rgba(56, 189, 248, 0.1) 0%,
        rgba(56, 189, 248, 0) 72%
    );
}

.section--glow > .container {
    position: relative;
    z-index: 1;
}

.section-head {
    max-width: 44rem;
    margin-bottom: clamp(2.75rem, 6vw, 4.5rem);
}

.section-head--center {
    margin-inline: auto;
    text-align: center;
}

.section-head__title {
    margin-top: var(--sp-5);
    font-size: clamp(1.8rem, 1.35rem + 1.9vw, 2.7rem);
    letter-spacing: -0.028em;
}

.section-head__lead {
    margin-top: var(--sp-5);
}

/* Etiqueta pequeña tipo chip, arriba del título */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.42rem 0.95rem 0.42rem 0.75rem;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    /* --celeste-suave sobre azul marino: 13:1 (AAA) */
    color: var(--celeste-suave);
    background-color: rgba(56, 189, 248, 0.08);
    border: 1px solid rgba(56, 189, 248, 0.22);
    border-radius: var(--radio-pill);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.chip::before {
    content: '';
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: var(--celeste);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.18);
}


/* --------------------------------------------------------------------------
   5.11 GRILLAS DE TARJETAS
   Los breakpoints (480 · 768 · 1024 · 1280) están en la sección 6.
   -------------------------------------------------------------------------- */
.benefits-grid,
.services-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.15rem, 2.4vw, 1.75rem);
}


/* --------------------------------------------------------------------------
   5.12 TARJETAS (beneficios y servicios)
   -------------------------------------------------------------------------- */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    padding: clamp(1.6rem, 3vw, 2.1rem);
    background-color: var(--glass-fondo);
    background-image: var(--grad-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-lg);
    overflow: hidden;
    transition: transform var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

/* Borde celeste animado: un anillo de 1px pintado con un gradiente que barre
   en diagonal. El mask deja visible únicamente el anillo. */
.card::after {
    content: '';
    position: absolute;
    inset: 0;
    padding: 1px;
    border-radius: inherit;
    background-image: linear-gradient(
        115deg,
        rgba(56, 189, 248, 0) 20%,
        var(--celeste) 38%,
        var(--celeste-suave) 50%,
        var(--celeste) 62%,
        rgba(56, 189, 248, 0) 80%
    );
    background-size: 250% 250%;
    background-position: 0% 50%;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out);
}

/* Elevación + glow celeste. Sombras siempre difusas y de spread negativo. */
.card:hover,
.card:focus-within {
    transform: translateY(-5px);
    background-color: var(--color-superficie-alta);
    border-color: rgba(56, 189, 248, 0.42);
    box-shadow: 0 28px 70px -44px rgba(56, 189, 248, 0.85),
                0 0 0 1px rgba(56, 189, 248, 0.07);
}

.card:hover::after,
.card:focus-within::after {
    opacity: 1;
    animation: lucase-border-sweep 2.8s linear infinite;
}

/* --- Ícono ---------------------------------------------------------------- */
.card__icon {
    position: relative;
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    margin-bottom: var(--sp-2);
    color: var(--celeste);
    background-color: rgba(56, 189, 248, 0.09);
    border: 1px solid rgba(56, 189, 248, 0.18);
    border-radius: 15px;
    transition: transform var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

.card__icon-svg {
    width: 30px;
    height: 30px;
}

.card:hover .card__icon,
.card:focus-within .card__icon {
    transform: translateY(-3px) scale(1.07);
    background-color: rgba(56, 189, 248, 0.17);
    border-color: rgba(56, 189, 248, 0.42);
    box-shadow: 0 0 0 7px rgba(56, 189, 248, 0.06),
                0 16px 34px -18px rgba(56, 189, 248, 0.9);
}

/* Los beneficios tienen el ícono un punto más grande. */
.card--benefit .card__icon {
    width: 56px;
    height: 56px;
}

.card--benefit .card__icon-svg {
    width: 34px;
    height: 34px;
}

/* Los servicios usan el tamaño del .card base. Se declara explícitamente para
   que el modificador exista en el CSS y no dependa de la ausencia de un
   override: así el HTML no tiene clases sin definir. */
.card--service .card__icon {
    width: 52px;
    height: 52px;
}

.card--service .card__icon-svg {
    width: 30px;
    height: 30px;
}

/* --- Texto ---------------------------------------------------------------- */
.card__title {
    /* Más chico que --fs-lg: en grillas de 3-4 columnas un titular de 24px
       parte los títulos en tres líneas y desordena las tarjetas. */
    font-size: clamp(1.0625rem, 1rem + 0.28vw, 1.1875rem);
    line-height: 1.32;
}

.card__text {
    font-size: var(--fs-sm);
    line-height: 1.7;
    color: var(--color-texto-suave);
}


/* --- Segmentos: LUCESAT Personal y LUCESAT Empresas ----------------------
   Dos tarjetas que reutilizan la superficie de .card. El ancho mínimo de
   columna es 22rem: con dos tarjetas pasan a dos columnas solas en cuanto
   hay espacio, sin necesidad de un breakpoint. */
.segmentos-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
    gap: clamp(1.15rem, 2.4vw, 1.75rem);
}

/* El contenido va alineado a la izquierda (los botones no se estiran) y el
   CTA se empuja al fondo para que las dos tarjetas lo alineen. */
.card--segmento {
    align-items: flex-start;
    gap: var(--sp-4);
}

.segmento__etiqueta {
    font-family: var(--font-display);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--color-acento);
}

.card--empresas .segmento__etiqueta {
    color: var(--celeste-suave);
}

/* Rubros: pastillas sueltas, que se acomodan solas según el largo. */
.segmento__rubros {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-1);
}

.segmento__rubros li {
    padding: 0.42rem 0.9rem;
    font-size: var(--fs-sm);
    font-weight: 500;
    line-height: 1.2;
    color: var(--color-texto-suave);
    background-color: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: 999px;
}

.segmento__cta {
    margin-top: auto;
    padding-top: 0.8rem;
}

.segmento__flecha {
    width: 1.05em;
    height: 1.05em;
    transition: transform var(--dur-base) var(--ease-out);
}

.segmento__cta:hover .segmento__flecha {
    transform: translateX(3px);
}


/* --------------------------------------------------------------------------
   5.13 MICROINTERACCIÓN DE ÍCONOS
   --------------------------------------------------------------------------
   Auto-dibujo: cada trazo deja de estar dibujado y se redibuja al pasar el
   mouse. Funciona porque cada elemento del SVG declara pathLength="100", lo
   que normaliza su longitud y hace que todos los íconos dibujen al mismo
   ritmo sin importar su tamaño real.
   -------------------------------------------------------------------------- */
.card__icon-svg :not(.is-dashed) {
    stroke-dasharray: 102;
    stroke-dashoffset: 0;
}

/* Las geocercas conservan su patrón punteado y quedan fuera del auto-dibujo. */
.card__icon-svg .is-dashed {
    stroke-dasharray: 3 2.6;
}

.card:hover .card__icon-svg :not(.is-dashed),
.card:focus-within .card__icon-svg :not(.is-dashed) {
    animation: lucase-icon-draw 820ms var(--ease-out);
}

@keyframes lucase-border-sweep {
    from { background-position: 0% 50%; }
    to   { background-position: 200% 50%; }
}

@keyframes lucase-icon-draw {
    from { stroke-dashoffset: 102; }
    to   { stroke-dashoffset: 0; }
}

/* Si el navegador no soporta mask-composite, el anillo no se dibuja:
   el borde celeste del :hover sigue funcionando igual. */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
    .card::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .card:hover,
    .card:focus-within,
    .card:hover .card__icon,
    .card:focus-within .card__icon {
        transform: none;
    }

    .card:hover::after,
    .card:focus-within::after,
    .card:hover .card__icon-svg :not(.is-dashed),
    .card:focus-within .card__icon-svg :not(.is-dashed) {
        animation: none;
    }
}

/* --------------------------------------------------------------------------
   5.14 APP MÓVIL
   -------------------------------------------------------------------------- */
.app-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 4.5rem);
    align-items: center;
}

/* min-width: 0 evita que una palabra larga estire la columna del grid y
   desborde el layout. */
.app-content {
    min-width: 0;
}

/* Cabecera de sección alineada a la izquierda (dentro de una columna). */
.section-head--left {
    max-width: 34rem;
    margin-bottom: clamp(2rem, 4vw, 2.75rem);
}

/* --- Lista de features ---------------------------------------------------- */
.app-features {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.app-feature {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    font-size: var(--fs-sm);
    line-height: 1.6;
    color: var(--color-texto-suave);
}

.app-feature__check {
    flex: none;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    margin-top: 1px;
    color: var(--celeste);
    transition: transform var(--dur-base) var(--ease-out);
}

.app-feature__check-svg {
    width: 22px;
    height: 22px;
}

/* Mismo motivo que .app-content: permite que el texto se envuelva en lugar de
   empujar el ancho del ítem flexible. */
.app-feature__text {
    min-width: 0;
}

.app-feature:hover .app-feature__check {
    transform: scale(1.16);
}

/* El check "brota" cuando el observer revela el ítem. `backwards` mantiene el
   estado inicial durante el retardo escalonado que fija main.js. */
.app-feature.is-visible .app-feature__check {
    animation: lucase-check-pop 520ms var(--ease-out) backwards;
    animation-delay: var(--reveal-delay, 0ms);
}

@keyframes lucase-check-pop {
    from { opacity: 0; transform: scale(0.4) rotate(-14deg); }
    to   { opacity: 1; transform: none; }
}

/* --- Badges de descarga --------------------------------------------------- */
.app-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-top: clamp(2rem, 4vw, 2.75rem);
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 1.05rem;
    color: var(--color-titulo);
    background-color: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--color-borde);
    border-radius: 13px;
    transition: transform var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

.badge:hover {
    color: var(--color-titulo);
    transform: translateY(-2px);
    background-color: rgba(255, 255, 255, 0.09);
    border-color: var(--color-borde-fuerte);
    box-shadow: 0 16px 34px -22px rgba(56, 189, 248, 0.7);
}

.badge__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
}

.badge__glyph {
    width: 24px;
    height: 24px;
}

.badge__text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.badge__text small {
    font-size: 0.58rem;
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    /* --color-texto-suave da 9:1 sobre el fondo del badge (AAA) */
    color: var(--color-texto-suave);
}

.badge__text strong {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 600;
}

/* --- Mockup del teléfono -------------------------------------------------- */
.app-visual {
    position: relative;
    display: grid;
    place-items: center;
}

.app-glow {
    position: absolute;
    z-index: 0;
    width: 74%;
    aspect-ratio: 1;
    border-radius: 50%;
    background-image: radial-gradient(
        circle,
        rgba(56, 189, 248, 0.5) 0%,
        rgba(14, 165, 233, 0.2) 45%,
        rgba(56, 189, 248, 0) 70%
    );
    filter: blur(46px);
    pointer-events: none;
}

.app-phone {
    position: relative;
    z-index: 1;
    width: min(280px, 74vw);
    margin: 0;
    padding: 10px;
    aspect-ratio: 9 / 19;
    background-color: rgba(10, 26, 51, 0.72);
    border: 1px solid var(--color-borde-fuerte);
    border-radius: 40px;
    box-shadow: 0 46px 100px -52px rgba(56, 189, 248, 0.75),
                var(--sombra-lg);
    overflow: hidden;
}

.app-phone__img {
    position: relative;
    z-index: 2;
    width: 100%;
    height: 100%;
    border-radius: 30px;
    object-fit: cover;
}

/* Muesca superior, por encima de la captura. */
.app-phone::after {
    content: '';
    position: absolute;
    top: 13px;
    left: 50%;
    z-index: 3;
    width: 34%;
    height: 17px;
    transform: translateX(-50%);
    background-color: rgba(6, 14, 28, 0.92);
    border-radius: var(--radio-pill);
}

/* Slot visible mientras no exista /assets/img/app-mockup.webp */
.app-phone__slot {
    position: absolute;
    inset: 10px;
    z-index: 1;
    display: grid;
    place-items: center;
    padding: 0 var(--sp-3);
    border-radius: 30px;
    background-color: rgba(56, 189, 248, 0.06);
    background-image:
        linear-gradient(rgba(56, 189, 248, 0.09) 1px, transparent 1px),
        linear-gradient(90deg, rgba(56, 189, 248, 0.09) 1px, transparent 1px);
    background-size: 26px 26px;
}

.app-phone__slot-label {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    line-height: 1.5;
    color: var(--color-texto-suave);
    text-align: center;
    overflow-wrap: anywhere;
}

/* Estados que aplica main.js según cargue o no el mockup. */
.app-phone.is-loaded .app-phone__slot { display: none; }
.app-phone.is-missing .app-phone__img { display: none; }


/* --------------------------------------------------------------------------
   5.15 COBERTURA Y UBICACIÓN
   -------------------------------------------------------------------------- */
.coverage-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 3vw, 2.25rem);
    align-items: stretch;
}

/* --- Marco del mapa ------------------------------------------------------- */
.coverage-map {
    position: relative;
    min-height: clamp(320px, 44vh, 470px);
    background-color: var(--marino-profundo);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-lg);
    box-shadow: var(--glass-sombra);
    overflow: hidden;
}

.coverage-map__canvas {
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* OpenStreetMap sirve teselas claras, que rompen el tema oscuro del sitio.
   Se las invierte por CSS (técnica estándar de "OSM en modo oscuro") en lugar
   de depender de un segundo proveedor de mapas.
   El filtro va SÓLO sobre el pane de teselas: el marcador, los controles de
   zoom y la atribución quedan sin alterar. */
.coverage-map .leaflet-tile-pane {
    filter: invert(1) hue-rotate(180deg) brightness(0.94) contrast(0.92) saturate(0.7);
}

/* Respaldo estático: sin JavaScript, o si Leaflet no carga. */
.coverage-map__fallback {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: none;
    place-content: center;
    justify-items: center;
    gap: var(--sp-4);
    padding: var(--sp-6);
    text-align: center;
    background-image: radial-gradient(
        70% 60% at 50% 40%,
        rgba(56, 189, 248, 0.12) 0%,
        rgba(56, 189, 248, 0) 72%
    );
}

.coverage-map__fallback-pin {
    color: var(--celeste);
}

.coverage-map__fallback-svg {
    width: 34px;
    height: 34px;
}

.coverage-map__fallback-text {
    font-size: var(--fs-sm);
    line-height: 1.6;
    color: var(--color-texto-suave);
}

.no-js .coverage-map__fallback,
.coverage-map.is-unavailable .coverage-map__fallback {
    display: grid;
}

/* Sin Leaflet no tiene sentido dejar el contenedor vacío a la vista. */
.coverage-map.is-unavailable .coverage-map__canvas {
    display: none;
}

/* --- Ajustes sobre el CSS de Leaflet --------------------------------------
   La hoja de Leaflet se carga después de esta, así que se la sobreescribe por
   especificidad (`.coverage-map .leaflet-…`) y no con !important. */
.coverage-map .leaflet-container {
    font-family: var(--font-body);
    background-color: var(--marino-profundo);
}

.coverage-map .leaflet-bar {
    border: 0;
    box-shadow: var(--sombra-md);
}

.coverage-map .leaflet-control-zoom a {
    width: 34px;
    height: 34px;
    line-height: 32px;
    font-size: 18px;
    color: var(--color-titulo);
    background-color: rgba(10, 26, 51, 0.86);
    border-color: var(--color-borde);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    transition: background-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
}

.coverage-map .leaflet-control-zoom a:hover,
.coverage-map .leaflet-control-zoom a:focus {
    color: var(--color-acento-texto);
    background-color: var(--celeste);
}

/* Único uso legítimo de --color-texto-tenue: un control deshabilitado, que
   WCAG 1.4.3 exceptúa expresamente de la exigencia de contraste. Que se vea
   apagado es justamente la señal de que no está disponible. */
.coverage-map .leaflet-control-zoom a.leaflet-disabled {
    color: var(--color-texto-tenue);
    background-color: rgba(10, 26, 51, 0.6);
}

/* La atribución de OpenStreetMap es obligatoria: se estiliza, no se oculta.
   Ojo con la especificidad: Leaflet define
   `.leaflet-container .leaflet-control-attribution { background: #fff }`, que
   empata en (0,2,0) con un selector de dos clases y gana por orden de carga.
   Por eso acá se usa un selector de tres clases. */
.coverage-map .leaflet-container .leaflet-control-attribution {
    padding: 2px 8px;
    font-size: 10px;
    color: var(--color-texto-suave);
    background-color: rgba(10, 26, 51, 0.82);
}

.coverage-map .leaflet-control-attribution a {
    color: var(--color-acento);
}

.coverage-map .leaflet-popup-content-wrapper,
.coverage-map .leaflet-popup-tip {
    color: var(--color-texto);
    background-color: var(--marino-medio);
    border: 1px solid var(--color-borde-fuerte);
    box-shadow: var(--sombra-md);
}

.coverage-map .leaflet-popup-content {
    margin: 0.7rem 0.95rem;
    font-family: var(--font-display);
    font-size: var(--fs-sm);
}

.coverage-map .leaflet-popup-close-button {
    color: var(--color-texto-suave);
}

/* --- Marcador propio (L.divIcon) -----------------------------------------
   Se usa un divIcon en lugar del marcador PNG por defecto de Leaflet: así el
   pin no depende de imágenes externas y hereda los colores del sitio. */
.map-pin {
    display: grid;
    place-items: center;
    background: none;
    border: 0;
}

.map-pin__dot {
    position: relative;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background-color: var(--celeste);
    box-shadow: 0 0 0 2.5px rgba(255, 255, 255, 0.9),
                0 0 18px 4px rgba(56, 189, 248, 0.75);
}

.map-pin__dot::after {
    content: '';
    position: absolute;
    inset: -6px;
    border: 2px solid rgba(56, 189, 248, 0.6);
    border-radius: 50%;
    animation: lucase-map-pulse 2.6s var(--ease-out) infinite;
}

@keyframes lucase-map-pulse {
    0%   { transform: scale(0.6); opacity: 0.9; }
    100% { transform: scale(2);   opacity: 0; }
}

/* --- Card lateral de datos ------------------------------------------------ */
.coverage-card {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    padding: clamp(1.6rem, 3vw, 2.1rem);
}

.coverage-card__title {
    font-size: var(--fs-lg);
}

.coverage-list {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.coverage-list__item {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-4);
}

.coverage-list__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    color: var(--celeste);
    background-color: rgba(56, 189, 248, 0.09);
    border: 1px solid rgba(56, 189, 248, 0.18);
    border-radius: 12px;
}

.coverage-list__svg {
    width: 20px;
    height: 20px;
}

.coverage-list__body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.coverage-list__label {
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    /* Etiqueta chica: --color-texto-suave asegura AA/AAA sobre la tarjeta. */
    color: var(--color-texto-suave);
}

.coverage-list__value {
    font-size: var(--fs-sm);
    line-height: 1.55;
    color: var(--color-texto);
}

.coverage-card__cta {
    align-self: flex-start;
    margin-top: auto;
}

@media (prefers-reduced-motion: reduce) {
    .app-feature.is-visible .app-feature__check { animation: none; }
    .app-feature:hover .app-feature__check { transform: none; }
    .map-pin__dot::after { animation: none; }
}

/* --------------------------------------------------------------------------
   5.16 FORMULARIO DE CONTACTO
   -------------------------------------------------------------------------- */
.contacto-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 3vw, 2.25rem);
    align-items: start;
}

.contacto-form {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    padding: clamp(1.6rem, 3vw, 2.4rem);
}

/* Honeypot: fuera de pantalla. No afecta el layout ni entra en el tabulado. */
.campo--honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --- Campos --------------------------------------------------------------- */
.campo {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.campo__label {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--color-titulo);
}

.campo__req {
    color: var(--color-acento);
}

.campo__input {
    width: 100%;
    padding: 0.8rem 1rem;
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    color: var(--color-texto);
    background-color: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-sm);
    transition: border-color var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-fast) var(--ease-out);
}

.campo__input::placeholder {
    /* --color-texto-tenue daba 4.4:1 sobre el fondo del campo, justo por debajo
       de AA. Con --color-texto-suave queda en 9:1, y sigue distinguiéndose del
       texto real (#EAF2FB). */
    color: var(--color-texto-suave);
}

.campo__input:hover {
    border-color: rgba(148, 187, 233, 0.32);
}

/* Foco: se reemplaza el outline global por un anillo más visible sobre el
   fondo oscuro del campo (borde celeste + halo). */
.campo__input:focus {
    outline: none;
    border-color: var(--color-acento);
    background-color: rgba(255, 255, 255, 0.06);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.22);
}

.campo__input--area {
    min-height: 8.5rem;
    resize: vertical;
    line-height: 1.6;
}

/* --- Estados de validación ------------------------------------------------ */
.campo.is-valid .campo__input {
    border-color: rgba(56, 189, 248, 0.45);
}

.campo.is-invalid .campo__input {
    border-color: var(--error-borde);
    background-color: var(--error-fondo);
}

.campo.is-invalid .campo__input:focus {
    box-shadow: 0 0 0 3px rgba(255, 123, 114, 0.2);
}

.campo__error {
    font-size: var(--fs-xs);
    line-height: 1.5;
    color: var(--error);
}

/* Sin mensaje, el <p> no ocupa espacio: el layout no salta al validar. */
.campo__error:empty {
    display: none;
}

.campo__hint {
    font-size: var(--fs-xs);
    line-height: 1.5;
    color: var(--color-texto-suave);
}

.campo__hint[data-counter] {
    align-self: flex-end;
    font-family: var(--font-mono);
}

.campo__hint.is-near {
    color: var(--celeste-suave);
}

/* --- Casilla de privacidad ------------------------------------------------ */
.campo--check {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.65rem 0.75rem;
    align-items: start;
}

.campo__check {
    width: 20px;
    height: 20px;
    margin-top: 1px;
    accent-color: var(--celeste);
    cursor: pointer;
}

.campo__check-label {
    font-size: var(--fs-sm);
    line-height: 1.55;
    color: var(--color-texto-suave);
    cursor: pointer;
}

.campo--check .campo__error {
    grid-column: 2;
}

/* --- Pie del formulario y spinner ---------------------------------------- */
.contacto-form__pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-4);
    margin-top: var(--sp-2);
}

.contacto-form__boton {
    position: relative;
    min-width: 12rem;
}

.contacto-form__label {
    transition: opacity var(--dur-fast) var(--ease-out);
}

.spinner {
    display: none;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(4, 18, 31, 0.3);
    border-top-color: var(--color-acento-texto);
    border-radius: 50%;
    animation: lucase-spin 700ms linear infinite;
}

.contacto-form.is-loading .spinner { display: block; }
.contacto-form.is-loading .contacto-form__label { opacity: 0.7; }
.contacto-form.is-loading .contacto-form__boton { cursor: progress; }

@keyframes lucase-spin {
    to { transform: rotate(360deg); }
}

/* --- Mensaje de resultado ------------------------------------------------- */
.form-status {
    display: none;
    padding: 0.85rem 1rem;
    font-size: var(--fs-sm);
    line-height: 1.55;
    border: 1px solid transparent;
    border-radius: var(--radio-sm);
}

.form-status:not(:empty) { display: block; }

.form-status--success {
    color: var(--exito);
    background-color: var(--exito-fondo);
    border-color: var(--exito-borde);
}

.form-status--error {
    color: var(--error);
    background-color: var(--error-fondo);
    border-color: var(--error-borde);
}

/* --- Card lateral de datos de contacto ----------------------------------- */
.contacto-datos {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    padding: clamp(1.6rem, 3vw, 2.1rem);
}

.contacto-datos__titulo {
    font-size: var(--fs-lg);
}

.contacto-datos__lista {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.contacto-datos__lista li {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.contacto-datos__rotulo {
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    /* Etiqueta chica: --color-texto-suave asegura AA sobre la tarjeta. */
    color: var(--color-texto-suave);
}

.contacto-datos__lista a,
.contacto-datos__lista li > span:not(.contacto-datos__rotulo) {
    font-size: var(--fs-sm);
    line-height: 1.55;
    color: var(--color-texto);
}

.contacto-datos__lista a:hover {
    color: var(--color-acento);
}

.contacto-datos__cta {
    align-self: flex-start;
    margin-top: auto;
}

/* --- Página de resultado (envío sin JavaScript) -------------------------- */
.form-resultado {
    padding: clamp(1.8rem, 4vw, 2.6rem);
    text-align: center;
    border-left: 3px solid var(--color-borde-fuerte);
}

.form-resultado--ok { border-left-color: var(--exito); }
.form-resultado--error { border-left-color: var(--error); }


/* --------------------------------------------------------------------------
   5.17 BOTÓN FLOTANTE DE WHATSAPP
   -------------------------------------------------------------------------- */
.float-wa {
    position: fixed;
    right: calc(clamp(1rem, 3vw, 1.75rem) + env(safe-area-inset-right, 0px));
    bottom: calc(clamp(1rem, 3vw, 1.75rem) + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-flotante);
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 1.1rem 0.7rem 0.8rem;
    color: var(--color-acento-texto);
    background-color: var(--celeste);
    background-image: var(--grad-acento);
    border-radius: var(--radio-pill);
    box-shadow: 0 14px 34px -14px rgba(56, 189, 248, 0.9),
                var(--sombra-md);
    transition: transform var(--dur-base) var(--ease-out),
                box-shadow var(--dur-base) var(--ease-out);
}

.float-wa:hover {
    color: var(--color-acento-texto);
    transform: translateY(-3px);
    box-shadow: 0 18px 40px -14px rgba(56, 189, 248, 1),
                var(--sombra-lg);
}

.float-wa:focus-visible {
    outline: 2px solid var(--blanco);
    outline-offset: 3px;
}

/* Anillo que se expande: es un borde sin relleno, así que se ve el botón a
   través suyo mientras crece. */
.float-wa__pulse {
    position: absolute;
    inset: 0;
    z-index: 0;
    border: 2px solid rgba(56, 189, 248, 0.65);
    border-radius: inherit;
    pointer-events: none;
    animation: lucase-wa-pulse 2.4s var(--ease-out) infinite;
}

.float-wa__icono,
.float-wa__texto {
    position: relative;
    z-index: 1;
}

.float-wa__icono {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
}

.float-wa__svg {
    width: 22px;
    height: 22px;
}

.float-wa__texto {
    font-family: var(--font-display);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 0.01em;
}

@keyframes lucase-wa-pulse {
    0%   { transform: scale(1);    opacity: 0.85; }
    70%  { transform: scale(1.6);  opacity: 0; }
    100% { transform: scale(1.6);  opacity: 0; }
}


/* --------------------------------------------------------------------------
   5.18 FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
    position: relative;
    /* Mismo gris neutro que la cabecera: el logo blanco apoya igual arriba y
       abajo, y las dos piezas se leen como un marco del sitio. */
    background-color: var(--barra);
    border-top: 1px solid var(--barra-borde);
}

/* Filo luminoso superior, muy sutil. */
.site-footer::before {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 1px;
    background-image: linear-gradient(
        90deg,
        rgba(0, 96, 208, 0) 0%,
        rgba(0, 96, 208, 0.5) 50%,
        rgba(0, 96, 208, 0) 100%
    );
    pointer-events: none;
}

.site-footer__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 3rem);
    padding-block: clamp(3rem, 7vw, 5rem);
}

.footer-col {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.footer-col--marca {
    max-width: 26rem;
}

.footer-col__titulo {
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-texto-suave);
}

.footer-col__texto,
.footer-col__nota {
    font-size: var(--fs-sm);
    line-height: 1.7;
    color: var(--color-texto-suave);
}

.footer-lista {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.footer-lista a,
.footer-contacto a {
    font-size: var(--fs-sm);
    color: var(--color-texto-suave);
    transition: color var(--dur-fast) var(--ease-out);
}

.footer-lista a:hover,
.footer-contacto a:hover {
    color: var(--color-acento);
}

.footer-contacto {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    font-size: var(--fs-sm);
}

.footer-contacto__tenue {
    color: var(--color-texto-suave);
}

/* --- Redes sociales ------------------------------------------------------- */
.social {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
}

.social__link {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    color: var(--color-texto-suave);
    background-color: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--barra-borde);
    border-radius: 13px;
    transition: color var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out),
                background-color var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out);
}

.social__link:hover {
    color: var(--color-acento);
    background-color: rgba(56, 189, 248, 0.12);
    border-color: var(--barra-borde-fuerte);
    transform: translateY(-2px);
}

.social__svg {
    width: 20px;
    height: 20px;
}

/* --- Barra inferior ------------------------------------------------------- */
.site-footer__bottom {
    /* Un escalón más oscuro que el resto del pie, para separar la barra legal. */
    background-color: rgba(16, 26, 40, 0.045);
    border-top: 1px solid var(--barra-borde);
}

.site-footer__bottom-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding-top: var(--sp-5);
    /* Reserva el alto del botón flotante más su margen, para que flote sobre
       espacio vacío en lugar de tapar los enlaces legales, que van abajo a la
       derecha. */
    padding-bottom: calc(var(--sp-5) + 3.75rem);
}

.site-footer__copy {
    font-size: var(--fs-xs);
    color: var(--color-texto-suave);
}

.legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-5);
}

.legal-links a {
    font-size: var(--fs-xs);
    color: var(--color-texto-suave);
}

.legal-links a:hover {
    color: var(--color-acento);
}

@media (prefers-reduced-motion: reduce) {
    .float-wa__pulse { animation: none; opacity: 0; }
    .spinner { animation-duration: 1.4s; }
}

/* El botón flotante no debe imprimirse. */
@media print {
    .float-wa { display: none; }
}

/* TODO: .plan, .faq y .step, cuando se construyan esas secciones. */


/* ==========================================================================
   6. RESPONSIVE
   Mobile-first. Breakpoints: 480 · 768 · 1024 · 1280
   ========================================================================== */

/* --- ≥ 480px: CTAs del hero en línea ------------------------------------- */
@media (min-width: 480px) {
    .hero__cta {
        width: auto;
    }

}

/* --- ≥ 768px: más aire, botones y drawer más grandes --------------------- */
@media (min-width: 768px) {
    .btn--lg {
        padding: 1.05rem 2.15rem;
    }

    .nav {
        width: min(60vw, 380px);
        padding-inline: var(--sp-7);
    }

    .nav-toggle,
    .nav__close {
        width: 48px;
        height: 48px;
    }

    /* La franja de capacidades pasa a cuatro columnas. */
    .hero__franja {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- ≥ 1024px: navegación en barra + hero a dos columnas ----------------- */
/* El menú horizontal necesita 1200px: con siete entradas, un logo grande y
   dos botones, a 1024px no entra por más que se achique la letra. Por debajo
   de 1200px se usa el drawer, como en mobile y tablet. */
@media (min-width: 1200px) {
    :root {
        --header-h: 80px;
    }

    /* El drawer y la hamburguesa desaparecen */
    .nav-toggle,
    .nav__head {
        display: none;
    }

    /* La navegación vuelve al flujo del header y se queda con el espacio
       libre entre la marca y los botones. */
    .nav {
        position: static;
        flex: 1;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        gap: 0;
        width: auto;
        padding: 0;
        background: none;
        border: 0;
        box-shadow: none;
        overflow: visible;
        transform: none;
        visibility: visible;
        transition: none;
    }

    /* El menú se centra en el espacio que queda entre la marca y los botones,
       no respecto del contenedor. Antes iba absoluto al centro exacto, y con
       un rótulo largo ("Políticas de privacidad"), un logo más grande y dos
       botones a la derecha terminaba superponiéndose. Así el propio flex
       reparte el espacio y no hay forma de que choquen, sea cual sea el
       rótulo o el tamaño de la marca. */
    .nav__list {
        position: static;
        flex-direction: row;
        align-items: center;
        gap: 0.75rem;
        white-space: nowrap;
        margin-inline: auto;
        transform: none;
    }

    .nav__item {
        display: flex;
    }

    .nav__link {
        position: relative;
        padding: 0.45rem 0.15rem;
        /* 13px en lugar de 14: con siete entradas, a 14 la barra no entra. */
        font-size: 0.8125rem;
        font-weight: 500;
        letter-spacing: 0.005em;
        border-bottom: 0;
    }

    .nav__link:hover,
    .nav__link.is-active {
        padding-left: 0.15rem;
    }

    /* Rótulos alternativos: el largo se ve en el drawer, donde hay lugar de
   sobra, y el corto en la barra de escritorio, donde el ancho es escaso.
   El oculto no se lee ni se anuncia: display:none lo saca del árbol. */
.nav__label-corto { display: none; }

@media (min-width: 1200px) {
    .nav__label-largo { display: none; }
    .nav__label-corto { display: inline; }
}

/* Subrayado que crece desde la izquierda */
    .nav__link::after {
        content: '';
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        height: 1.5px;
        background-image: var(--grad-acento);
        border-radius: 2px;
        transform: scaleX(0);
        transform-origin: left center;
        transition: transform var(--dur-base) var(--ease-out);
    }

    .nav__link:hover::after,
    .nav__link:focus-visible::after,
    .nav__link.is-active::after {
        transform: scaleX(1);
    }

    .nav__actions {
        flex-direction: row;
        align-items: center;
        gap: var(--sp-3);
        margin-top: 0;
        margin-left: auto;
    }

    .nav__cta {
        width: auto;
        padding-inline: 1.2rem;
    }

    .nav-overlay {
        display: none;
    }

}

/* El texto del hero no debe estirarse a todo el ancho: se limita a una medida
   cómoda de lectura, aunque la foto ocupe toda la pantalla. */
@media (min-width: 1024px) {
    .hero__content {
        max-width: 46rem;
    }
}

/* --- ≥ 1280px: ajustes finos de respiración ------------------------------ */
@media (min-width: 1280px) {
    .site-header__inner {
        gap: var(--sp-6);
    }

    /* El tamaño del logo se define junto a la regla .brand__logo (sección 5.4),
       para tener todos los breakpoints de la marca en un mismo lugar. */

    .nav__list {
        gap: 1rem;
    }

    .hero__inner {
        gap: clamp(3rem, 5vw, 5rem);
    }

}

/* --- Tarjetas: 2 columnas desde 480 ------------------------------------- */
@media (min-width: 480px) {
    .benefits-grid,
    .services-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* --- Tarjetas: más aire desde 768 --------------------------------------- */
@media (min-width: 768px) {
    .benefits-grid,
    .services-grid {
        gap: var(--sp-6);
    }
}

/* --- Tarjetas: 4 beneficios · 3 servicios desde 1024 --------------------- */
@media (min-width: 1024px) {
    .benefits-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .services-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* --- Tarjetas: 4 servicios por fila desde 1280 -------------------------- */
@media (min-width: 1280px) {
    .services-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- App móvil: más aire y badges separados desde 768 ------------------- */
@media (min-width: 768px) {
    .app-badges {
        gap: var(--sp-4);
    }

    .app-phone {
        width: 290px;
    }
}

/* --- App y cobertura: dos columnas desde 1024 --------------------------- */
@media (min-width: 1024px) {
    .app-grid {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    }

    .coverage-grid {
        grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    }

    .coverage-map {
        min-height: clamp(400px, 52vh, 540px);
    }
}

/* --- Cobertura: el mapa gana peso desde 1280 ---------------------------- */
@media (min-width: 1280px) {
    .coverage-grid {
        grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    }

    .app-phone {
        width: 300px;
    }
}

/* --- Footer: dos columnas desde 480 ------------------------------------- */
@media (min-width: 480px) {
    .site-footer__inner {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* --- Formulario y footer: columnas anchas desde 1024 -------------------- */
@media (min-width: 1024px) {
    .contacto-grid {
        grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    }

    .site-footer__inner {
        grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    }
}

/* --- Contacto: el formulario gana peso desde 1280 ----------------------- */
@media (min-width: 1280px) {
    .contacto-grid {
        grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    }
}

/* --- En mobile el botón flotante se compacta ---------------------------- */
@media (max-width: 767px) {
    .float-wa {
        padding: 0.62rem 0.9rem 0.62rem 0.72rem;
    }
}

/* --- Pantallas muy bajas: el indicador de scroll estorba ----------------- */
@media (max-height: 620px) {
    .scroll-cue {
        display: none;
    }
}

/* --- Sin backdrop-filter: fondo sólido para el header -------------------- */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .site-header.is-scrolled::before {
        background-color: rgba(10, 26, 51, 0.96);
    }
}
