/* ============================================================================
   INGClean® · Estilos del sitio público en /
   ----------------------------------------------------------------------------
   Filosofía: dark mode tech premium, coherente con la app móvil React/Capacitor.
   Linear/Stripe style con identidad INGClean, no agencia con neones.
   Stack: CSS plano, variables nativas, sin frameworks, sin build step.
   ============================================================================ */


/* ===== 1. RESET MÍNIMO ===================================================== */

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

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body, h1, h2, h3, h4, h5, h6, p, ul, ol, figure, blockquote {
    margin: 0;
}

ul[role="list"],
ol[role="list"],
ul.footer-column__list,
ul.lang-toggle {
    list-style: none;
    padding: 0;
}

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

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
    /* Anula el push-button nativo de iOS Safari (y appearance default de
       otros browsers). Sin esto, iOS Safari aplica su estilo nativo encima
       de cualquier styling custom · los .hero__chip se veían como texto
       plano sin pastilla en mobile. Como el reset ya quita border y
       background, agregar appearance:none NO cambia la apariencia de los
       botones que ya tienen su styling custom (.pillars__arrow, .btn,
       .hero__chip) · solo desbloquea que ese styling sí se aplique en iOS. */
    -webkit-appearance: none;
    appearance: none;
}

a {
    color: inherit;
    text-decoration: none;
}

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


/* ===== 2. DESIGN TOKENS ==================================================== */

:root {
    /* --- Colores · alineados con la app móvil INGClean® --- */
    --bg-base:        #02040b;
    --bg-layer:       #0a1228;
    --bg-deep:        #010207;
    --bg-elev:        rgba(255, 255, 255, 0.03);
    --bg-elev-2:      rgba(255, 255, 255, 0.05);

    --brand:          #2A8DFF;
    --brand-glow:     #4FB5FF;
    --brand-deep:     #0B3D91;

    --cyan:           #00E5FF;
    --emerald:        #00FFA3;  /* decorativo · pilares de seguridad, badges partner */

    /* --- Estados funcionales · NO confundir con los acentos decorativos --- */
    --success:        #00FFA3;  /* funcional · lead enviado, validación pasada */
    --warn:           #FFB547;  /* alertas suaves · avisos informativos */
    --danger:         #FF5470;  /* errores hard de form, fallos críticos */

    --text:           #FFFFFF;
    --text-muted:     rgba(255, 255, 255, 0.62);
    --text-dim:       rgba(255, 255, 255, 0.32);
    --text-line:      rgba(255, 255, 255, 0.08);
    --text-edge:      rgba(255, 255, 255, 0.06);

    /* --- Tipografía · cargada desde Google Fonts en inc/header.php --- */
    --font-display:   'Saira', system-ui, -apple-system, sans-serif;
    --font-brand:     'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono:      'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

    /* Escala fluida · clamp(mínimo, preferido, máximo) */
    --text-xs:        0.75rem;
    --text-sm:        0.875rem;
    --text-base:      1rem;
    --text-lg:        1.125rem;
    --text-xl:        clamp(1.25rem, 1.4vw, 1.5rem);
    --text-2xl:       clamp(1.5rem, 2vw, 1.875rem);
    --text-3xl:       clamp(1.875rem, 2.8vw, 2.5rem);
    --text-4xl:       clamp(2.25rem, 4vw, 3.5rem);
    --text-5xl:       clamp(3rem, 5vw, 4.5rem);
    --text-display:   clamp(3.5rem, 7vw, 7.5rem);

    /* Spacing · base 4 */
    --space-1:        0.25rem;
    --space-2:        0.5rem;
    --space-3:        0.75rem;
    --space-4:        1rem;
    --space-5:        1.25rem;
    --space-6:        1.5rem;
    --space-8:        2rem;
    --space-10:       2.5rem;
    --space-12:       3rem;
    --space-16:       4rem;
    --space-20:       5rem;
    --space-24:       6rem;
    --space-32:       8rem;

    /* Radios */
    --radius-sm:      8px;
    --radius-md:      16px;
    --radius-lg:      24px;
    --radius-xl:      32px;
    --radius-pill:    9999px;

    /* Sombras · todas tintadas en azul, ninguna en negro puro */
    --shadow-sm:      0 2px 8px rgba(11, 61, 145, 0.18);
    --shadow-md:      0 12px 32px rgba(11, 61, 145, 0.28);
    --shadow-lg:      0 32px 80px rgba(11, 61, 145, 0.45);
    --shadow-glow:    0 0 32px rgba(79, 181, 255, 0.18);
    --shadow-inset:   inset 0 1px 1px rgba(79, 181, 255, 0.18);
    --shadow-edge:    inset 0 0 0 1px var(--text-edge);

    /* Easing curves · spring-friendly */
    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
    --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
    --ease-stripe:    cubic-bezier(0.32, 0.72, 0, 1);

    /* Transitions reutilizables */
    --t-fast:         150ms var(--ease-out-quart);
    --t-base:         280ms var(--ease-stripe);
    --t-slow:         600ms var(--ease-out-expo);

    /* Layout · container y secciones */
    --container-max:  1320px;
    --container-px:   clamp(1.25rem, 4vw, 3rem);
    --section-py:     clamp(5rem, 10vw, 9rem);

    /* Z-index scale · disciplinado */
    --z-base:         1;
    --z-elevated:     10;
    --z-sticky:       80;
    --z-topbar:       100;
    --z-overlay:      200;
    --z-modal:        300;
}

/* Espaciado vertical entre secciones · más compacto en móvil para que el
   scroll no se sienta espaciado de más. Solo afecta <768px. Desktop sigue
   con el clamp(5rem, 10vw, 9rem) del :root sin tocar. Reducción ~40%:
   80px min mobile → 48px min · 144px max → 72px max. */
@media (max-width: 767px) {
    :root {
        --section-py: clamp(3rem, 7vw, 4.5rem);
    }
}


/* ===== 3. BASE · TIPOGRAFÍA Y CUERPO ======================================= */

/* NOTA · NO usar `html, body { height: 100% }` · constriñe el <body> a 100vh
   y rompe el position:sticky de las navs (.nav-home/.nav-cliente/.nav-partner)
   después del primer scroll · sticky pierde su contenedor cuando body queda
   "atrás" del viewport. El `min-height: 100dvh` del body (regla abajo) ya
   garantiza que bg-base cubra la pantalla aunque el contenido sea corto ·
   no necesitamos height fijo en html/body para nada en el sitio. */

body {
    min-height: 100dvh;
    margin: 0;
    background-color: var(--bg-base);
    color: var(--text);
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: -0.005em;
    overflow-x: hidden;                    /* fallback Safari 14-15 · previene scroll horizontal */
}

/* overflow-x:hidden en el body convierte al body en scrolling container y
   rompe position:sticky en TODOS los descendientes (la imagen sticky de
   .hero-band quedaba anclada al body fijo en lugar del viewport, así que
   no se "pegaba"). overflow:clip recorta visualmente igual que hidden pero
   NO crea scrolling container · sticky funciona normal. @supports asegura
   que Safari 14-15 (sin soporte clip) conserve el clipping con hidden;
   browsers modernos (>97% del tráfico) usan clip y disfrutan del sticky. */
@supports (overflow: clip) {
    body {
        overflow-x: clip;
    }
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--text);
    text-wrap: balance;
}

h1 {
    font-size: var(--text-4xl);
    font-weight: 700;
}

h2 {
    font-size: var(--text-3xl);
    font-weight: 700;
}

h3 {
    font-size: var(--text-2xl);
    font-weight: 600;
}

h4 {
    font-size: var(--text-xl);
    font-weight: 600;
}

p {
    line-height: 1.65;
    text-wrap: pretty;
}

.lead {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-width: 62ch;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--brand-glow);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

::selection {
    background-color: rgba(79, 181, 255, 0.32);
    color: var(--text);
}


/* ===== 4. LAYOUT PRIMITIVES ================================================ */

.container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-px);
}

.section {
    padding-block: var(--section-py);
    position: relative;
}

.section--narrow {
    padding-block: clamp(3rem, 6vw, 5rem);
}

.grid-2 {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-8);
}

.grid-3 {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

.grid-4 {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

.stack-sm > * + * { margin-top: var(--space-2); }
.stack-md > * + * { margin-top: var(--space-4); }
.stack-lg > * + * { margin-top: var(--space-8); }
.stack-xl > * + * { margin-top: var(--space-12); }


/* ===== 5. COMPONENTES BASE ================================================= */

/* --- Wordmark INGClean® ---------------------------------------------------- */

.brand {
    font-family: var(--font-brand);
    font-weight: 800;
    font-style: normal;
    letter-spacing: -0.01em;
    color: var(--text);
    display: inline;
}

/* Marca registrada · canónica · UNA SOLA clase para TODO el sitio (preview/
   + coming soon). Aplicada automáticamente a cualquier ® via initBrandReg()
   en motion.js, y también via brand() helper de PHP. color: inherit hace
   que el ® siga el color del contexto (blanco en headings, gris en párrafos,
   azul en wordmark del topbar) · más versátil que un color fijo. vertical-
   align: super lo eleva al estilo "marca registrada". line-height: 0 evita
   que afecte la altura de la línea anfitriona. font-size: 0.6em lo hace
   visible pero discreto. */
.brand-reg {
    font-size: 0.5em;
    vertical-align: super;
    line-height: 0;
    font-weight: 400;
    font-style: normal;
    letter-spacing: 0;
    margin-inline-start: 0.05em;
    color: inherit;
}

/* Alias legacy · mismas propiedades. Mantiene compatibilidad con cualquier
   instancia de .brand__reg que pudiera quedar suelta tras el refactor (ej:
   versiones cacheadas del brand() helper antes del cambio). */
.brand__reg {
    font-size: 0.5em;
    vertical-align: super;
    line-height: 0;
    font-weight: 400;
    font-style: normal;
    letter-spacing: 0;
    margin-inline-start: 0.05em;
    color: inherit;
}

/* Override · el ® en headings (h1/h2/h3) usa 0.3em (en vez del 0.5em
   general de .brand-reg) porque los headings son tipográficamente grandes
   (clamp ~24-64px). Con 0.5em el ® medía 12-32px (visualmente grande,
   competía con las letras); con 0.3em queda en 7-19px · proporción de
   "marca registrada discreta" exactamente igual a la del wordmark del hero
   (que también usa 0.3em). Especificidad (0,1,1) > .brand-reg (0,1,0) ·
   gana en cascada. NO pisa el override del hero (.hero__brand-wordmark
   .brand-reg, 0.3em, especificidad 0,2,0) porque el wordmark vive en un
   span aparte, no dentro de un <h1>. Body text, topbar y footer siguen
   en 0.5em. */
h1 .brand-reg,
h2 .brand-reg,
h3 .brand-reg {
    font-size: 0.3em;
}


/* --- Eyebrows · pill micro-label superior --------------------------------- */

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.eyebrow::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: var(--shadow-glow);
}

.eyebrow--plain::before {
    display: none;
}


/* --- Botones · primary y ghost, con button-in-button arrow ---------------- */

.btn {
    --btn-bg:           var(--brand);
    --btn-color:        var(--text);
    --btn-border:       transparent;
    --btn-arrow-bg:     var(--brand-deep);
    --btn-arrow-color:  var(--text);
    --btn-shadow:       var(--shadow-md);

    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6);
    background-color: var(--btn-bg);
    color: var(--btn-color);
    border: 1px solid var(--btn-border);
    border-radius: var(--radius-pill);
    font-weight: 600;
    font-size: var(--text-base);
    letter-spacing: -0.01em;
    text-decoration: none;
    box-shadow: var(--btn-shadow), var(--shadow-inset);
    transition: transform var(--t-base),
                background-color var(--t-base),
                box-shadow var(--t-base),
                color var(--t-base);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.btn:hover {
    background-color: var(--brand-glow);
    box-shadow: var(--shadow-lg), var(--shadow-inset);
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(1px);
    box-shadow: var(--shadow-sm), var(--shadow-inset);
}

.btn__label {
    line-height: 1;
}

.btn__arrow {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background-color: var(--btn-arrow-bg);
    color: var(--btn-arrow-color);
    transition: transform var(--t-base), background-color var(--t-base);
    flex-shrink: 0;
}

.btn__arrow svg {
    width: 16px;
    height: 16px;
}

.btn:hover .btn__arrow {
    transform: translateX(2px);
    background-color: rgba(255, 255, 255, 0.18);
}

/* Variante ghost · borde sutil, sin fill */
.btn-ghost {
    --btn-bg:           transparent;
    --btn-color:        var(--brand-glow);
    --btn-border:       rgba(79, 181, 255, 0.32);
    --btn-arrow-bg:     rgba(79, 181, 255, 0.12);
    --btn-arrow-color:  var(--brand-glow);
    --btn-shadow:       none;
}

.btn-ghost:hover {
    background-color: rgba(79, 181, 255, 0.08);
    color: var(--text);
    box-shadow: var(--shadow-glow);
    --btn-arrow-color: var(--text);
}

/* Variante small */
.btn-sm {
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
    font-size: var(--text-sm);
}

.btn-sm .btn__arrow {
    width: 24px;
    height: 24px;
}

.btn-sm .btn__arrow svg {
    width: 12px;
    height: 12px;
}


/* --- Tarjeta-pilar con doppelrand (doble borde anidado) ------------------ */

.pillar-card {
    background-color: var(--bg-elev);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    transition: transform var(--t-base), box-shadow var(--t-base);
}

.pillar-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-edge), var(--shadow-lg);
}

.pillar-card__inner {
    background-color: var(--bg-layer);
    border-radius: calc(var(--radius-xl) - 6px);
    padding: var(--space-8);
    height: 100%;
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* Visual superior de la pillar-card · full-bleed via margins negativos que
   escapan del padding del .pillar-card__inner. Border-radius solo en las
   esquinas superiores (matchea el interior del inner = radius-xl - 6px).
   Aspect-ratio 4:5 vertical en mobile/tablet matchea las imágenes
   originales (1122×1402). En desktop (≥1024px, 4 columnas) cambia a 1:1
   para que las tarjetas no queden excesivamente altas en la fila de 4 ·
   ver override en §14.5. width/height del <img> reservan el espacio
   antes del decode · sin CLS. */
.pillar-card__media {
    margin: calc(var(--space-8) * -1) calc(var(--space-8) * -1) 0;
    border-top-left-radius: calc(var(--radius-xl) - 6px);
    border-top-right-radius: calc(var(--radius-xl) - 6px);
    overflow: hidden;
    background: var(--bg-base);
    aspect-ratio: 4 / 5;
}

.pillar-card__media-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center center;
}

.pillar-card__icon {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(42, 141, 255, 0.18), rgba(0, 229, 255, 0.08));
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-glow);
}

.pillar-card__title {
    font-size: var(--text-xl);
    font-weight: 600;
    line-height: 1.2;
}

.pillar-card__body {
    color: var(--text-muted);
    line-height: 1.6;
    font-size: var(--text-base);
}

/* Hover-reveal del body · SOLO en devices con hover capability Y SIN
   reducción de movimiento. Anidamos las dos queries con AND para cubrir
   3 escenarios sin !important ni bloque reduced separado:
     · PC con mouse, sin reduced-motion → hover-reveal funciona
     · PC con mouse, CON reduced-motion → la query NO matchea · body queda
       en su default (visible siempre) y la imagen no recibe filter
     · Mobile/touch (sin hover) → la query NO matchea · idem default
   max-height 350px alcanza para el body más largo en EN (card 4 payments
   envuelve a más líneas que en ES).
   CRÍTICO: `min-height: 0` anula el `auto` implícito que CSS Flexbox da a
   los flex items en el eje principal (.pillar-card__inner es flex column).
   Sin ese override, min-height: auto (≈ alto del contenido) GANA sobre
   max-height: 0 · el body no colapsaba y quedaba visible siempre. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .pillar-card__body {
        max-height: 0;
        min-height: 0;
        opacity: 0;
        margin: 0;
        overflow: hidden;
        transform: translateY(20px);
        transition:
            max-height 400ms var(--ease-smooth),
            opacity 350ms var(--ease-smooth),
            transform 350ms var(--ease-smooth);
    }

    .pillar-card:hover .pillar-card__body {
        max-height: 350px;
        opacity: 1;
        transform: translateY(0);
    }

    .pillar-card__media-img {
        transition: filter 350ms var(--ease-smooth);
    }

    .pillar-card:hover .pillar-card__media-img {
        filter: brightness(0.6);
    }
}


/* --- Form fields · label arriba, error abajo ----------------------------- */

.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.form-field__label {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text);
    letter-spacing: 0;
}

.form-field__label--required::after {
    content: ' *';
    color: var(--brand-glow);
}

.form-field__input,
.form-field__select,
.form-field__textarea {
    width: 100%;
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    color: var(--text);
    font-size: var(--text-base);
    transition: border-color var(--t-base), background-color var(--t-base), box-shadow var(--t-base);
}

/* Select dark mode · color-scheme dice al browser que es un widget oscuro
   (scrollbar, focus ring del SO se renderizan dark). Appearance:none nos
   permite reemplazar el chevron nativo con un SVG inline coherente.        */
.form-field__select {
    color-scheme: dark;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none'><path d='M1 1l5 5 5-5' stroke='%234FB5FF' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right var(--space-4) center;
    background-size: 12px;
    padding-right: calc(var(--space-4) + 20px);
    cursor: pointer;
}

/* Options · styling explícito para que el dropdown se vea dark en Chrome/Edge/Firefox
   (Safari iOS tiene un dropdown del sistema con styling limitado · color-scheme ayuda). */
.form-field__select option {
    background-color: var(--bg-layer);
    color: var(--text);
    padding: 8px 12px;
}

.form-field__select option[value=""],
.form-field__select option:disabled {
    color: var(--text-dim);
}

.form-field__input::placeholder,
.form-field__textarea::placeholder {
    color: var(--text-dim);
}

.form-field__input:hover,
.form-field__select:hover,
.form-field__textarea:hover {
    border-color: rgba(79, 181, 255, 0.32);
}

.form-field__input:focus,
.form-field__select:focus,
.form-field__textarea:focus {
    outline: none;
    border-color: var(--brand-glow);
    background-color: var(--bg-elev-2);
    box-shadow: 0 0 0 4px rgba(79, 181, 255, 0.12);
}

.form-field__helper {
    font-size: var(--text-xs);
    color: var(--text-dim);
}

.form-field__error {
    font-size: var(--text-xs);
    color: var(--danger);
    display: none;
}

.form-field.is-invalid .form-field__input,
.form-field.is-invalid .form-field__select,
.form-field.is-invalid .form-field__textarea {
    border-color: var(--danger);
    box-shadow: 0 0 0 4px rgba(255, 84, 112, 0.12);
}

.form-field.is-invalid .form-field__error {
    display: block;
}

/* Honeypot · oculto visualmente y para asistencia, no tabable */
.honeypot {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}


/* ===== 6. TOPBAR FLOTANTE ================================================= */

.topbar {
    position: fixed;
    top: clamp(0.75rem, 2vw, 1.5rem);
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-topbar);
    width: calc(100% - 1.5rem);
    max-width: 1180px;
    padding: var(--space-2) var(--space-4);
    background-color: rgba(10, 18, 40, 0.55);
    -webkit-backdrop-filter: blur(18px) saturate(160%);
    backdrop-filter: blur(18px) saturate(160%);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-md), var(--shadow-edge);
}

.topbar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    min-height: 44px;
}

.topbar__brand {
    font-size: var(--text-lg);
    line-height: 1;
    color: var(--text);
    text-decoration: none;
    transition: opacity var(--t-fast);
    display: inline-flex;
    align-items: center;
    gap: 1.125rem;  /* 18px · separación entre logo y wordmark, respira mejor */
}

.topbar__brand:hover {
    opacity: 0.85;
}

/* Logo PNG en el topbar · cuadrado · width/height fijo evita layout shift */
.topbar__logo {
    width: 40px;
    height: 40px;
    flex-shrink: 0;          /* no se comprime aunque el wordmark presione */
    display: block;
}

/* Wordmark texto · se oculta en pantallas muy chicas (≤400px) para que el
   logo solo lleve el branding sin saturar la barra. Mantiene a11y porque
   el <a> sigue teniendo aria-label="brand_home". */
.topbar__wordmark {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

@media (max-width: 400px) {
    .topbar__wordmark {
        display: none;
    }
}


/* --- Lang toggle · pequeño selector ES/EN -------------------------------- */

.lang-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.08em;
    list-style: none;
    padding: 0;
}

.lang-toggle__btn {
    color: var(--text-muted);
    text-decoration: none;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    transition: color var(--t-fast), background-color var(--t-fast);
}

.lang-toggle__btn:hover {
    color: var(--text);
}

.lang-toggle__btn.is-active {
    color: var(--cyan);
    background-color: rgba(0, 229, 255, 0.08);
}

.lang-toggle__sep {
    color: var(--text-dim);
    user-select: none;
}


/* ===== 7. SITE FOOTER ===================================================== */

.site-footer {
    position: relative;
    margin-top: var(--space-32);
    padding-top: clamp(4rem, 8vw, 7rem);
    padding-bottom: var(--space-10);
    background-color: var(--bg-deep);
    color: var(--text-muted);
    z-index: var(--z-base);
}

.site-footer::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(79, 181, 255, 0.32) 30%,
        rgba(0, 229, 255, 0.45) 50%,
        rgba(79, 181, 255, 0.32) 70%,
        transparent 100%);
}

/* --- Anclas de marca · cobertura geográfica + alcance del servicio ----- */

.site-footer__anchors {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    padding-bottom: var(--space-12);
    border-bottom: 1px solid var(--text-edge);
}

.anchor-block {
    padding: var(--space-6) var(--space-6);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-inset);
}

.anchor-block__eyebrow {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    margin-bottom: var(--space-3);
}

.anchor-block__text {
    font-size: var(--text-lg);
    color: var(--text);
    line-height: 1.45;
    text-wrap: balance;
}


/* --- Audience splitter CTA ------------------------------------------------ */

.site-footer__cta {
    padding-block: clamp(3rem, 6vw, 5rem);
    text-align: center;
}

.site-footer__cta-title {
    font-size: var(--text-3xl);
    font-weight: 700;
    color: var(--text);
    margin-bottom: var(--space-3);
    text-wrap: balance;
}

.site-footer__cta-sub {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-width: 52ch;
    margin: 0 auto var(--space-8);
    line-height: 1.55;
}

.site-footer__cta-buttons {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
}


/* --- Tres columnas: nav rápida · legal · contacto ------------------------ */

.site-footer__columns {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-10);
    padding-block: var(--space-10);
    border-top: 1px solid var(--text-edge);
    border-bottom: 1px solid var(--text-edge);
}

.footer-column__title {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.2em;
    margin-bottom: var(--space-4);
}

.footer-column__list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.footer-column__link {
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--text-sm);
    transition: color var(--t-fast);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.footer-column__link:hover {
    color: var(--text);
}

.footer-column__city {
    color: var(--text-dim);
    font-size: var(--text-sm);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* Indicador de email pendiente · línea punteada sutil bajo el link */
.footer-column__link[data-pending="true"] {
    border-bottom: 1px dashed rgba(79, 181, 255, 0.32);
    padding-bottom: 1px;
}

/* Teléfono del footer · acento neón azul + monospace tabular para que los
   dígitos no bailen al hover. text-shadow multi-capa = glow neón sutil base
   + halo medio + halo amplio. Hover intensifica el glow sin cambiar layout
   (sin font-weight ni size · solo shadow + color más claro). */
.footer-column__link--phone {
    color: var(--brand-glow);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    text-shadow:
        0 0 6px  rgba(79, 181, 255, 0.45),
        0 0 14px rgba(79, 181, 255, 0.30),
        0 0 28px rgba(79, 181, 255, 0.15);
    transition: text-shadow var(--t-base), color var(--t-base);
}

.footer-column__link--phone:hover,
.footer-column__link--phone:focus-visible {
    color: #B4E6FF;                                /* blanco azulado, más intenso */
    text-shadow:
        0 0 8px  rgba(79, 181, 255, 0.65),
        0 0 18px rgba(79, 181, 255, 0.45),
        0 0 36px rgba(79, 181, 255, 0.25),
        0 0 56px rgba(79, 181, 255, 0.12);
}

/* Reduced-motion · desactivamos la transition (el glow sigue visible al
   hover, solo aparece instantáneo · consistente con el resto del sistema
   de hover-glows del proyecto). */
@media (prefers-reduced-motion: reduce) {
    .footer-column__link--phone {
        transition: none;
    }
}


/* --- Línea final: copyright + redes sociales ----------------------------- */

.site-footer__bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-6);
    padding-top: var(--space-8);
}

/* Brand block del footer · logo + copyright apilados en mobile, lado a lado
   en desktop (el media-query de site-footer__bottom flex-row lo cubre). */
.site-footer__brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

/* Logo PNG del footer · 56px alto (entre 48-64 según pediste).
   width auto preserva aspect ratio del PNG 126×128. */
.site-footer__logo {
    height: 56px;
    width: auto;
    display: block;
    opacity: 0.85;             /* sutil descuento del brillo en footer */
    transition: opacity var(--t-fast);
}

.site-footer__logo:hover {
    opacity: 1;
}

.site-footer__copyright {
    font-size: var(--text-sm);
    color: var(--text-dim);
    text-align: center;
    margin: 0;
}

.site-footer__socials {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.social-link {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    border-radius: var(--radius-pill);
    transition: color var(--t-fast), background-color var(--t-fast), transform var(--t-fast);
}

.social-link svg {
    width: 18px;
    height: 18px;
}

.social-link:hover {
    color: var(--brand-glow);
    background-color: rgba(79, 181, 255, 0.08);
    transform: translateY(-1px);
}

/* Placeholder pendiente · cursor de aviso sutil */
.social-link[data-pending="true"] {
    opacity: 0.78;
}


/* ===== 8. ACCESIBILIDAD ==================================================== */

.skip-link {
    position: absolute;
    top: -100px;
    left: var(--space-4);
    z-index: var(--z-modal);
    background-color: var(--brand);
    color: var(--text);
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-md);
    font-weight: 600;
    font-size: var(--text-sm);
    text-decoration: none;
    transition: top var(--t-fast);
}

.skip-link:focus {
    top: var(--space-4);
}

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


/* ===== 9. EFECTOS AMBIENTALES · grid 3D + HUD corners ===================== */

.bg-grid {
    position: fixed;
    inset: -15% -15%;
    z-index: -1;
    pointer-events: none;
    background-image:
        linear-gradient(to right, rgba(79, 181, 255, 0.06) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(79, 181, 255, 0.06) 1px, transparent 1px);
    background-size: 72px 72px;
    background-position: center;
    transform-origin: 50% 50%;
    transform: perspective(1400px) rotateX(56deg) translateZ(-220px) scale(1);
    -webkit-mask-image: radial-gradient(ellipse 85% 65% at 50% 40%, #000 50%, transparent 100%);
            mask-image: radial-gradient(ellipse 85% 65% at 50% 40%, #000 50%, transparent 100%);
    animation: bg-grid-breathe 8s ease-in-out infinite;
    will-change: transform, opacity;
}

@keyframes bg-grid-breathe {
    0%, 100% {
        transform: perspective(1400px) rotateX(56deg) translateZ(-220px) scale(1);
        opacity: 0.7;
    }
    50% {
        transform: perspective(1400px) rotateX(56deg) translateZ(-220px) scale(1.04);
        opacity: 0.95;
    }
}

/* HUD corners · marcos de las cuatro esquinas, decorativos */

.hud-corners {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: var(--z-base);
}

.hud-corner {
    position: absolute;
    width: 28px;
    height: 28px;
    border-color: rgba(79, 181, 255, 0.45);
    border-style: solid;
    border-width: 0;
}

.hud-corner--tl {
    top: clamp(0.75rem, 2vw, 1.5rem);
    left: clamp(0.75rem, 2vw, 1.5rem);
    border-top-width: 1px;
    border-left-width: 1px;
}
.hud-corner--tr {
    top: clamp(0.75rem, 2vw, 1.5rem);
    right: clamp(0.75rem, 2vw, 1.5rem);
    border-top-width: 1px;
    border-right-width: 1px;
}
.hud-corner--bl {
    bottom: clamp(0.75rem, 2vw, 1.5rem);
    left: clamp(0.75rem, 2vw, 1.5rem);
    border-bottom-width: 1px;
    border-left-width: 1px;
}
.hud-corner--br {
    bottom: clamp(0.75rem, 2vw, 1.5rem);
    right: clamp(0.75rem, 2vw, 1.5rem);
    border-bottom-width: 1px;
    border-right-width: 1px;
}


/* ===== 10. EFECTOS DE HERO · scan-line + matrix-rain ====================== */
/* Estos efectos se activan SOLO en heroes (no en pestañas internas) agregando
   las clases .with-scanline / .with-matrix al contenedor del hero.            */

.with-scanline {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.with-scanline::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(180deg,
        transparent 0%,
        rgba(0, 229, 255, 0.18) 49%,
        rgba(0, 229, 255, 0.32) 50%,
        rgba(0, 229, 255, 0.18) 51%,
        transparent 100%);
    background-size: 100% 320px;
    background-repeat: no-repeat;
    background-position: 0 -320px;
    mix-blend-mode: screen;
    animation: scanline-sweep 7s linear infinite;
    z-index: 2;
}

@keyframes scanline-sweep {
    0%   { background-position: 0 -320px; }
    100% { background-position: 0 calc(100% + 320px); }
}

.with-matrix {
    position: relative;
    isolation: isolate;
}

.with-matrix::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='280' height='320'><text x='10' y='30' font-family='monospace' font-size='12' fill='%234FB5FF' opacity='0.55'>10110</text><text x='80' y='80' font-family='monospace' font-size='12' fill='%232A8DFF' opacity='0.45'>01001</text><text x='150' y='130' font-family='monospace' font-size='12' fill='%2300E5FF' opacity='0.35'>11010</text><text x='40' y='180' font-family='monospace' font-size='12' fill='%234FB5FF' opacity='0.5'>10011</text><text x='200' y='220' font-family='monospace' font-size='12' fill='%232A8DFF' opacity='0.45'>00110</text><text x='100' y='280' font-family='monospace' font-size='12' fill='%2300E5FF' opacity='0.4'>01101</text></svg>");
    background-repeat: repeat;
    opacity: 0.22;
    mix-blend-mode: screen;
    z-index: 1;
}


/* ===== 11. UTILIDADES ===================================================== */

.text-muted { color: var(--text-muted); }
.text-dim   { color: var(--text-dim); }
.text-brand { color: var(--brand-glow); }
.text-cyan  { color: var(--cyan); }
.text-mono  { font-family: var(--font-mono); }

.mt-auto { margin-top: auto; }
.mb-auto { margin-bottom: auto; }


/* ===== 12. RESPONSIVE · mobile-first ====================================== */

@media (min-width: 640px) {
    .grid-2 { grid-template-columns: 1fr 1fr; }
    .site-footer__anchors { grid-template-columns: 1fr 1fr; }
    .site-footer__cta-buttons { flex-direction: row; }
}

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

    .site-footer__columns {
        grid-template-columns: 2fr 1fr 1.5fr;
        gap: var(--space-12);
    }

    .site-footer__bottom {
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
    }

    .site-footer__brand {
        flex-direction: row;     /* desktop: logo a la izq, copyright a la der */
        align-items: center;
        gap: 1rem;
    }

    .site-footer__copyright {
        text-align: start;
    }

    .topbar {
        padding: var(--space-2) var(--space-5);
    }
}

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


/* ===== 13. MOTION REDUCTION · respetar accesibilidad ====================== */

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

    .bg-grid {
        transform: perspective(1400px) rotateX(56deg) translateZ(-220px) scale(1);
        opacity: 0.7;
    }

    .with-scanline::after,
    .with-matrix::before {
        display: none;
    }
}


/* ===== 14. HOME NEUTRAL · hero · audience splitter · 4 pilares ============ */


/* --- 14.1 Hero principal ------------------------------------------------- */

.hero {
    position: relative;
    min-height: 90dvh;
    display: flex;
    align-items: center;
    /* Topbar (~52px) + nav-home sticky (~50px) + respiro · mismo clamp que .hero-page */
    padding-top: clamp(9rem, 16vw, 13rem);
    padding-bottom: var(--section-py);
    overflow: hidden;
}

/* === Hero con imagen del globo de fondo · banner superior full-bleed ====== */
/* La imagen /media/hero-globe.webp (1920×640, fondo negro) se posiciona
   absoluta en la parte superior del hero, ancho completo. Gradients laterales
   + bottom la funden con el bg-base para que el corte no se note y el texto
   del hero (que va encima con z-index >0) se lea sin perder contraste.
   Animaciones · fade-in al cargar + zoom "respira" muy sutil (loop 18s).
   prefers-reduced-motion apaga ambas · el globo queda visible estático. */

.hero__globe {
    position: absolute;
    inset: 0;                               /* cubre TODO el hero · full-bleed */
    overflow: hidden;
    pointer-events: none;
    z-index: 0;                             /* detrás del .hero__inner (z:3) */
}

.hero__globe-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    opacity: 0;                             /* estado inicial · hero-globe-enter hace fade-in */
    animation:
        hero-globe-enter 1.5s var(--ease-smooth) 0.2s forwards,
        hero-globe-breathe 18s ease-in-out 1.7s infinite;
    will-change: opacity, transform;
}

/* Overlay radial uniforme · atenúa el globo full-bleed para que el texto del
   hero (que va con z-index:3 encima) se lea con contraste. Centro al 40% de
   oscuridad (globo más visible donde no hay texto crítico), bordes al 80%
   (más oscuro · funde con el bg-base de las secciones siguientes). */
.hero__globe::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at center,
        rgba(2, 4, 11, 0.40) 0%,
        rgba(2, 4, 11, 0.55) 60%,
        rgba(2, 4, 11, 0.80) 100%);
    pointer-events: none;
}

@keyframes hero-globe-enter {
    from { opacity: 0; transform: scale(1.04); }
    to   { opacity: 1; transform: scale(1);    }
}

@keyframes hero-globe-breathe {
    0%, 100% { transform: scale(1);     }
    50%      { transform: scale(1.025); }
}

@media (prefers-reduced-motion: reduce) {
    .hero__globe-img {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* === Banda visual entre hero y audience splitter · sticky reveal ========
   Imagen responsive con 3 versiones (vertical mobile · cuadrada tablet ·
   panorámica desktop) seleccionadas via <picture media>. EFECTO PARALLAX:
   la imagen queda anclada (position:sticky) mientras el usuario scrollea
   sobre el stage; el audience splitter siguiente sube margin-top negativo
   y pasa POR ENCIMA cubriéndola con fundido suave (gradient top
   transparente→bg-base). Sin will-change permanente y sin animaciones en
   el <img> · sticky es repaint-heavy, mantener overhead mínimo evita jank
   en mobile. prefers-reduced-motion apaga todo el efecto y vuelve a flujo
   estático clásico (sin sticky, sin margins negativos). */

/* Stage · contenedor que define cuánto scroll dura el efecto sticky.
   El padding-bottom es el "rango" durante el cual la imagen permanece
   pegada al top del viewport mientras el audience sube por encima.
     · mobile  50vh  (efecto breve · scroll corto)
     · tablet  60vh
     · desktop 70vh  (efecto más cinematográfico) */
.hero-band-stage {
    position: relative;
    padding-bottom: 50vh;
}

@media (min-width: 641px) {
    .hero-band-stage { padding-bottom: 60vh; }
}

@media (min-width: 1025px) {
    .hero-band-stage { padding-bottom: 70vh; }
}

/* Imagen sticky · anclada al top del viewport durante el scroll sobre el
   stage. z-index:0 la deja debajo del audience (z:1) y muy debajo del
   topbar fijo (z:100). NO usa will-change · sticky ya gestiona compositing
   y mantener will-change permanente empeora performance en mobile (la GPU
   mantiene la layer cacheada todo el tiempo, no solo durante movimiento). */
.hero-band {
    position: sticky;
    top: 0;
    z-index: 0;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
    background: var(--bg-base);
    line-height: 0;                        /* elimina descender del <img> · sin gap */
}

/* Imagen COMPLETA · ratio natural · sin recorte. Sin animaciones · imagen
   quieta mientras el audience pasa por encima (efecto cinematográfico
   limpio, sin distracciones competing por atención). */
/* Wrapper scrollable interno · necesario para que en mobile (<900px) la
   infografía mantenga min-width 900px legible con scroll horizontal sin
   romper el overflow:hidden del .hero-band sticky padre. -webkit-overflow-
   scrolling: touch para momentum nativo en iOS. */
.hero-band__scroll {
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.hero-band__img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 1448px;                     /* no estira más allá del ancho natural */
    margin-left: auto;                     /* centra en monitores >1448px */
    margin-right: auto;
}

/* Mobile <900px · forzamos min-width 900px en la imagen para que el texto
   denso de la infografía (horarios, nombres, servicios) siga legible. El
   wrapper .hero-band__scroll captura el overflow y permite swipe lateral. */
@media (max-width: 900px) {
    .hero-band__img {
        min-width: 900px;
    }
}

/* Gradient asimétrico · fade-in top 12% + fade-out bottom 90→100% al
   bg-base. El fade bottom cubre cualquier pixel claro del borde inferior
   de la imagen (la versión wide.webp panorámica tenía un borde con
   luminancia distinta que aparecía como raya clara en PC durante la
   transición sticky → audience). El último 10% se solapa con el audience
   que viene por encima · invisible en condiciones normales, solo activo
   en el frame justo antes de que el audience cubra completamente. */
.hero-band::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(to bottom,
        var(--bg-base) 0%,
        transparent 12%,
        transparent 90%,
        var(--bg-base) 100%);
}

/* Excepción al sistema reveal · .hero-band está en REVEAL_SELECTORS (motion.js)
   para hacer fade-in suave al entrar al viewport. Pero el .reveal base aplica
   transform: translateY(20px)→0 que convierte al .hero-band en su PROPIO
   containing block, lo cual ancla el position:sticky a sí mismo en vez del
   viewport y rompe el efecto (la imagen no se "pega" al top al scrollear).
   Acá sobreescribimos solo el transform y will-change · conservamos el fade
   de opacity (efecto sutil de entrada) y dejamos sticky funcionando. La
   especificidad (0,2,0) y (0,3,0) gana sobre .reveal (0,1,0) sin importar
   el orden de aparición. */
.hero-band.reveal,
.hero-band.reveal.is-revealed {
    transform: none;
    will-change: opacity;
}

/* Audience splitter · sube margin-top negativo (matchea padding-bottom
   del stage en vh) y pasa por encima de la imagen sticky. z-index:1
   garantiza superposición sobre la banda (z:0). El gradient top
   transparente→bg-base produce el fundido suave al cubrir la imagen
   detrás. padding-top extra da aire al título dentro de la zona ya
   con bg sólido. Selector adjacent sibling para que SOLO aplique cuando
   el audience viene inmediatamente después del stage (home neutral). */
.hero-band-stage + .comparison {
    position: relative;
    z-index: 1;
    margin-top: -50vh;
    background: linear-gradient(to bottom,
        transparent 0%,
        var(--bg-base) clamp(80px, 12vw, 160px),
        var(--bg-base) 100%);
    padding-top: clamp(120px, 18vw, 240px);
}

@media (min-width: 641px) {
    .hero-band-stage + .comparison { margin-top: -60vh; }
}

@media (min-width: 1025px) {
    .hero-band-stage + .comparison { margin-top: -70vh; }
}

/* Reduced-motion · fallback completo · sin sticky, sin margins negativos,
   sin gradients de fundido. La página vuelve a flujo estático clásico:
   imagen en su posición normal seguida del audience también en su
   posición normal. Accesible y sin jank para usuarios que pidieron
   reducción de movimiento. */
@media (prefers-reduced-motion: reduce) {
    .hero-band-stage {
        padding-bottom: 0;
    }
    .hero-band {
        position: static;
    }
    .hero-band-stage + .comparison {
        margin-top: 0;
        background: var(--bg-base);
        padding-top: var(--section-py);
    }
}

.hero__inner {
    display: flex;
    flex-direction: column;
    align-items: center;                /* todo el hero centrado horizontalmente */
    gap: var(--space-6);
    max-width: 980px;
    position: relative;
    z-index: 3;
}

/* Wrapper del bloque brand · contiene .hero__brand-row + .hero__brand-tagline.
   width:fit-content hace que el ancho del bloque se ajuste al hijo más ancho.
   Cuando el tagline mono wrappea a varias líneas (max-width 56ch), el block
   toma ese ancho y el tagline queda left-aligned al borde izquierdo (que es
   donde está la "I" del wordmark). Si el row es más ancho que el tagline, el
   block toma el ancho del row. En ambos casos: tagline alineado a la I.
   En mobile el block pasa a align-items: center (ver media query abajo). */
.hero__brand-block {
    display: flex;
    flex-direction: column;
    align-items: flex-start;            /* tagline alineado al borde izquierdo del bloque */
    width: fit-content;                 /* ancho = el del hijo más ancho */
    max-width: 100%;                    /* nunca desborda el .hero__inner */
}

/* Bloque brand del hero · <h1> que envuelve logo + wordmark inline.
   El font-size establecido acá da el contexto em para el .hero__logo
   (height 1.05em) y el .hero__brand-wordmark (font-size 1em). */
.hero__brand-row {
    display: inline-flex;
    align-items: center;
    gap: clamp(1.25rem, 2.5vw, 1.75rem);   /* 20px → 28px responsive */
    font-size: var(--text-display);
    line-height: 0.95;
    margin: var(--space-2) 0 0;
}

/* Logo dentro del .hero__brand-row · height proporcional al font-size del
   padre (1em ≈ font-size). 1.05em da un bounding box ~1.46× del cap-height
   visible del wordmark (cap ≈ 0.72em del font), notoriamente más grande sin
   abrumar. width: auto preserva aspect ratio del PNG 504×512. */
.hero__logo {
    height: 1.05em;
    width: auto;
    flex-shrink: 0;
    display: block;
}

/* Wordmark text inline · usa el font-size del padre brand-row · estilos
   tipográficos del helper brand() (Plus Jakarta Sans 800) ya aplican desde
   la clase .brand del span devuelto por brand(). */
.hero__brand-wordmark {
    display: inline-flex;
    align-items: center;
    line-height: 1;
    font-size: 1em;
}

/* Override · el ® dentro del wordmark grande del hero usa 0.3em (en vez del
   0.6em general de .brand-reg) porque el contexto base es enorme: el
   var(--text-display) del .hero__brand-row es clamp(3.5rem, 7vw, 7.5rem) ·
   56→120px. Con 0.6em el ® medía 33-72px (casi del tamaño de una letra del
   wordmark) · con 0.3em queda en 17-36px · proporción clásica de marca
   registrada discreta (~30% del cap height), claramente más chica que las
   letras. Especificidad (0,2,0) > .brand-reg (0,1,0) · gana en cascada.
   Solo afecta el wordmark del hero · topbar, footer, textos normales y
   coming soon siguen con 0.6em que en sus contextos chicos queda bien.
   Mantiene el resto de .brand-reg: vertical-align super, line-height 0,
   color inherit, font-weight 400, margin-inline-start 0.05em. */
.hero__brand-wordmark .brand-reg {
    font-size: 0.3em;
}

/* Tagline mono debajo del brand-row · uppercase con tracking ancho.
   Espacio sutil arriba (sigue al brand) y más espacio abajo (antes del heading
   grande con split por palabras). */
.hero__brand-tagline {
    /* Offset que alinea la "P" de PLATAFORMA con la "I" de INGClean.
       El brand-row de arriba es: [logo] [gap] [wordmark]. Para que el
       contenido del tagline arranque donde empieza el wordmark, le damos
       padding-left = (logo width) + (gap).
       - logo width = 1.05em × aspect 504/512 ≈ 1.033em del font-size
         del brand-row (var(--text-display) = clamp(3.5rem, 7vw, 7.5rem))
       - logo width en abs ≈ clamp(3.62rem, 7.24vw, 7.76rem)
       - gap = clamp(1.25rem, 2.5vw, 1.75rem)
       - total padding-left ≈ clamp(4.87rem, 9.74vw, 9.51rem)
       Como el font-size del tagline es muy distinto al del brand-row,
       NO podemos usar em adentro del tagline para igualar el offset.
       El clamp absoluto escala proporcionalmente con la misma curve. */
    padding-left: clamp(4.85rem, 9.74vw, 9.5rem);
    max-width: 720px;          /* ancho suficiente para acomodar la frase EN
                                  (88 chars uppercase + letter-spacing 0.14em)
                                  en 2 líneas balanceadas por text-wrap: balance */
    margin: 0.25rem 0 0;
    font-family: var(--font-mono);
    font-size: clamp(0.875rem, 1.5vw, 1.125rem);   /* 14px → 18px · sube un escalón */
    font-weight: 500;
    letter-spacing: 0.14em;
    line-height: 1.5;
    text-transform: uppercase;
    color: var(--text);                            /* blanco · alta legibilidad */
    text-shadow: 0 0 14px rgba(42, 141, 255, 0.18);
    text-align: left;
    text-wrap: balance;
}

/* Resaltado de las 3 tecnologías clave dentro del .hero__brand-tagline
   ("verificación facial" · "rastreo GPS en tiempo real" · "tecnología de
   seguridad avanzada"). Aplicado vía <span class="brand-tagline-hl">
   dentro del string i18n (mismo mecanismo que el <b> del heading). Solo
   overridea color y peso · hereda font-family, font-size, letter-spacing,
   text-transform y text-shadow del padre. weight 700 (vs base 500) crea
   jerarquía visual fuerte sin romper la línea mono uppercase. */
.brand-tagline-hl {
    color: var(--brand-glow);
    font-weight: 700;
}

/* === Verde neón scoped al HERO DEL HOME ==================================
   Tintea el eyebrow superior y el tagline inferior en verde emerald con
   glow estático (3 capas, mismo patrón que el teléfono del footer pero en
   rgb(0,255,163)). Scoped a `.hero` para NO afectar las 7 páginas internas
   que usan `.hero-page` (clientes/*, partners/*, quienes-somos, legal).
   Sin animación · visible siempre · respeta prefers-reduced-motion
   naturalmente (no hay transitions ni keyframes que silenciar). */

.hero .eyebrow {
    color: var(--emerald);
    text-shadow:
        0 0 6px  rgba(0, 255, 163, 0.45),
        0 0 14px rgba(0, 255, 163, 0.30),
        0 0 28px rgba(0, 255, 163, 0.15);
}

/* Dot del eyebrow · el relleno hereda 'currentColor' del padre y ya queda
   verde con el override de arriba. Acá repintamos solo el halo (box-shadow)
   en verde para reemplazar el var(--shadow-glow) azul del default. */
.hero .eyebrow::before {
    box-shadow:
        0 0 6px  rgba(0, 255, 163, 0.45),
        0 0 14px rgba(0, 255, 163, 0.30),
        0 0 28px rgba(0, 255, 163, 0.15);
}

/* Brand-tagline · override del color blanco + text-shadow azul sutil
   (rgba(42, 141, 255, 0.18)) por verde con el patrón neón completo. */
.hero__brand-tagline {
    color: var(--emerald);
    text-shadow:
        0 0 6px  rgba(0, 255, 163, 0.45),
        0 0 14px rgba(0, 255, 163, 0.30),
        0 0 28px rgba(0, 255, 163, 0.15);
}

/* Preemptivo · si en el futuro el i18n del tagline trae
   <span class="brand-tagline-hl"> para resaltar palabras, lo pintamos verde
   también, scoped al .hero. Defiende contra que un highlight reaparezca
   azul dentro del bloque verde. Hoy no hay strings que usen esta clase. */
.hero .brand-tagline-hl {
    color: var(--emerald);
}

/* Mobile · el alignment a la "I" se vería raro en pantallas chicas.
   Centramos el bloque entero y el tagline · sin padding-left. */
@media (max-width: 600px) {
    .hero__brand-block {
        align-items: center;
    }
    .hero__brand-tagline {
        padding-left: 0;
        text-align: center;
    }
}

/* Mensaje del medio · texto secundario entre heading y slogan rotator.
   Estilo simple/legible · centrado · color del texto principal (blanco)
   para presencia · sin tratamiento visual fino (eso se hace después si
   hace falta). Reveal y reduced-motion heredan del sistema general
   (.hero__inner > * está en REVEAL_SELECTORS). */
.hero__middle {
    text-align: center;
    max-width: 56ch;
    margin: 0 auto;
    color: var(--text);
    font-size: var(--text-lg);
    line-height: 1.55;
    text-wrap: pretty;
}

/* === Componente Chips del hero · 5 pilares interactivos ===================
   5 botones tipo pill que al hover (PC) o tap (mobile) cambian el contenido
   del panel .hero__chips-explain debajo. Lenguaje visual matchea con las
   etiquetas COVERAGE/SERVICES del hero · brand-glow azul para hover/active.
   flex-wrap permite acomodarse en varias filas según ancho disponible.
   max-width 880px evita que se estire demasiado en monitores ultra-wide.
   initHeroChips() corre ANTES del guard de reduced-motion (motion.js sección
   0c) · la interacción funciona aunque el usuario tenga reducir movimiento. */
.hero__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: center;
    max-width: 880px;
    margin: var(--space-4) auto 0;
}

/* Chip individual · <button> estilizado como pill · combina con tags ya
   existentes del sitio. Color muted por default · al hover/active sube
   a brand-glow con halo (mismo lenguaje visual que nav links + comparison). */
.hero__chip {
    display: inline-flex;
    align-items: center;
    padding: var(--space-3) var(--space-5);       /* 12px 20px · más presencia */
    background: rgba(2, 4, 11, 0.50);
    border: 1px solid rgba(79, 181, 255, 0.30);
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    font-family: inherit;
    font-size: var(--text-base);                  /* 16px · un escalón arriba del anterior 14px */
    font-weight: 500;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
    transition:
        color var(--t-fast),
        background-color var(--t-fast),
        border-color var(--t-fast),
        box-shadow var(--t-fast);
}

/* Hover solo en devices con hover capability · evita estado pegado tras
   tap en mobile. El cambio de explicación lo hace el JS (con delay 180ms
   anti-flicker) · el efecto visual del hover sigue siendo inmediato. */
@media (hover: hover) {
    .hero__chip:hover {
        color: var(--brand-glow);
        background: rgba(79, 181, 255, 0.10);
        border-color: rgba(79, 181, 255, 0.55);
        box-shadow: 0 0 14px rgba(79, 181, 255, 0.25);
    }
}

/* Estado activo · más intenso que hover · marca el chip "fijo" actual */
.hero__chip.is-active {
    color: var(--brand-glow);
    background: rgba(79, 181, 255, 0.18);
    border-color: rgba(79, 181, 255, 0.60);
    box-shadow:
        0 0 0 1px rgba(79, 181, 255, 0.35),
        0 0 18px rgba(79, 181, 255, 0.35);
}

.hero__chip:focus-visible {
    outline: 2px solid var(--brand-glow);
    outline-offset: 3px;
}

/* Panel de explicación · texto que cambia según chip activo. Fade ~150ms
   al cambiar via clase .is-changing (JS la toggle-ea). min-height evita
   "saltos" de layout cuando explicaciones varían en longitud entre chips.
   Reveal hereda de .hero__inner > * (motion.js REVEAL_SELECTORS). */
.hero__chips-explain {
    text-align: center;
    max-width: 56ch;
    margin: var(--space-3) auto 0;
    min-height: 3em;
    color: var(--text);
    font-size: var(--text-base);
    line-height: 1.55;
    text-wrap: pretty;
    opacity: 1;
    transition: opacity 150ms var(--ease-smooth);
}

.hero__chips-explain.is-changing {
    opacity: 0;
}

/* prefers-reduced-motion · sin transiciones decorativas, pero los chips
   SIGUEN funcionando · cambio de explicación es instantáneo (JS detecta
   la preferencia y no usa la clase .is-changing). Respeta la preferencia
   visual sin romper la funcionalidad esencial. */
@media (prefers-reduced-motion: reduce) {
    .hero__chip,
    .hero__chips-explain {
        transition: none;
    }
}

.hero__heading {
    font-size: clamp(1.5rem, 2.6vw, 2.375rem);   /* 24px → 38px · un escalón abajo del anterior 30→46 */
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    max-width: 26ch;
    margin-top: var(--space-2);
    text-align: center;                      /* centra el texto dentro de su max-width */
    text-wrap: balance;
}

.hero__tagline {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.6;
    max-width: 60ch;
    text-align: center;                      /* centra el texto dentro de su max-width */
    text-wrap: pretty;
}

.hero__anchors {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
    width: 100%;
}

.hero-anchor {
    padding: var(--space-5);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-inset);
}

.hero-anchor__label {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    margin-bottom: var(--space-2);
}

.hero-anchor__text {
    font-size: var(--text-base);
    color: var(--text);
    line-height: 1.5;
    text-wrap: balance;
}

.hero__cta {
    margin-top: var(--space-4);
}


/* --- 14.2 Audience splitter · header centrado --------------------------- */

.audience {
    padding-block: var(--section-py);
    position: relative;
}

.audience__header {
    text-align: center;
    max-width: 720px;
    margin-inline: auto;
    margin-bottom: clamp(3rem, 5vw, 4.5rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
}

.audience__title {
    font-size: clamp(2rem, 3.5vw, 2.875rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.audience__subtitle {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-width: 52ch;
    text-wrap: pretty;
}

.audience__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}


/* --- 14.3 Tarjetas del audience splitter -------------------------------- */

.audience-card {
    --card-accent:        var(--brand);
    --card-accent-glow:   var(--brand-glow);
    --card-accent-soft:   rgba(42, 141, 255, 0.18);
    --card-accent-deep:   var(--brand-deep);

    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-8);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    text-decoration: none;
    color: var(--text);
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: transform var(--t-base),
                border-color var(--t-base),
                box-shadow var(--t-base);
    box-shadow: var(--shadow-inset);
}

.audience-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(circle at 100% 0%,
                var(--card-accent-soft) 0%,
                transparent 55%);
    opacity: 0;
    transition: opacity var(--t-base);
    pointer-events: none;
    z-index: -1;
}

.audience-card:hover {
    transform: translateY(-3px);
    border-color: var(--card-accent);
    box-shadow: var(--shadow-lg), var(--shadow-inset);
}

.audience-card:hover::before {
    opacity: 1;
}

.audience-card:focus-visible {
    outline: 2px solid var(--card-accent-glow);
    outline-offset: 4px;
}

.audience-card__icon {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-lg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--card-accent-glow);
    background: linear-gradient(135deg,
                var(--card-accent-soft),
                rgba(0, 229, 255, 0.06));
    box-shadow: var(--shadow-inset);
}

.audience-card__icon svg {
    width: 28px;
    height: 28px;
}

.audience-card__title {
    font-size: var(--text-2xl);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.audience-card__desc {
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.6;
    flex: 1;
}

.audience-card__arrow {
    align-self: flex-start;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-pill);
    background-color: var(--card-accent-deep);
    color: var(--text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform var(--t-base), background-color var(--t-base);
    margin-top: var(--space-2);
}

.audience-card__arrow svg {
    width: 16px;
    height: 16px;
}


/* === 14.6 · Tabla comparativa · imagen 16:9 ES/EN server-side ============
   Sección que va debajo de los 4 pilares en la home neutral. La imagen
   completa se ve hasta max-width 1280px en desktop con border-radius +
   shadow para combinar con el lenguaje visual de cards. En mobile (<700px)
   el wrapper interno activa scroll horizontal con la imagen manteniendo
   min-width 700px · evita que la tabla quede diminuta y obliga al usuario
   a swipe lateral para verla legible. Hover-glow neón azul (4 capas) solo
   en PC con hover capability y sin reducción de movimiento. Fade-in al
   scroll vía .comparison__frame en REVEAL_SELECTORS (motion.js). */
.comparison {
    padding-block: var(--section-py);
}

.comparison__frame {
    position: relative;
    margin-left: auto;
    margin-right: auto;
    max-width: 1448px;
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: var(--bg-base);              /* fallback durante lazy load */
    box-shadow: var(--shadow-edge);          /* elevación leve · matchea cards */
    isolation: isolate;                      /* contiene el glow del hover */
    transition: box-shadow 350ms var(--ease-smooth);
}

/* Wrapper scrollable interno · necesario para que el scroll horizontal en
   mobile no rompa el border-radius del frame (overflow:hidden vs auto). En
   desktop el scroll no aparece porque el frame siempre es más ancho que el
   min-width de la imagen. -webkit-overflow-scrolling: touch para momentum
   nativo en iOS. */
.comparison__scroll {
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.comparison__img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: contain;                     /* imagen COMPLETA · sin recorte */
}

/* Mobile <700px · forzamos min-width 700px en la imagen para que la tabla
   mantenga tamaño legible. El wrapper .comparison__scroll captura el overflow
   y permite swipe lateral. border-radius del frame un escalón más chico para
   acompañar el lenguaje de cards en pantallas pequeñas. */
@media (max-width: 700px) {
    .comparison__img {
        min-width: 700px;
    }
    .comparison__frame {
        border-radius: var(--radius-lg);
    }
}

/* Hover-glow neón azul · 4 capas de box-shadow superpuestas (borde fino +
   inner glow + middle glow + outer halo) · SOLO en PC con hover capability
   Y sin reducción de movimiento. En touch/mobile y con reduced-motion la
   media query no matchea y la imagen queda sin glow. */
@media (hover: hover) {
    .comparison__frame:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

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

/* Espacio reducido entre los 4 pilares y la tabla comparativa cuando vienen
   inmediatamente seguidas (orden actual de la home: pilares → tabla). El
   padding-top del .comparison se reduce a clamp 0.5-1.25rem (8-20px) en vez
   del padding-block estándar de var(--section-py) (~48-80px). Sigue habiendo
   separación visible (no quedan pegadas) pero ~40-60px más juntas. El
   padding-bottom de .pillars se mantiene · da respiro a las sombras de las
   cards y evita que se pisen con el borde superior de la tabla. */
.comparison + .pillars {
    padding-top: clamp(0.5rem, 1.5vw, 1.25rem);
}

.audience-card:hover .audience-card__arrow {
    transform: translateX(4px);
    background-color: var(--card-accent);
}

/* Variante Partner · tinte emerald · diferencia visual respecto al Cliente */
.audience-card--partner {
    --card-accent:        var(--emerald);
    --card-accent-glow:   var(--emerald);
    --card-accent-soft:   rgba(0, 255, 163, 0.16);
    --card-accent-deep:   rgba(0, 80, 50, 0.7);
}


/* --- 14.4 Sección de los 4 pilares · header + grid ---------------------- */

.pillars {
    padding-block: var(--section-py);
    position: relative;
}

.pillars__header {
    text-align: center;
    max-width: 760px;
    margin-inline: auto;
    margin-bottom: clamp(3rem, 5vw, 4.5rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
}

.pillars__title {
    font-size: clamp(2rem, 3.5vw, 2.875rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.pillars__lead {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-width: 62ch;
    text-wrap: pretty;
}

/* Carrusel wrapper · contiene track + 2 flechas (las flechas solo en PC).
   position: relative para que las flechas absolutas se posicionen contra
   este contenedor. NO usa overflow propio · el wrapper queda en flujo
   normal y el sticky-reveal de la banda + sticky de la nav no se afectan. */
.pillars__carousel {
    position: relative;
}

/* Track del carrusel · flex horizontal con scroll-snap nativo. Reemplaza
   el grid anterior (que era 1/2/4 columnas) por un layout que escala a 5+
   cards con scroll horizontal. overflow-x: auto · overflow-y: visible para
   que las sombras de hover-lift no se recorten. -webkit-overflow-scrolling:
   touch da momentum nativo en iOS. Scrollbar oculto (no aporta info en este
   contexto · las flechas indican el control en PC y el swipe es natural
   en mobile). padding-block pequeño para que el lift de hover (-3px) y el
   shadow no se corten contra los bordes del wrapper. */
.pillars__grid {
    list-style: none;
    padding: var(--space-2) 0;
    margin: 0;
    display: flex;
    gap: var(--space-6);
    overflow-x: auto;
    overflow-y: visible;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--space-2);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.pillars__grid::-webkit-scrollbar {
    display: none;
}

/* La clase base .pillar-card y .pillar-card__inner viven en sección 5.
   Acá ajustamos solo el ícono individual para más prominencia visual. */
.pillar-card__icon {
    width: 56px;
    height: 56px;
}

.pillar-card__icon svg {
    width: 28px;
    height: 28px;
}

/* Cards · flex items con ancho fijo según breakpoint · snap al inicio.
   flex-shrink: 0 evita que se compriman. Mobile: 1.2 cards visibles (peek
   del 20% de la siguiente para indicar que hay más para scrollear).
   Tablet 640+: 2 cards completas. Desktop 1024+: 4 cards completas
   (la 5ta requiere usar la flecha next). */
.pillar-card {
    flex-shrink: 0;
    flex-basis: calc((100% - var(--space-6)) / 1.2);     /* mobile · 1.2 cards · peek de la siguiente */
    scroll-snap-align: start;
}

@media (min-width: 640px) {
    .pillar-card {
        flex-basis: calc((100% - var(--space-6)) / 2);   /* tablet · 2 cards */
    }
}

@media (min-width: 1024px) {
    .pillar-card {
        flex-basis: calc((100% - var(--space-6) * 3) / 4); /* desktop · 4 cards */
    }
}

/* Flechas del carrusel · ocultas por default (mobile/touch usa swipe nativo).
   Solo se muestran en desktop ≥1024px Y con hover capability (PC con mouse).
   En iPads con touch capacity quedan ocultas · el swipe nativo cubre la UX. */
.pillars__arrow {
    display: none;
}

@media (min-width: 1024px) and (hover: hover) {
    .pillars__arrow {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 48px;
        height: 48px;
        border-radius: 50%;
        background: rgba(2, 4, 11, 0.85);
        border: 1px solid rgba(79, 181, 255, 0.30);
        color: var(--brand-glow);
        cursor: pointer;
        z-index: 2;
        padding: 0;
        font: inherit;
        line-height: 0;
        transition:
            background-color 250ms var(--ease-smooth),
            border-color 250ms var(--ease-smooth),
            box-shadow 250ms var(--ease-smooth),
            opacity 250ms var(--ease-smooth);
    }

    /* Posicionar FUERA del container del carrusel para no tapar cards.
       calc negativo sale de la columna container con un offset razonable. */
    .pillars__arrow--prev {
        left: calc(var(--space-6) * -1);
    }

    .pillars__arrow--next {
        right: calc(var(--space-6) * -1);
    }

    .pillars__arrow svg {
        width: 18px;
        height: 18px;
    }

    /* Hover · glow neón azul (mismo lenguaje visual que los nav links) */
    .pillars__arrow:hover {
        background: rgba(79, 181, 255, 0.18);
        border-color: rgba(79, 181, 255, 0.55);
        box-shadow:
            0 0 0 1px rgba(79, 181, 255, 0.30),
            0 0 18px rgba(79, 181, 255, 0.35);
    }

    .pillars__arrow:focus-visible {
        outline: 2px solid var(--brand-glow);
        outline-offset: 3px;
    }

    /* Estado disabled · visible pero atenuado · cursor not-allowed.
       opacity 0.30 deja que el usuario vea que existen pero no se pueden usar. */
    .pillars__arrow[disabled],
    .pillars__arrow:disabled {
        opacity: 0.30;
        cursor: not-allowed;
        pointer-events: none;
    }
}

/* prefers-reduced-motion · scroll-behavior auto en el track para que las
   flechas hagan jump instantáneo en lugar de smooth scroll. El swipe en
   mobile sigue funcionando igual (es animación del browser, no nuestra). */
@media (prefers-reduced-motion: reduce) {
    .pillars__grid {
        scroll-behavior: auto;
    }
}


/* --- 14.5 Responsive del Home neutral ----------------------------------- */

@media (min-width: 640px) {
    .hero__anchors {
        grid-template-columns: 1fr 1fr;
    }
}

@media (min-width: 768px) {
    .audience__grid {
        grid-template-columns: 1fr 1fr;
    }
    /* .pillars__grid ya no usa grid-template-columns · refactorizado a flex
       carrusel en §14.4 (cards con flex-basis por breakpoint). */
}

@media (min-width: 1024px) {
    /* En desktop con 4 columnas la card es estrecha · aspect 1:1 evita que
       el visual quede excesivamente alto y desbalancee la card respecto al
       texto. Las 5 imágenes siguen iguales entre sí en este viewport.
       Nota: la regla del grid-template-columns: repeat(4, 1fr) se reemplazó
       por el flex-basis de .pillar-card (§14.4 arriba) en el refactor a
       carrusel. */
    .pillar-card__media {
        aspect-ratio: 1 / 1;
    }
}


/* ===== 15. VISTA CLIENTE ================================================== */


/* --- 15.1 Nav contextual cliente · sticky bajo topbar ------------------- */

.nav-cliente {
    position: sticky;
    /* El topbar pill flota top clamp(0.75rem, 2vw, 1.5rem) con ~52px de alto.
       El nav-cliente se stickea unos 12-16px más abajo para no chocar.
       Sin backdrop-filter · bug documentado de Chromium hace que sticky se
       rompa cuando el elemento sticky mismo tiene backdrop-filter. Para
       compensar el frosted glass perdido, subimos el alpha del background
       de 0.72 a 0.92 · queda casi opaco pero el efecto visual es similar
       sobre fondos dark del sitio. */
    top: clamp(4.5rem, 9vw, 6rem);
    z-index: var(--z-sticky);
    padding: var(--space-3) 0;
    background-color: rgba(2, 4, 11, 0.92);
    border-bottom: 1px solid var(--text-edge);
}

.nav-cliente__inner {
    display: flex;
    align-items: center;
    gap: var(--space-5);
}

.nav-cliente__badge {
    flex-shrink: 0;
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    padding: var(--space-2) var(--space-3);
    border: 1px solid rgba(79, 181, 255, 0.32);
    border-radius: var(--radius-pill);
    background-color: rgba(42, 141, 255, 0.08);
    white-space: nowrap;
    line-height: 1;
}

.nav-cliente__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: var(--space-2);
    flex: 1;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* Mobile · fade edges para sugerir el scroll horizontal */
    -webkit-mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
            mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
}

.nav-cliente__list::-webkit-scrollbar {
    display: none;
}

.nav-cliente__item {
    flex-shrink: 0;
}

.nav-cliente__link {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    border-radius: var(--radius-pill);
    transition:
        color var(--t-fast),
        background-color var(--t-fast),
        text-shadow var(--t-fast),
        box-shadow var(--t-fast);
    white-space: nowrap;
    position: relative;
}

/* Hover neón azul brand-glow · SOLO en devices con hover capability para que
   tras un tap en mobile el glow no quede pegado. text-shadow + box-shadow
   crean el efecto "neon" suave: texto azul con halo + borde fino + halo
   exterior del pill. */
@media (hover: hover) {
    .nav-cliente__link:hover {
        color: var(--brand-glow);
        background-color: rgba(79, 181, 255, 0.10);
        text-shadow: 0 0 12px rgba(79, 181, 255, 0.55);
        box-shadow:
            0 0 0 1px rgba(79, 181, 255, 0.30),
            0 0 14px rgba(79, 181, 255, 0.25);
    }
}

.nav-cliente__link:focus-visible {
    outline: 2px solid var(--brand-glow);
    outline-offset: 2px;
}

/* Pestaña activa · selector semántico [aria-current="page"] · sin clase extra */
.nav-cliente__link[aria-current="page"] {
    color: var(--brand-glow);
    background-color: rgba(79, 181, 255, 0.10);
}

.nav-cliente__link[aria-current="page"]::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -6px;
    transform: translateX(-50%);
    width: 16px;
    height: 2px;
    border-radius: var(--radius-pill);
    background-color: var(--brand-glow);
    box-shadow: 0 0 8px rgba(79, 181, 255, 0.6);
}

/* Desktop · ya hay espacio para todas las pestañas, sacamos el mask de scroll */
@media (min-width: 768px) {
    .nav-cliente__list {
        -webkit-mask-image: none;
                mask-image: none;
        overflow-x: visible;
        gap: var(--space-3);
    }
}


/* --- 15.1b Nav contextual HOME · 4 pestañas globales, sin badge -------- */
/* Mismo patrón que .nav-cliente__* (sticky, blur, brand-glow azul) pero
   sin badge y con justify-content: center para coherencia visual con el
   resto del home (todo centrado horizontalmente). */
.nav-home {
    position: sticky;
    /* Sin backdrop-filter · bug de Chromium rompe sticky cuando el elemento
       sticky mismo tiene backdrop-filter aplicado. Alpha del bg sube de
       0.72 a 0.92 para compensar el frosted glass perdido. */
    top: clamp(4.5rem, 9vw, 6rem);
    z-index: var(--z-sticky);
    padding: var(--space-3) 0;
    background-color: rgba(2, 4, 11, 0.92);
    border-bottom: 1px solid var(--text-edge);
}

.nav-home__inner {
    display: flex;
    align-items: center;
    justify-content: center;            /* 4 tabs centrados (vs flex-start de cliente/partner que tienen badge) */
}

.nav-home__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* Mobile · fade edges para sugerir el scroll horizontal */
    -webkit-mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
            mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
}

.nav-home__list::-webkit-scrollbar {
    display: none;
}

.nav-home__item {
    flex-shrink: 0;
}

.nav-home__link {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    border-radius: var(--radius-pill);
    transition:
        color var(--t-fast),
        background-color var(--t-fast),
        text-shadow var(--t-fast),
        box-shadow var(--t-fast);
    white-space: nowrap;
    position: relative;
}

/* Hover neón azul brand-glow · SOLO con hover capability (evita glow pegado
   en mobile tras un tap). Mismo efecto que nav-cliente · home y cliente
   comparten identidad visual azul brand-glow. */
@media (hover: hover) {
    .nav-home__link:hover {
        color: var(--brand-glow);
        background-color: rgba(79, 181, 255, 0.10);
        text-shadow: 0 0 12px rgba(79, 181, 255, 0.55);
        box-shadow:
            0 0 0 1px rgba(79, 181, 255, 0.30),
            0 0 14px rgba(79, 181, 255, 0.25);
    }
}

.nav-home__link:focus-visible {
    outline: 2px solid var(--brand-glow);
    outline-offset: 2px;
}

/* Pestaña activa · brand-glow azul + underline animado */
.nav-home__link[aria-current="page"] {
    color: var(--brand-glow);
    background-color: rgba(79, 181, 255, 0.10);
}

.nav-home__link[aria-current="page"]::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -6px;
    transform: translateX(-50%);
    width: 16px;
    height: 2px;
    border-radius: var(--radius-pill);
    background-color: var(--brand-glow);
    box-shadow: 0 0 8px rgba(79, 181, 255, 0.6);
}

/* Desktop · sacamos el mask del scroll horizontal (todo cabe) */
@media (min-width: 768px) {
    .nav-home__list {
        -webkit-mask-image: none;
                mask-image: none;
        overflow-x: visible;
        gap: var(--space-3);
    }
}


/* --- 15.2 Hero específico de subpáginas · más sobrio que el home ------- */

.hero-page {
    position: relative;
    min-height: 70dvh;
    display: flex;
    align-items: center;
    /* Topbar (~52px) + nav-cliente sticky (~50px) + respiro · total clamp */
    padding-top: clamp(9rem, 16vw, 13rem);
    padding-bottom: var(--section-py);
}

.hero-page__inner {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);
    max-width: 880px;
    position: relative;
    z-index: 3;
}

.hero-page__heading {
    font-size: clamp(2.5rem, 6vw, 5rem);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.02em;
    max-width: 14ch;
    text-wrap: balance;
}

.hero-page__subtitle {
    font-size: var(--text-xl);
    color: var(--text-muted);
    line-height: 1.5;
    max-width: 58ch;
    text-wrap: pretty;
    margin-top: calc(var(--space-2) * -1);
}

.hero-page__cta {
    margin-top: var(--space-3);
}


/* --- 15.3 Zig-zag · 3 features alternados con visual decorativo ------- */

.features-zigzag {
    padding-block: var(--section-py);
}

.features-zigzag__header {
    max-width: 720px;
    margin-bottom: clamp(3rem, 6vw, 5rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.features-zigzag__title {
    font-size: clamp(1.875rem, 3.5vw, 2.875rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.feature-block {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-8);
    align-items: center;
}

.feature-block + .feature-block {
    border-top: 1px solid var(--text-edge);
    margin-top: clamp(3rem, 6vw, 5rem);
    padding-top: clamp(3rem, 6vw, 5rem);
}

.feature-block__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 56ch;
}

.feature-block__step {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.feature-block__title {
    font-size: clamp(1.5rem, 2.5vw, 2rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.feature-block__body {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.6;
    text-wrap: pretty;
}

.feature-block__visual {
    width: 100%;
}

/* Visual decorativo · doppelrand + SVG protagonista + chip de estado */

.feature-visual {
    position: relative;
    aspect-ratio: 1;
    width: 100%;
    max-width: 360px;
    margin-inline: auto;
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    overflow: hidden;
    isolation: isolate;
}

.feature-visual::before {
    content: '';
    position: absolute;
    inset: 6px;
    border-radius: calc(var(--radius-xl) - 6px);
    background-color: var(--bg-layer);
    box-shadow: var(--shadow-inset);
    z-index: 0;
}

.feature-visual__svg {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    color: var(--brand-glow);
    padding: var(--space-6);
}

/* Imagen reemplaza al SVG en las 3 cards de la sección "Tres cosas que vas
   a recibir" (clientes/index.php). Va A SANGRADO dentro del frame interior
   del recuadro (zona del ::before, 348×348 en outer 360×360) · sin padding
   como tenía el SVG · object-fit: cover llena el cuadrado manteniendo
   aspecto. border-radius propio matchea el del ::before (radius-xl menos
   los 6px de padding del outer) · esquinas redondeadas perfectas, sin
   bordes cuadrados asomando. z-index: 1 igual que el SVG · queda DEBAJO
   del chip (z-index: 2). Si la imagen no carga, el ::before debajo se ve
   como fallback dark con bg-layer. */
.feature-visual__img {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center center;
    border-radius: calc(var(--radius-xl) - 6px);
}

.feature-visual__chip {
    position: absolute;
    bottom: var(--space-5);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--emerald);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    padding: var(--space-2) var(--space-3);
    background-color: rgba(0, 255, 163, 0.10);
    border: 1px solid rgba(0, 255, 163, 0.32);
    border-radius: var(--radius-pill);
    white-space: nowrap;
}

.feature-visual__chip::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: 0 0 8px rgba(0, 255, 163, 0.7);
}

/* === Hover-glow neón scoped por sección · .feature-visual--photo ============
   El sistema más usado del proyecto (zigzag de clientes/partners + quienes
   somos) hasta ahora NO tenía glow definido. Esto lo agrega siguiendo el
   patrón consistente del resto: 4 capas neón, color azul por default
   (cliente/home), emerald override via body.section-partner. Para casos
   cross-section como quienes-somos C partners en body.section-home, el
   modifier .feature-visual--for-partner permite override por elemento.

   Reduced-motion: el glow SIGUE VISIBLE pero sin transition · aparece
   instantáneo al hover (criterio uniformado con las otras 5 reglas de
   hover-glow del proyecto · cambio de color/box-shadow no es 'motion'
   WCAG, solo se desactiva la animación de 350ms). ===========================  */
.feature-visual--photo {
    transition: box-shadow 350ms var(--ease-smooth);
}

@media (hover: hover) {
    .feature-visual--photo:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

/* Override EMERALD · 2 caminos: (a) body.section-partner para partners/* pages,
   (b) modifier .feature-visual--for-partner para fotos partner en section-home
   (caso quienes-somos C). Specificity (0,3,1) y (0,3,0) ambos ganan sobre la
   base (0,2,0). En partner pages CON modifier, body.section-partner gana por
   higher specificity · sigue siendo emerald sin colisión. */
@media (hover: hover) {
    body.section-partner .feature-visual--photo:hover,
    .feature-visual--for-partner.feature-visual--photo:hover {
        box-shadow:
            0 0 0 1px var(--emerald),
            0 0 24px rgba(0, 255, 163, 0.45),
            0 0 60px rgba(0, 255, 163, 0.30),
            0 0 120px rgba(0, 255, 163, 0.15);
    }
}

@media (prefers-reduced-motion: reduce) {
    .feature-visual--photo {
        transition: none;
    }
}

@media (min-width: 768px) {
    .feature-block {
        grid-template-columns: 1fr 1fr;
        gap: clamp(3rem, 6vw, 5rem);
    }

    /* En la versión reverse, el visual va a la columna izquierda */
    .feature-block--reverse .feature-block__visual {
        order: -1;
    }
}


/* --- 15.3b CTA strip · cierre de página hacia contacto ---------------- */

.cta-strip {
    padding-block: var(--section-py);
}

.cta-strip__inner {
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: clamp(2rem, 5vw, 4rem);
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    align-items: flex-start;
}

.cta-strip__title {
    font-size: clamp(1.5rem, 3vw, 2.25rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.cta-strip__subtitle {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.55;
    max-width: 56ch;
    margin-top: var(--space-2);
}

@media (min-width: 768px) {
    .cta-strip__inner {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-8);
    }
}


/* --- 15.4 Steps timeline · pasos numerados con línea conectora vertical -- */

.steps {
    padding-block: var(--section-py);
}

.steps__list {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: step;
}

.step-block {
    display: grid;
    grid-template-columns: 60px 1fr;
    gap: var(--space-5);
    padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
    position: relative;
}

.step-block:last-child {
    padding-bottom: 0;
}

/* Línea SVG dashed conectando indicators · va del fondo del indicator
   anterior hasta el tope del siguiente. La hacemos con background gradient
   + background-size para emular dashed sin SVG real (más simple). */
.step-block:not(:last-child)::before {
    content: '';
    position: absolute;
    top: 60px;
    left: 29px;
    bottom: 0;
    width: 2px;
    background-image: linear-gradient(to bottom,
        var(--brand-glow) 0%,
        var(--brand-glow) 50%,
        transparent 50%);
    background-size: 100% 12px;
    opacity: 0.4;
}

.step-indicator {
    width: 60px;
    height: 60px;
    border-radius: var(--radius-pill);
    background-color: var(--bg-layer);
    border: 1px solid rgba(79, 181, 255, 0.4);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-inset), var(--shadow-sm);
    position: relative;
    z-index: 2;
    flex-shrink: 0;
}

.step-indicator__number {
    font-family: var(--font-brand);
    font-weight: 800;
    font-size: 1.375rem;
    color: var(--brand-glow);
    letter-spacing: -0.01em;
    line-height: 1;
}

.step-block__content {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    padding-top: var(--space-3);
}

.step-block__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 56ch;
}

.step-block__label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.step-block__title {
    font-size: clamp(1.5rem, 2.5vw, 2rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.step-block__body {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.6;
    text-wrap: pretty;
}

.step-block__visual {
    width: 100%;
}

@media (min-width: 768px) {
    .step-block {
        grid-template-columns: 80px 1fr;
        gap: var(--space-8);
    }

    .step-block:not(:last-child)::before {
        left: 39px;
    }

    .step-block__content {
        grid-template-columns: 1fr 1fr;
        gap: clamp(2.5rem, 5vw, 4rem);
        align-items: center;
    }

    /* En --reverse, el visual queda en la columna izquierda del content */
    .step-block--reverse .step-block__visual {
        order: -1;
    }

    .step-indicator {
        width: 80px;
        height: 80px;
    }

    .step-indicator__number {
        font-size: 1.625rem;
    }
}


/* --- 15.5 Hero con globe abstracto · porque.php ----------------------- */

.hero-page__inner--two-col {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
    max-width: 1200px;
}

.hero-page__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    align-items: flex-start;
}

.hero-page__visual {
    display: flex;
    justify-content: center;
    align-items: center;
}

.globe {
    position: relative;
    width: 280px;
    height: 280px;
    color: var(--brand-glow);                      /* currentColor para SVG version (partner) */
}

/* Variante FOTO · usada en clientes/porque.php (la cliente ya migró a foto)
   Aporta look de tarjeta · borde azul tenue + sombra base + esquinas xl + iso
   para contener el glow del hover. La versión partner (sin --photo) mantiene
   el globe SVG dibujado, sin estos tratamientos. */
.globe--photo {
    border-radius: var(--radius-xl);
    overflow: hidden;
    border: 1px solid rgba(79, 181, 255, 0.18);   /* azul brand al 18% · superficie sutil */
    background: var(--bg-base);                    /* fallback durante lazy load de la foto */
    box-shadow: var(--shadow-edge);                /* sombra base · matchea .comparison__frame */
    isolation: isolate;                            /* contiene el glow del hover */
    transition: box-shadow 350ms var(--ease-smooth);
}

.globe__svg {
    display: block;
    width: 100%;
    height: 100%;
}

.globe__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;                             /* recorta cuadrado sin deformar */
}

/* Pulse del núcleo central · cada 4s · sutil · sólo SVG version (partner) */
.globe__core {
    transform-box: fill-box;
    transform-origin: center;
    animation: globe-core-pulse 4s ease-in-out infinite;
}

@keyframes globe-core-pulse {
    0%, 100% { transform: scale(1);    opacity: 0.85; }
    50%      { transform: scale(1.08); opacity: 1;    }
}

/* Orbit de los nodos · 80s linear, muy lento, casi imperceptible · sólo SVG.
   Rotamos alrededor del centro del SVG (180, 180) explícitamente. */
.globe__orbit {
    transform-origin: 180px 180px;
    animation: globe-orbit 80s linear infinite;
}

@keyframes globe-orbit {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}

/* Hover-glow neón azul · 4 capas idénticas a .comparison__frame:hover ·
   SOLO sobre la variante foto · SOLO en PC con hover capability Y sin
   reducción de movimiento. En touch y con reduced-motion la media query no
   matchea y la foto queda con la sombra base sin glow. */
@media (hover: hover) {
    .globe--photo:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

/* Hover-glow EMERALD · 4 capas mismas estructura que el azul pero en verde
   para la versión partner (foto trae glow verde incorporado, evita choque
   verde+azul). Scoped via body.section-partner para sobrescribir SOLO en
   partner sin tocar el comportamiento cliente. Specificity (0,2,1) > la
   regla base (0,1,1) · gana en partner por orden CSS + specificity. */
@media (hover: hover) {
    body.section-partner .globe--photo:hover {
        box-shadow:
            0 0 0 1px var(--emerald),
            0 0 24px rgba(0, 255, 163, 0.45),
            0 0 60px rgba(0, 255, 163, 0.30),
            0 0 120px rgba(0, 255, 163, 0.15);
    }
}

/* Reduced motion · desactivamos las anims del SVG version Y la transición de
   box-shadow de la variante foto (la media de hover ya bloquea el glow, esto
   solo evita cualquier animación residual). */
@media (prefers-reduced-motion: reduce) {
    .globe__core,
    .globe__orbit {
        animation: none;
    }
    .globe--photo {
        transition: none;
    }
}

@media (min-width: 768px) {
    .hero-page__inner--two-col {
        grid-template-columns: 1.2fr 1fr;
    }
    .globe {
        width: 360px;
        height: 360px;
    }
}


/* --- 15.6 Bento asimétrico · 4 pilares + métricas --------------------- */

.bento {
    padding-block: var(--section-py);
}

.bento__header {
    max-width: 720px;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.bento__title {
    font-size: clamp(1.875rem, 3.5vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.bento__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
}

/* Card base · doppelrand consistente con el resto del bloque */
.bento__card {
    background-color: var(--bg-elev);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    position: relative;
    overflow: hidden;
}

.bento__card-inner {
    background-color: var(--bg-layer);
    border-radius: calc(var(--radius-xl) - 6px);
    padding: clamp(1.5rem, 3vw, 2.25rem);
    height: 100%;
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.bento__card-icon {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(42, 141, 255, 0.18), rgba(0, 229, 255, 0.08));
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-glow);
    box-shadow: var(--shadow-inset);
}

.bento__card-icon svg {
    width: 28px;
    height: 28px;
}

.bento__card-label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.18em;
}

.bento__card-title {
    font-size: clamp(1.25rem, 2vw, 1.625rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.bento__card-body {
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.6;
}

.bento__card-chip {
    align-self: flex-start;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--emerald);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    padding: 4px var(--space-3);
    background-color: rgba(0, 255, 163, 0.10);
    border: 1px solid rgba(0, 255, 163, 0.32);
    border-radius: var(--radius-pill);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: auto;
}

.bento__card-chip::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: 0 0 8px rgba(0, 255, 163, 0.7);
}

/* Hero card (pilar 1) · más prominente */
.bento__card--hero .bento__card-icon {
    width: 64px;
    height: 64px;
}

.bento__card--hero .bento__card-icon svg {
    width: 32px;
    height: 32px;
}

.bento__card--hero .bento__card-title {
    font-size: clamp(1.5rem, 2.5vw, 2rem);
}

.bento__card-bullets {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.bento__card-bullets li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    font-size: var(--text-base);
    color: var(--text);
    line-height: 1.5;
}

.bento__card-bullets li::before {
    content: '';
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 3px;
    background-color: rgba(0, 255, 163, 0.12);
    border: 1px solid rgba(0, 255, 163, 0.45);
    border-radius: 50%;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 8l3 3 5-6' stroke='%2300FFA3' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-size: 12px;
    background-position: center;
    background-repeat: no-repeat;
}

/* Métrica destacada dentro del pilar 1 */
.bento__card-metric {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--text-edge);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.bento__card-metric-cifra {
    font-family: var(--font-brand);
    font-weight: 800;
    font-size: clamp(2.25rem, 4vw, 3rem);
    color: var(--brand-glow);
    line-height: 1;
    letter-spacing: -0.02em;
}

.bento__card-metric-label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    line-height: 1.4;
}

/* Card de 4 métricas · grid interno 2x2 */
.bento__card--metrics .bento__card-inner {
    padding: clamp(1.25rem, 2.5vw, 1.75rem);
}

.bento__metrics-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    height: 100%;
}

.bento__metric {
    padding: var(--space-4);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    box-shadow: var(--shadow-inset);
    justify-content: center;
}

.bento__metric-cifra {
    font-family: var(--font-brand);
    font-weight: 800;
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    color: var(--brand-glow);
    line-height: 1;
    letter-spacing: -0.02em;
}

.bento__metric-label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    line-height: 1.4;
}

/* Bento responsive · simplificación progresiva entre breakpoints */

@media (min-width: 640px) {
    .bento__grid {
        grid-template-columns: 1fr 1fr;
    }
    .bento__card--hero {
        grid-column: 1 / -1;
    }
}

@media (min-width: 1024px) {
    .bento__grid {
        grid-template-columns: repeat(12, 1fr);
        grid-auto-flow: dense;
    }
    .bento__card--hero       { grid-column: span 8; grid-row: span 2; }
    .bento__card--gps        { grid-column: span 4; }
    .bento__card--background { grid-column: span 4; }
    .bento__card--payments   { grid-column: span 6; }
    .bento__card--metrics    { grid-column: span 6; }
}


/* --- 15.7 Visibility · texto + badges + mapa GPS ---------------------- */

.visibility {
    padding-block: var(--section-py);
}

.visibility__layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}

.visibility__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    max-width: 56ch;
}

.visibility__title {
    font-size: clamp(1.875rem, 3vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.visibility__body {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.6;
}

.badge-list {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.badge-list__item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    color: var(--text);
    line-height: 1.4;
}

.badge-list__check {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background-color: rgba(0, 255, 163, 0.12);
    border: 1px solid rgba(0, 255, 163, 0.45);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--emerald);
}

.badge-list__check svg {
    width: 12px;
    height: 12px;
}

/* Mapa GPS · card doppelrand con SVG decorativo + chip flotante */

.visibility__map {
    width: 100%;
}

.gps-map {
    position: relative;
    aspect-ratio: 1.15 / 1;
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    overflow: hidden;
    isolation: isolate;
}

.gps-map::before {
    content: '';
    position: absolute;
    inset: 6px;
    border-radius: calc(var(--radius-xl) - 6px);
    background-color: var(--bg-layer);
    box-shadow: var(--shadow-inset);
    z-index: 0;
}

.gps-map__svg {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    padding: var(--space-4);
    color: var(--brand-glow);
}

/* Foto variante · sangrado en el frame interior (sin padding), border-radius
   matchea las esquinas internas del ::before. Misma posición que el SVG (z:1)
   para que el chip (.gps-map__chip z:2) siga flotando encima. */
.gps-map__img {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: calc(var(--radius-xl) - 6px);
}

/* Pulse del pin destino · 2.5s ease-out, scale + fade */
.gps-map__pulse {
    transform-box: fill-box;
    transform-origin: center;
    animation: gps-pulse 2.5s ease-out infinite;
}

@keyframes gps-pulse {
    0%   { transform: scale(0.7); opacity: 0.6; }
    100% { transform: scale(2);   opacity: 0;   }
}

.gps-map__chip {
    position: absolute;
    top: var(--space-5);
    right: var(--space-5);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--emerald);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    padding: var(--space-2) var(--space-3);
    background-color: rgba(0, 255, 163, 0.10);
    border: 1px solid rgba(0, 255, 163, 0.32);
    border-radius: var(--radius-pill);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.gps-map__chip::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: 0 0 8px rgba(0, 255, 163, 0.7);
}

@media (prefers-reduced-motion: reduce) {
    .gps-map__pulse {
        animation: none;
    }
}

/* Modifier · activa transición de box-shadow para el hover-glow neón azul.
   Scoped al modifier · cero impacto en partners/porque.php que sigue usando
   .gps-map sin --photo. */
.gps-map--photo {
    transition: box-shadow 350ms var(--ease-smooth);
}

/* Hover-glow neón azul · 4 capas idénticas a .comparison__frame:hover y a
   .globe--photo:hover · SOLO sobre la variante foto · SOLO en PC con hover
   capability Y sin reducción de movimiento. En touch y con reduced-motion la
   media query no matchea y la card queda con su sombra base sin glow. */
@media (hover: hover) {
    .gps-map--photo:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

/* Container cuadrado · scoped a partner via body.section-partner para no
   afectar cliente que sigue con aspect 1.15:1 landscape. Specificity (0,2,1)
   gana sobre la regla base .gps-map { aspect-ratio: 1.15/1 } de (0,1,0).
   Necesario porque la foto partner-visibilidad.webp es 1:1 nativa y queremos
   que se vea completa sin recortes laterales. */
body.section-partner .gps-map--photo {
    aspect-ratio: 1 / 1;
}

/* Hover-glow EMERALD · 4 capas misma estructura que el azul de cliente pero
   en verde para alinear con el tinte emerald de la pagina partner. Scoped
   via body.section-partner para sobrescribir SOLO partner. Specificity
   (0,3,1) gana sobre la regla base .gps-map--photo:hover (0,2,0). */
@media (hover: hover) {
    body.section-partner .gps-map--photo:hover {
        box-shadow:
            0 0 0 1px var(--emerald),
            0 0 24px rgba(0, 255, 163, 0.45),
            0 0 60px rgba(0, 255, 163, 0.30),
            0 0 120px rgba(0, 255, 163, 0.15);
    }
}

/* Override defensivo · con reducción de movimiento desactivamos también la
   transición de box-shadow de la variante foto (la media de hover ya bloquea
   el glow, esto solo evita cualquier animación residual). */
@media (prefers-reduced-motion: reduce) {
    .gps-map--photo {
        transition: none;
    }
}

@media (min-width: 768px) {
    .visibility__layout {
        grid-template-columns: 1fr 1.1fr;
    }
}


/* --- 15.8 Antes y durante · 2 moment cards simétricas ---------------- */

.moments {
    padding-block: var(--section-py);
}

.moments__header {
    max-width: 720px;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.moments__title {
    font-size: clamp(1.875rem, 3.5vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.moments__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

.moment-card {
    background-color: var(--bg-elev);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    position: relative;
}

.moment-card__inner {
    background-color: var(--bg-layer);
    border-radius: calc(var(--radius-xl) - 6px);
    padding: clamp(1.75rem, 3vw, 2.5rem);
    height: 100%;
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.moment-card__visual {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-glow);
    box-shadow: var(--shadow-inset);
}

.moment-card__visual svg {
    width: 40px;
    height: 40px;
}

.moment-card__label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--brand-glow);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.moment-card__title {
    font-size: clamp(1.375rem, 2.5vw, 1.875rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.moment-card__items {
    list-style: none;
    padding: 0;
    margin: var(--space-2) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.moment-card__items li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.5;
}

.moment-card__items li::before {
    content: '';
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 3px;
    background-color: rgba(0, 255, 163, 0.12);
    border: 1px solid rgba(0, 255, 163, 0.45);
    border-radius: 50%;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 8l3 3 5-6' stroke='%2300FFA3' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-size: 12px;
    background-position: center;
    background-repeat: no-repeat;
}

@media (min-width: 768px) {
    .moments__grid {
        grid-template-columns: 1fr 1fr;
    }
}


/* --- 15.9 Plataforma escalable · 4 features bottom ------------------- */

.platform {
    padding-block: var(--section-py);
}

.platform__header {
    max-width: 720px;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.platform__title {
    font-size: clamp(1.875rem, 3.5vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.platform__subtitle {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.55;
    max-width: 60ch;
}

.platform__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
}

.platform-feature {
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    box-shadow: var(--shadow-inset);
    transition: border-color var(--t-base), transform var(--t-base);
}

.platform-feature:hover {
    border-color: rgba(79, 181, 255, 0.32);
    transform: translateY(-2px);
}

.platform-feature__icon {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(42, 141, 255, 0.16), rgba(0, 229, 255, 0.06));
    color: var(--brand-glow);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.platform-feature__icon svg {
    width: 22px;
    height: 22px;
}

.platform-feature__title {
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.platform-feature__body {
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: 1.55;
}

@media (min-width: 640px) {
    .platform__grid {
        grid-template-columns: 1fr 1fr;
    }
}

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


/* --- 15.10 Servicios · Residencial · featured + grid 2x2 ----------- */

.residential {
    padding-block: var(--section-py);
}

.residential__header {
    max-width: 720px;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.residential__title {
    font-size: clamp(1.875rem, 3.5vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.residential__lead {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.55;
    max-width: 60ch;
}

/* Featured · overview del residencial · doppelrand 2-col en desktop */

.residential-featured {
    background-color: var(--bg-elev);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    margin-bottom: clamp(2rem, 4vw, 3.5rem);
}

.residential-featured__inner {
    background-color: var(--bg-layer);
    border-radius: calc(var(--radius-xl) - 6px);
    padding: clamp(1.75rem, 4vw, 3rem);
    box-shadow: var(--shadow-inset);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    align-items: center;
}

.residential-featured__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.residential-featured__title {
    font-size: clamp(1.5rem, 2.5vw, 2rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.residential-featured__body {
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.6;
}

.residential-featured__bullets {
    list-style: none;
    padding: 0;
    margin: var(--space-2) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.residential-featured__bullets li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    font-size: var(--text-base);
    color: var(--text);
    line-height: 1.5;
}

.residential-featured__bullets li::before {
    content: '';
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 3px;
    background-color: rgba(0, 255, 163, 0.12);
    border: 1px solid rgba(0, 255, 163, 0.45);
    border-radius: 50%;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 8l3 3 5-6' stroke='%2300FFA3' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-size: 12px;
    background-position: center;
    background-repeat: no-repeat;
}

.residential-featured__visual {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-glow);
}

.residential-featured__visual svg {
    width: 100%;
    height: auto;
    max-width: 280px;
}

/* Foto variante · el wrapper se convierte en card de superficie con borde
   sutil + sombra + radius. Constraint a 420px max (más presencia que el SVG
   original que estaba capped a 280px). Aspect 1:1 enforced. margin-inline
   auto centra dentro de la celda del grid de .residential-featured__inner. */
.residential-featured__visual--photo {
    width: 100%;
    max-width: 420px;
    aspect-ratio: 1 / 1;
    margin-inline: auto;
    border-radius: var(--radius-xl);
    overflow: hidden;
    border: 1px solid rgba(79, 181, 255, 0.18);   /* azul brand al 18% · igual que .globe--photo */
    background: var(--bg-base);                    /* fallback durante lazy load */
    box-shadow: var(--shadow-edge);                /* sombra base · matchea .comparison__frame */
    isolation: isolate;                            /* contiene el glow del hover */
    transition: box-shadow 350ms var(--ease-smooth);
}

.residential-featured__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;                             /* llena el card 420x420, recorta sin deformar */
}

/* Hover-glow neón azul · 4 capas idénticas a .comparison__frame:hover,
   .globe--photo:hover y .gps-map--photo:hover · SOLO sobre la variante foto
   · SOLO en PC con hover capability Y sin reducción de movimiento. En touch
   y con reduced-motion la media query no matchea y la card queda con su
   sombra base sin glow. */
@media (hover: hover) {
    .residential-featured__visual--photo:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

/* Override defensivo · con reducción de movimiento desactivamos también la
   transición de box-shadow de la variante foto (la media de hover ya bloquea
   el glow, esto solo evita cualquier animación residual). */
@media (prefers-reduced-motion: reduce) {
    .residential-featured__visual--photo {
        transition: none;
    }
}

/* Grid 2x2 de los 4 subtipos · cards compactas */

.residential-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
}

.service-card {
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    box-shadow: var(--shadow-inset);
    transition: border-color var(--t-base), transform var(--t-base);
}

.service-card:hover {
    border-color: rgba(79, 181, 255, 0.32);
    transform: translateY(-2px);
}

.service-card__icon {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(42, 141, 255, 0.16), rgba(0, 229, 255, 0.06));
    color: var(--brand-glow);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

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

.service-card__title {
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.service-card__body {
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: 1.55;
}

@media (min-width: 768px) {
    .residential-featured__inner {
        grid-template-columns: 1.4fr 1fr;
        gap: clamp(2rem, 5vw, 4rem);
    }
    .residential-grid {
        grid-template-columns: 1fr 1fr;
    }
}


/* --- 15.11 Servicios · Comercial · coming soon banner 2-col -------- */

.commercial {
    padding-block: var(--section-py);
}

.commercial__banner {
    background-color: var(--bg-deep);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: clamp(2rem, 5vw, 4rem);
    box-shadow: var(--shadow-inset);
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2rem, 4vw, 3rem);
    align-items: center;
    position: relative;
    overflow: hidden;
}

/* Subtle warm wash · señala "no es el principal pero está vivo" */
.commercial__banner::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(135deg,
        transparent 0%,
        rgba(255, 181, 71, 0.04) 100%);
    pointer-events: none;
}

.commercial__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    align-items: flex-start;
    position: relative;
    z-index: 1;
}

.commercial__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--warn);
    text-transform: uppercase;
    letter-spacing: 0.2em;
    padding: var(--space-2) var(--space-3);
    background-color: rgba(255, 181, 71, 0.08);
    border: 1px solid rgba(255, 181, 71, 0.32);
    border-radius: var(--radius-pill);
}

.commercial__badge-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: 0 0 8px rgba(255, 181, 71, 0.6);
}

.commercial__title {
    font-size: clamp(1.875rem, 3.5vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.015em;
    text-wrap: balance;
    color: var(--text);
    opacity: 0.92;
}

.commercial__body {
    font-size: var(--text-lg);
    color: var(--text-muted);
    line-height: 1.55;
    max-width: 56ch;
}

.commercial__cta {
    margin-top: var(--space-3);
}

.commercial__visual {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    position: relative;
    z-index: 1;
}

.commercial__visual svg {
    width: 100%;
    height: auto;
    max-width: 220px;
    opacity: 0.7;
}

/* Foto variante · el wrapper se convierte en card de superficie con borde
   sutil + sombra + radius. Constraint a 420px max (más presencia que el SVG
   original capped a 220-240px). Aspect 1:1 enforced. margin-inline auto
   centra dentro de la celda del grid de .commercial__banner. El position
   relative + z-index 1 se heredan de la regla base .commercial__visual,
   así la card sigue flotando sobre el warm-wash del ::before del banner. */
.commercial__visual--photo {
    width: 100%;
    max-width: 420px;
    aspect-ratio: 1 / 1;
    margin-inline: auto;
    border-radius: var(--radius-xl);
    overflow: hidden;
    border: 1px solid rgba(79, 181, 255, 0.18);   /* azul brand al 18% · igual que las otras 4 cards-foto */
    background: var(--bg-base);                    /* fallback durante lazy load */
    box-shadow: var(--shadow-edge);                /* sombra base · matchea .comparison__frame */
    isolation: isolate;                            /* contiene el glow del hover */
    transition: box-shadow 350ms var(--ease-smooth);
}

.commercial__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;                             /* llena el card 420x420, recorta sin deformar */
}

/* Hover-glow neón azul · 4 capas idénticas a .comparison__frame:hover,
   .globe--photo:hover, .gps-map--photo:hover y .residential-featured__visual--photo:hover ·
   SOLO sobre la variante foto · SOLO en PC con hover capability Y sin
   reducción de movimiento. En touch y con reduced-motion la media query no
   matchea y la card queda con su sombra base sin glow. */
@media (hover: hover) {
    .commercial__visual--photo:hover {
        box-shadow:
            0 0 0 1px var(--brand-glow),
            0 0 24px rgba(79, 181, 255, 0.45),
            0 0 60px rgba(79, 181, 255, 0.30),
            0 0 120px rgba(79, 181, 255, 0.15);
    }
}

/* Override defensivo · con reducción de movimiento desactivamos también la
   transición de box-shadow de la variante foto (la media de hover ya bloquea
   el glow, esto solo evita cualquier animación residual). */
@media (prefers-reduced-motion: reduce) {
    .commercial__visual--photo {
        transition: none;
    }
}

@media (min-width: 768px) {
    .commercial__banner {
        grid-template-columns: 1.4fr 1fr;
    }
    .commercial__visual svg {
        max-width: 240px;
    }
}


/* --- 15.12 Contact · form 2-col layout + componentes de input ------- */

.contact {
    padding-block: var(--section-py);
}

.contact-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-10);
    align-items: start;
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: clamp(1.5rem, 4vw, 2.5rem);
    box-shadow: var(--shadow-inset);
}

.contact-form__title {
    font-size: clamp(1.375rem, 2.2vw, 1.625rem);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
    margin-bottom: var(--space-2);
}

.contact-form__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
}

.contact-form__submit {
    align-self: flex-start;
    margin-top: var(--space-2);
}

.form-required-note {
    font-size: var(--text-xs);
    color: var(--text-dim);
    margin: 0;
    font-style: italic;
}


/* Fieldset · contenedor de radios sin border-default del navegador */

.form-fieldset {
    border: 0;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.form-fieldset legend {
    /* legend reusa estilo de form-field__label */
    padding: 0;
}


/* Radios estilizados como pills con :has() · CSS moderno */

.form-radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.form-radio {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background-color: var(--bg-elev-2);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: border-color var(--t-fast), background-color var(--t-fast);
    position: relative;
}

.form-radio:hover {
    border-color: rgba(79, 181, 255, 0.32);
}

.form-radio input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.form-radio:has(input:checked) {
    border-color: var(--brand-glow);
    background-color: rgba(79, 181, 255, 0.10);
}

.form-radio:has(input:focus-visible) {
    outline: 2px solid var(--brand-glow);
    outline-offset: 2px;
}

.form-radio__label {
    font-size: var(--text-sm);
    color: var(--text);
    line-height: 1;
}


/* Checkbox de consentimiento · estilo custom */

.form-field--checkbox {
    gap: var(--space-2);
}

.form-checkbox {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    cursor: pointer;
    line-height: 1.5;
    position: relative;
}

.form-checkbox input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.form-checkbox__box {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    margin-top: 2px;
    background-color: var(--bg-elev-2);
    border: 1px solid var(--text-line);
    border-radius: 4px;
    position: relative;
    transition: border-color var(--t-fast), background-color var(--t-fast);
}

.form-checkbox:has(input:checked) .form-checkbox__box {
    background-color: var(--brand);
    border-color: var(--brand);
}

.form-checkbox:has(input:checked) .form-checkbox__box::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 6px;
    width: 5px;
    height: 10px;
    border: solid var(--text);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.form-checkbox:has(input:focus-visible) .form-checkbox__box {
    outline: 2px solid var(--brand-glow);
    outline-offset: 2px;
}

.form-checkbox__label {
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: 1.5;
}


/* Form message · success / info / error (lo emite lead-form.js) */

.form-message {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    line-height: 1.5;
    display: none;
}

.form-message.is-success {
    display: block;
    background-color: rgba(0, 255, 163, 0.10);
    border: 1px solid rgba(0, 255, 163, 0.32);
    color: var(--success);
}

.form-message.is-info {
    display: block;
    background-color: rgba(79, 181, 255, 0.10);
    border: 1px solid rgba(79, 181, 255, 0.32);
    color: var(--brand-glow);
}

.form-message.is-error {
    display: block;
    background-color: rgba(255, 84, 112, 0.10);
    border: 1px solid rgba(255, 84, 112, 0.32);
    color: var(--danger);
}


/* Submit en estado loading · sutil con opacity, sin spinner extra */

.btn.is-loading {
    opacity: 0.78;
    pointer-events: none;
    cursor: wait;
}


/* --- 15.13 Contact · trust sidebar (sticky desktop) + escape hatch -- */

.contact-sidebar {
    width: 100%;
}

.contact-sidebar__inner {
    background-color: var(--bg-elev);
    border: 1px solid var(--text-line);
    border-radius: var(--radius-xl);
    padding: clamp(1.5rem, 3vw, 2rem);
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.contact-sidebar__title {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.01em;
}

.contact-sidebar__subtitle {
    font-size: var(--text-sm);
    color: var(--text-muted);
    line-height: 1.55;
    margin: calc(var(--space-2) * -1) 0 var(--space-1);
}

.contact-sidebar__escape {
    margin-top: var(--space-3);
    padding-top: var(--space-4);
    border-top: 1px dashed var(--text-edge);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.contact-sidebar__escape-text {
    font-size: var(--text-xs);
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-family: var(--font-mono);
    margin: 0;
}

.contact-sidebar__escape-link {
    color: var(--brand-glow);
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    transition: color var(--t-fast);
}

.contact-sidebar__escape-link:hover {
    color: var(--text);
}

.contact-sidebar__escape-link svg {
    width: 14px;
    height: 14px;
}


/* Aria-invalid styling · refuerzo a11y · selector más fuerte que .is-invalid */

[aria-invalid="true"].form-field__input,
[aria-invalid="true"].form-field__select,
[aria-invalid="true"].form-field__textarea {
    border-color: var(--danger);
    box-shadow: 0 0 0 4px rgba(255, 84, 112, 0.12);
}


/* Responsive del contact layout */

@media (min-width: 640px) {
    .contact-form__row {
        grid-template-columns: 1fr 1fr;
    }
    .contact-form__row--phone {
        grid-template-columns: 110px 1fr;
    }
}

@media (min-width: 1024px) {
    .contact-layout {
        grid-template-columns: 2fr 1fr;
        gap: var(--space-10);
    }
    .contact-sidebar {
        position: sticky;
        top: clamp(7rem, 12vw, 9rem);
    }
}


/* ===== 16. VISTA PARTNER ================================================== */
/* Identidad emerald (#00FFA3) scoped a body.section-partner. La marca global
   INGClean® (topbar, HUD corners, bg-grid, footer) mantiene brand-glow azul. */


/* --- 16.1 Nav contextual partner · espejo de nav-cliente con tinte emerald -- */

.nav-partner {
    position: sticky;
    /* Sin backdrop-filter · bug de Chromium rompe sticky cuando el elemento
       sticky mismo tiene backdrop-filter aplicado. Alpha del bg sube de
       0.72 a 0.92 para compensar el frosted glass perdido. */
    top: clamp(4.5rem, 9vw, 6rem);
    z-index: var(--z-sticky);
    padding: var(--space-3) 0;
    background-color: rgba(2, 4, 11, 0.92);
    border-bottom: 1px solid var(--text-edge);
}

.nav-partner__inner {
    display: flex;
    align-items: center;
    gap: var(--space-5);
}

.nav-partner__badge {
    flex-shrink: 0;
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--emerald);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    padding: var(--space-2) var(--space-3);
    border: 1px solid rgba(0, 255, 163, 0.32);
    border-radius: var(--radius-pill);
    background-color: rgba(0, 255, 163, 0.08);
    white-space: nowrap;
    line-height: 1;
}

.nav-partner__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: var(--space-2);
    flex: 1;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
            mask-image: linear-gradient(to right,
        transparent 0,
        #000 12px,
        #000 calc(100% - 12px),
        transparent 100%);
}

.nav-partner__list::-webkit-scrollbar {
    display: none;
}

.nav-partner__item {
    flex-shrink: 0;
}

.nav-partner__link {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    border-radius: var(--radius-pill);
    transition:
        color var(--t-fast),
        background-color var(--t-fast),
        text-shadow var(--t-fast),
        box-shadow var(--t-fast);
    white-space: nowrap;
    position: relative;
}

/* Hover neón emerald · SOLO con hover capability. Mantiene la identidad
   visual de la sección partner (emerald #00FFA3) en lugar del azul de home
   y cliente. Misma estructura · solo cambia el color: text-shadow halo
   emerald + borde fino emerald + halo exterior emerald. */
@media (hover: hover) {
    .nav-partner__link:hover {
        color: var(--emerald);
        background-color: rgba(0, 255, 163, 0.10);
        text-shadow: 0 0 12px rgba(0, 255, 163, 0.55);
        box-shadow:
            0 0 0 1px rgba(0, 255, 163, 0.30),
            0 0 14px rgba(0, 255, 163, 0.25);
    }
}

.nav-partner__link:focus-visible {
    outline: 2px solid var(--emerald);
    outline-offset: 2px;
}

.nav-partner__link[aria-current="page"] {
    color: var(--emerald);
    background-color: rgba(0, 255, 163, 0.10);
}

.nav-partner__link[aria-current="page"]::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -6px;
    transform: translateX(-50%);
    width: 16px;
    height: 2px;
    border-radius: var(--radius-pill);
    background-color: var(--emerald);
    box-shadow: 0 0 8px rgba(0, 255, 163, 0.6);
}

@media (min-width: 768px) {
    .nav-partner__list {
        -webkit-mask-image: none;
                mask-image: none;
        overflow-x: visible;
        gap: var(--space-3);
    }
}


/* --- 16.2 Overrides emerald scoped a body.section-partner ----------------- */
/* Identificadores visuales del POV partner. La marca global INGClean® (topbar,
   bg-grid, HUD corners, footer) mantiene brand-glow azul intacto. */

body.section-partner .eyebrow {
    color: var(--emerald);
}

body.section-partner .feature-block__step {
    color: var(--emerald);
}

body.section-partner .hero-anchor__label {
    color: var(--emerald);
}

body.section-partner .feature-visual__svg {
    color: var(--emerald);
}

/* CTA primary en vista partner · fill emerald, texto oscuro alto contraste,
   círculo de la flecha en fondo oscuro semitransparente con flecha emerald. */
body.section-partner .btn-primary {
    --btn-bg:           var(--emerald);
    --btn-color:        var(--bg-base);
    --btn-arrow-bg:     rgba(2, 4, 11, 0.75);
    --btn-arrow-color:  var(--emerald);
    --btn-shadow:       0 12px 32px rgba(0, 80, 50, 0.32);
}

body.section-partner .btn-primary:hover {
    background-color: #00ffd4;
    box-shadow: 0 32px 80px rgba(0, 80, 50, 0.45), var(--shadow-inset);
}

body.section-partner .btn-primary:hover .btn__arrow {
    background-color: rgba(0, 0, 0, 0.88);
    transform: translateX(2px);
}

body.section-partner .btn-primary:active {
    background-color: var(--emerald);
}


/* --- 16.3 Steps timeline · overrides emerald para vista partner ---------- */
/* Solo cambia color/border/línea conectora · misma estructura del cliente. */

body.section-partner .step-indicator {
    border-color: rgba(0, 255, 163, 0.4);
}

body.section-partner .step-indicator__number {
    color: var(--emerald);
}

body.section-partner .step-block__label {
    color: var(--emerald);
}

/* Línea dashed vertical entre indicators · emerald scoped */
body.section-partner .step-block:not(:last-child)::before {
    background-image: linear-gradient(to bottom,
        var(--emerald) 0%,
        var(--emerald) 50%,
        transparent 50%);
}


/* --- 16.4 Página porque · overrides emerald scoped partner ---------------- */
/* Globe, mapa GPS, bento card icons, métricas, plataforma features y moments
   visuals cambian a tinte emerald cuando body tiene section-partner. */

body.section-partner .globe {
    color: var(--emerald);
}

body.section-partner .gps-map__svg {
    color: var(--emerald);
}

body.section-partner .bento__card-icon {
    color: var(--emerald);
    background: linear-gradient(135deg, rgba(0, 255, 163, 0.18), rgba(0, 229, 255, 0.08));
}

body.section-partner .pillar-card__icon {
    color: var(--emerald);
    background: linear-gradient(135deg, rgba(0, 255, 163, 0.18), rgba(0, 229, 255, 0.08));
}

body.section-partner .bento__card-metric-cifra,
body.section-partner .bento__metric-cifra {
    color: var(--emerald);
}

body.section-partner .platform-feature__icon {
    color: var(--emerald);
    background: linear-gradient(135deg, rgba(0, 255, 163, 0.16), rgba(0, 229, 255, 0.06));
}

body.section-partner .platform-feature:hover {
    border-color: rgba(0, 255, 163, 0.32);
}

body.section-partner .moment-card__visual {
    color: var(--emerald);
}


/* --- 16.5 Página requisitos · 3 grupos doppelrand + transparency note ---- */
/* Página única del Bloque 4 sin equivalente en cliente · solo aparece bajo
   body.section-partner, así que los colores emerald van hardcoded acá.    */

.requisitos {
    padding-block: var(--section-py);
}

.requisitos__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
}

/* Card · doppelrand consistente con bento/audience/moment del bloque */
.requisitos__card {
    background-color: var(--bg-elev);
    border-radius: var(--radius-xl);
    padding: 6px;
    box-shadow: var(--shadow-edge);
    position: relative;
}

.requisitos__card-inner {
    background-color: var(--bg-layer);
    border-radius: calc(var(--radius-xl) - 6px);
    padding: clamp(1.5rem, 3vw, 2.25rem);
    height: 100%;
    box-shadow: var(--shadow-inset);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.requisitos__card-icon {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(0, 255, 163, 0.18), rgba(0, 229, 255, 0.08));
    color: var(--emerald);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-inset);
}

.requisitos__card-icon svg {
    width: 28px;
    height: 28px;
}

.requisitos__card-title {
    font-size: clamp(1.25rem, 2vw, 1.5rem);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.requisitos__card-desc {
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.55;
    text-wrap: pretty;
}

/* La lista de items usa .badge-list existente · solo ajustamos margen */
.requisitos__card .badge-list {
    margin-top: var(--space-2);
    gap: var(--space-3);
}

@media (min-width: 1024px) {
    .requisitos__grid {
        grid-template-columns: repeat(3, 1fr);
        gap: var(--space-5);
        align-items: stretch;
    }
}


/* --- 16.5b · Transparency note · banner sutil con icon info emerald ----- */

.transparency {
    padding-block: clamp(2rem, 5vw, 4rem);
}

.transparency-note {
    display: flex;
    gap: var(--space-5);
    align-items: flex-start;
    padding: clamp(1.5rem, 3vw, 2.25rem);
    background-color: var(--bg-elev);
    border: 1px dashed rgba(0, 255, 163, 0.32);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-inset);
}

.transparency-note__icon {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: linear-gradient(135deg, rgba(0, 255, 163, 0.18), rgba(0, 229, 255, 0.08));
    color: var(--emerald);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.transparency-note__icon svg {
    width: 22px;
    height: 22px;
}

.transparency-note__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.transparency-note__eyebrow {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--emerald);
    text-transform: uppercase;
    letter-spacing: 0.18em;
}

.transparency-note__body {
    font-size: var(--text-base);
    color: var(--text-muted);
    line-height: 1.6;
    text-wrap: pretty;
    margin: 0;
}


/* --- 16.6 Contacto partner · overrides emerald scoped del form + sidebar -- */

/* Asterisco * de campo requerido · brand → emerald en partner */
body.section-partner .form-field__label--required::after {
    color: var(--emerald);
}

/* Focus de inputs · borde emerald + box-shadow emerald */
body.section-partner .form-field__input:focus,
body.section-partner .form-field__select:focus,
body.section-partner .form-field__textarea:focus {
    border-color: var(--emerald);
    box-shadow: 0 0 0 4px rgba(0, 255, 163, 0.12);
}

/* Hover de inputs · border emerald sutil */
body.section-partner .form-field__input:hover,
body.section-partner .form-field__select:hover,
body.section-partner .form-field__textarea:hover {
    border-color: rgba(0, 255, 163, 0.32);
}

/* Chevron SVG del select · emerald (era brand-glow azul) */
body.section-partner .form-field__select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none'><path d='M1 1l5 5 5-5' stroke='%2300FFA3' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Radio pills · hover, checked y focus → emerald */
body.section-partner .form-radio:hover {
    border-color: rgba(0, 255, 163, 0.32);
}

body.section-partner .form-radio:has(input:checked) {
    border-color: var(--emerald);
    background-color: rgba(0, 255, 163, 0.10);
}

body.section-partner .form-radio:has(input:focus-visible) {
    outline: 2px solid var(--emerald);
}

/* Checkbox consent · cuando checked, bg emerald (en lugar de brand) */
body.section-partner .form-checkbox:has(input:checked) .form-checkbox__box {
    background-color: var(--emerald);
    border-color: var(--emerald);
}

/* Color del check tick adentro del checkbox · contraste con emerald */
body.section-partner .form-checkbox:has(input:checked) .form-checkbox__box::after {
    border-color: var(--bg-base);
}

body.section-partner .form-checkbox:has(input:focus-visible) .form-checkbox__box {
    outline: 2px solid var(--emerald);
}

/* Link del escape hatch · emerald */
body.section-partner .contact-sidebar__escape-link {
    color: var(--emerald);
}


/* ===== 17. LEGAL · Privacy Policy ========================================= */
/* Página /legal/privacy.php · wrapper visual del documento exigido por App
   Store y Play. Layout 2-col en desktop (TOC sticky + prose 65ch), 1-col en
   mobile sin TOC. Sin tinte emerald: el legal es neutral (brand-glow azul). */


/* --- 17.1 · Hero compacto del legal --------------------------------------- */
/* Solo eyebrow + título + fecha. Sin doppelrand, sin CTA. El padding-top
   compensa la topbar fija para que el h1 no quede tapado al entrar. */
.legal-hero {
    padding: clamp(7rem, 12vw, 9rem) 0 clamp(2rem, 4vw, 3rem);
    border-bottom: 1px solid var(--border-soft);
}

.legal-hero__title {
    font-family: var(--font-brand);
    font-weight: 800;
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.1;
    letter-spacing: -0.02em;
    margin: 0.5rem 0 1rem;
    color: var(--text-primary);
}

.legal-hero__date {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.legal-hero__date-label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

.legal-hero__date-value {
    color: var(--text-secondary);
}


/* --- 17.2 · Layout 2-col · TOC sticky + prose ----------------------------- */
.legal {
    padding: clamp(2rem, 5vw, 4rem) 0 clamp(4rem, 8vw, 6rem);
}

.legal__layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2rem, 4vw, 3rem);
}

@media (min-width: 1024px) {
    .legal__layout {
        grid-template-columns: 240px 1fr;
        gap: 4rem;
        align-items: start;
    }
}


/* --- 17.3 · TOC sidebar · sticky en desktop, oculto mobile --------------- */
.legal__toc {
    display: none;
}

@media (min-width: 1024px) {
    .legal__toc {
        display: block;
        position: sticky;
        top: 6rem;
        max-height: calc(100vh - 8rem);
        overflow-y: auto;
    }
}

.legal__toc-label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
    margin: 0 0 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-soft);
}

.legal__toc-list {
    list-style: none;
    counter-reset: toc;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.legal__toc-list li {
    counter-increment: toc;
}

.legal__toc-link {
    display: block;
    font-size: 0.875rem;
    color: var(--text-secondary);
    text-decoration: none;
    padding: 0.375rem 0;
    line-height: 1.4;
    transition: color 0.15s ease;
}

.legal__toc-link::before {
    content: counter(toc, decimal-leading-zero) " · ";
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
}

.legal__toc-link:hover,
.legal__toc-link:focus-visible {
    color: var(--brand);
    outline: none;
}


/* --- 17.4 · Prose body · 65ch + line-height holgado --------------------- */
.legal__prose {
    max-width: 65ch;
    color: var(--text-secondary);
    line-height: 1.7;
    font-size: 1rem;
}

.legal__intro {
    color: var(--text-muted);
    font-size: 1.0625rem;
    margin: 0 0 clamp(2.5rem, 5vw, 3.5rem);
    padding-bottom: clamp(2rem, 4vw, 2.5rem);
    border-bottom: 1px solid var(--border-soft);
}


/* --- 17.5 · Secciones · scroll-margin para anchor jumps ----------------- */
.legal__section {
    margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
    scroll-margin-top: 6rem;
}

.legal__section:last-of-type {
    margin-bottom: 0;
}

.legal__section p {
    margin: 0 0 1rem;
}

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

.legal__heading {
    font-family: var(--font-brand);
    font-weight: 800;
    font-size: clamp(1.25rem, 2.5vw, 1.5rem);
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--text-primary);
    margin: 0 0 1.25rem;
}


/* --- 17.6 · Listas · bullets dots emerald minimalistas ----------------- */
.legal__list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.legal__list li {
    position: relative;
    padding-left: 1.5rem;
    line-height: 1.7;
}

.legal__list li::before {
    content: "";
    position: absolute;
    left: 0.25rem;
    top: 0.7rem;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: var(--emerald);
    box-shadow: 0 0 8px rgba(0, 255, 163, 0.5);
}


/* --- 17.7 · Bloque de contacto destacado · sección 10 ----------------- */
.legal__contact {
    margin-top: 1.5rem;
    padding: clamp(1.25rem, 3vw, 1.75rem);
    border: 1px solid rgba(0, 255, 163, 0.18);
    border-radius: 0.75rem;
    background-color: rgba(0, 255, 163, 0.04);
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

.legal__contact-row {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

@media (min-width: 600px) {
    .legal__contact-row {
        flex-direction: row;
        gap: 1rem;
        align-items: baseline;
    }
}

.legal__contact-label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--emerald);
    flex-shrink: 0;
    min-width: 5.5rem;
}

.legal__contact-value {
    color: var(--text-primary);
    text-decoration: none;
    word-break: break-all;
    transition: color 0.15s ease;
}

.legal__contact-value:hover,
.legal__contact-value:focus-visible {
    color: var(--emerald);
    outline: none;
}

/* Email con casilla aún no creada · mismo treatment que el footer */
.legal__contact-value[data-pending="true"] {
    text-decoration: underline dashed;
    text-underline-offset: 4px;
    cursor: help;
}


/* --- 17.8 · Responsive overrides para mobile --------------------------- */
@media (max-width: 1023px) {
    .legal__prose {
        max-width: 100%;
    }
}


/* ===== 18. MOTION SYSTEM · Bloque 6A · Paso 1 ============================= */
/* Sistema centralizado de movimiento. Tres pilares en este paso:
     a) Scroll-triggered reveals · cards y heros fade + slide-up al viewport
     b) Stagger entre hermanos · delay incremental por --i seteado por JS
     c) Hover lift refinado · easing pulido para todas las cards interactivas
   Todo gateado por prefers-reduced-motion: reduce (§18.10 apaga la capa entera).
   Los efectos JS-dependientes (counters, magnetic, slogan rotador, heading
   reveal) llegan en los pasos 6A.2 y 6A.3 — esta base solo cubre lo que
   marca el viewport. */


/* --- 18.1 · Motion tokens · curvas y duraciones centralizadas ----------- */
:root {
    /* Curva Apple smooth-out · entrada suave con overshoot mínimo */
    --ease-smooth:    cubic-bezier(0.2, 0.8, 0.2, 1);
    /* Curva spring leve para microinteractions (botones, arrows) */
    --ease-spring:    cubic-bezier(0.34, 1.56, 0.64, 1);
    /* Curva estándar simétrica · para transiciones bidireccionales */
    --ease-standard:  cubic-bezier(0.4, 0, 0.2, 1);

    /* Duraciones canónicas · reveal grande / microinteraction / hover */
    --dur-reveal:     600ms;
    --dur-micro:      300ms;
    --dur-hover:      200ms;

    /* Paso del stagger entre hermanos · JS asigna --i a cada hijo */
    --stagger-step:   70ms;
}


/* --- 18.2 · .reveal base · estado inicial + estado "in viewport" ------- */
/* JS aplica .reveal a los selectores aprobados al cargar la página.
   El IntersectionObserver agrega .is-revealed cuando cada elemento entra al
   viewport. La transición corre UNA SOLA VEZ (once: true en JS). */
.reveal {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity var(--dur-reveal) var(--ease-smooth),
        transform var(--dur-reveal) var(--ease-smooth);
    will-change: opacity, transform;
}

.reveal.is-revealed {
    opacity: 1;
    transform: translateY(0);
    will-change: auto;  /* libera memoria del compositor una vez animado */
}


/* --- 18.3 · Stagger system · delay incremental por hermano ------------- */
/* JS recorre el contenedor .reveal--stagger y setea --i en cada hijo .reveal
   (0, 1, 2, 3...). El transition-delay aplica calc(var(--i) * stagger-step)
   para que entren en cascada en lugar de simultáneos. */
.reveal--stagger > .reveal {
    transition-delay: calc(var(--i, 0) * var(--stagger-step));
}


/* --- 18.4 · Counter wrappers · numéricos puros y cifras mixtas ---------- */
/* Dos tratamientos para las cifras de porque pages:
     (a) [data-counter="N"] · cifra con dígito inicial (100%, 4 capas).
         JS anima 0→N con RAF y mantiene sufijo fijo (% o " capas"/" layers").
         tabular-nums evita jitter de ancho mientras los dígitos cambian.
     (b) .metric-glow · cifras sin dígito animable (24/7, < 30s).
         Al entrar viewport hace fade + scale + glow con .is-counter-done. */
[data-counter] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

.metric-glow {
    display: inline-block;
    transform: scale(0.92);
    transition:
        transform var(--dur-reveal) var(--ease-spring),
        text-shadow 800ms var(--ease-smooth);
    will-change: transform, text-shadow;
}

.metric-glow.is-counter-done {
    transform: scale(1);
    text-shadow:
        0 0 12px rgba(42, 141, 255, 0.55),
        0 0 28px rgba(42, 141, 255, 0.25);
    will-change: auto;
}

/* En vista partner el glow es emerald (coherente con el tinte de la sección) */
body.section-partner .metric-glow.is-counter-done {
    text-shadow:
        0 0 12px rgba(0, 255, 163, 0.55),
        0 0 28px rgba(0, 255, 163, 0.25);
}

/* Cuando un [data-counter] termina su animación también recibe la clase
   .is-counter-done · permite un fade-bump opcional similar al glow */
[data-counter].is-counter-done {
    text-shadow:
        0 0 8px rgba(42, 141, 255, 0.35);
    transition: text-shadow 400ms var(--ease-smooth);
}

body.section-partner [data-counter].is-counter-done {
    text-shadow:
        0 0 8px rgba(0, 255, 163, 0.35);
}


/* --- 18.5 · Magnetic buttons + arrow microinteraction ------------------ */
/* .btn-primary se "imanta" sutilmente al cursor mediante --mx/--my que
   JS setea en mousemove (clamp ±6px). El arrow icon además hace translateX
   al hover como microinteraction. Reset on mouseleave. */
.btn-primary {
    transform: translate(var(--mx, 0), var(--my, 0));
    transition:
        transform var(--dur-micro) var(--ease-spring),
        background-color var(--dur-micro) var(--ease-smooth),
        border-color var(--dur-micro) var(--ease-smooth),
        box-shadow var(--dur-micro) var(--ease-smooth);
}

.btn-primary .btn__arrow svg {
    transition: transform var(--dur-micro) var(--ease-spring);
}

.btn-primary:hover .btn__arrow svg,
.btn-primary:focus-visible .btn__arrow svg {
    transform: translateX(3px);
}


/* --- 18.6 · Hover lift refinado · cards interactivas ------------------ */
/* Override de hover de las cards para que el lift sea más smooth y
   coherente con el resto del motion. No cambia magnitudes — solo curva y
   duración. Aplica a las 8 familias de cards aprobadas. */
.pillar-card,
.bento__card,
.moment-card,
.service-card,
.requisitos__card,
.audience-card,
.platform-feature,
.step-card {
    transition:
        transform var(--dur-hover) var(--ease-smooth),
        border-color var(--dur-hover) var(--ease-smooth),
        background-color var(--dur-hover) var(--ease-smooth),
        box-shadow var(--dur-hover) var(--ease-smooth);
}


/* --- 18.7 · Slogan rotator del hero · 4 slogans alternando ------------- */
/* Contenedor en grid stack · todos los slogans superpuestos en grid-area 1/1
   para evitar layout shift. Solo .is-active tiene opacity 1, los demás 0.
   JS rota la clase .is-active cada 4s (pause on hover detectado en JS).
   Fallback: si JS no carga, el slogan 1 queda visible estático. */
.hero__slogan-rotator {
    display: grid;
    place-items: center;
    min-height: 2.4em;
    margin: 1rem auto 1.25rem;
    max-width: 56ch;
    padding: 0 1rem;
    /* will-change opacity en los hijos · no en el contenedor */
}

.hero__slogan {
    grid-area: 1 / 1;
    opacity: 0;
    color: var(--text-muted);
    font-family: var(--font-body);
    font-size: clamp(0.95rem, 1.4vw, 1.0625rem);
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1.5;
    text-align: center;
    text-shadow: 0 0 14px rgba(42, 141, 255, 0.15);
    transition: opacity 500ms var(--ease-smooth);
    will-change: opacity;
}

.hero__slogan.is-active {
    opacity: 1;
}


/* --- 18.9 · Heading split reveal · palabras en cascada al cargar ------- */
/* JS toma .hero__heading, separa el textContent por palabras, envuelve cada
   una en <span class="word" style="--i:N">. CSS aplica opacity 0 + slide-up
   inicial; al agregar .is-revealed cada palabra anima con su propio --i
   (stagger 80ms). Si JS no carga, el heading muestra el texto plano normal. */
.heading-split .word {
    display: inline-block;
    opacity: 0;
    transform: translateY(8px);
    transition:
        opacity var(--dur-reveal) var(--ease-smooth),
        transform var(--dur-reveal) var(--ease-smooth);
    transition-delay: calc(var(--i, 0) * 80ms);
    will-change: opacity, transform;
}

.heading-split.is-revealed .word {
    opacity: 1;
    transform: translateY(0);
    will-change: auto;
}


/* --- 18.10 · prefers-reduced-motion · apaga TODO el motion nuevo ------- */
/* El usuario que pidió reducir movimiento ve los reveals como contenido
   estático visible al cargar. JS también respeta este flag y no monta los
   observers ni los rotators ni los counters. */
@media (prefers-reduced-motion: reduce) {
    .reveal,
    .reveal.is-revealed {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    .reveal--stagger > .reveal {
        transition-delay: 0ms !important;
    }

    /* Hover lift se mantiene pero sin transiciones (cambio instantáneo) */
    .pillar-card,
    .bento__card,
    .moment-card,
    .service-card,
    .requisitos__card,
    .audience-card,
    .platform-feature,
    .step-card {
        transition: none !important;
    }

    /* Cifras mixtas · sin escalar ni glow, mostrar valor final tal cual */
    .metric-glow,
    .metric-glow.is-counter-done {
        transform: none !important;
        transition: none !important;
        text-shadow: none !important;
    }

    /* Counters numéricos · JS detecta el flag y muestra el valor final
       al instante sin animar (ver guard en motion.js initCounters) */
    [data-counter].is-counter-done {
        text-shadow: none !important;
        transition: none !important;
    }

    /* Magnetic buttons · cancelar el translate del cursor y el arrow */
    .btn-primary,
    .btn-primary .btn__arrow svg {
        transform: none !important;
        transition: none !important;
    }

    /* Slogan rotator · JS guard ya impide que arranque el timer; acá nos
       aseguramos de que solo el primer slogan quede visible (estático). */
    .hero__slogan {
        opacity: 0 !important;
        transition: none !important;
    }
    .hero__slogan:first-child {
        opacity: 1 !important;
    }

    /* Heading split · JS guard ya impide el split, pero por las dudas también
       neutralizamos cualquier .word que hubiera sobrevivido (todo opacity 1). */
    .heading-split .word,
    .heading-split.is-revealed .word {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}


/* ===== 19. MATRIX INTRO · 10s rain en home neutral · Tarea final ========= */
/* Canvas overlay full-screen creado dinámicamente por JS al cargar /.
   Códigos binarios "0" y "1" cayendo en azul brand · réplica del efecto del
   coming soon viejo pero con duración LIMITADA: 10s de rain + 2s de fade-out
   + remove del DOM. Solo se ejecuta una vez por carga de página.
   NO se renderiza si prefers-reduced-motion (guard global del motion.js).
   ============================================================================ */

.matrix-intro {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 1;            /* arriba del .bg-grid (-1), debajo del hero__inner (3) */
    pointer-events: none;
    opacity: 0.32;          /* más visible que el .with-matrix::before (0.22) */
    mix-blend-mode: screen;
    transition: opacity 2000ms var(--ease-smooth);
}

.matrix-intro.is-fading-out {
    opacity: 0;
}


/* ===== 20. CTA DESCARGA APPS · global, antes del footer en todas las páginas */
/* Bloque marketing con badges App Store + Google Play. Los <a> tienen
   data-pending="true" hasta que las apps estén live en las stores. Hover
   neón azul multi-layer glow · feature exclusiva de esta sección (no usa
   .btn-primary porque los badges tienen su propio lenguaje visual oficial
   de Apple / Google que no se debe alterar — solo se decora con sombra). */

.cta-apps {
    padding: clamp(3rem, 6vw, 5rem) clamp(1.25rem, 4vw, 3rem);
    text-align: center;
    border-top: 1px solid var(--text-edge);
    background: linear-gradient(180deg, transparent, rgba(42, 141, 255, 0.02));
}

.cta-apps__title {
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: 700;
    margin-bottom: 0.5rem;
    color: var(--text);
}

.cta-apps__subtitle {
    font-size: clamp(0.875rem, 1.4vw, 1rem);
    color: var(--text-muted);
    margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
    font-family: var(--font-mono);
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.cta-apps__badges {
    display: flex;
    gap: clamp(1rem, 2vw, 1.5rem);
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}

.cta-apps__badge {
    display: inline-block;
    line-height: 0;
    border-radius: 12px;
    /* Fondo blanco casi opaco · necesario para que los badges oficiales de
       Apple/Google (negros con texto blanco) tengan contraste sobre el dark
       mode del sitio. Padding genera respiro entre el borde del wrapper y
       el badge mismo. */
    background: rgba(255, 255, 255, 0.92);
    padding: 8px 14px;
    transition:
        transform var(--dur-hover) var(--ease-smooth),
        box-shadow var(--dur-hover) var(--ease-smooth),
        background var(--dur-hover) var(--ease-smooth);
    position: relative;
    isolation: isolate;
}

.cta-apps__badge img {
    /* Más chico que antes porque el wrapper ahora tiene 8+8 = 16px de padding
       vertical · el conjunto wrapper+badge mantiene tamaño visual similar. */
    height: clamp(40px, 6vw, 52px);
    width: auto;
    display: block;
}

/* Efecto neón azul al hover · multi-layer glow más intenso + fondo blanco
   puro (sin transparencia) para que el badge cobre máxima legibilidad. */
.cta-apps__badge:hover,
.cta-apps__badge:focus-visible {
    transform: translateY(-3px);
    background: rgba(255, 255, 255, 1);
    box-shadow:
        0 0 0 1px rgba(79, 181, 255, 0.5),
        0 0 24px rgba(79, 181, 255, 0.55),
        0 0 48px rgba(79, 181, 255, 0.35),
        0 0 72px rgba(79, 181, 255, 0.2),
        0 8px 24px rgba(0, 0, 0, 0.4);
}

.cta-apps__badge:active {
    transform: translateY(-1px);
}

/* Pending state · cursor not-allowed indica visualmente "no clickeable aún".
   Cuando las apps estén live, se quita data-pending y el href apunta al store. */
.cta-apps__badge[data-pending="true"],
.cta-apps__badge[data-pending="true"]:hover {
    cursor: not-allowed;
}

/* Mobile · badges apilados verticalmente con padding ajustado */
@media (max-width: 480px) {
    .cta-apps__badges {
        flex-direction: column;
        gap: 1rem;
    }
}

/* Reduced-motion · sin transform/glow animado, solo mantiene borde sutil */
@media (prefers-reduced-motion: reduce) {
    .cta-apps__badge,
    .cta-apps__badge:hover {
        transform: none !important;
        transition: none !important;
    }
    .cta-apps__badge:hover {
        box-shadow: 0 0 0 1px rgba(79, 181, 255, 0.4) !important;
    }
}
