/* ============================================================
   Sistema de identidad — Cristian González
   Fuente de verdad: "Identidad Visual - Cristian González" v1
   Los hex son exactos, NO improvisar variantes fuera de esta escala.
   ============================================================ */

/* ------------------------------------------------------------
   Tipografía — SOLO estas tres familias.
   El documento de identidad venía con Archivo, Chivo, Literata y
   Source Serif 4 declaradas pero sin un solo uso en el markup:
   quedan descartadas a propósito, no las vuelvas a agregar.

   Las familias son: Space Grotesk (500/700), IBM Plex Sans (400/600),
   IBM Plex Mono (400/500) y Material Symbols Rounded (íconos — set de
   glifos, no cuenta como cuarta familia de texto: reemplaza a los <svg>
   dibujados a mano de los controles del slider. Variante Rounded, no
   Outlined: trazo más fino y esquinas suaves).

   OJO — NO volver a traerlas con @import acá.
   Estaban así y salía carísimo: un @import obliga al navegador a bajar
   Y parsear este archivo entero antes de siquiera enterarse de que las
   fuentes existen, y recién ahí empezar el pedido a fonts.googleapis.com,
   que a su vez devuelve otro CSS que recién ahí revela los .woff2 en
   fonts.gstatic.com. Tres viajes en fila, uno atrás del otro.

   Medido en producción (PageSpeed, mobile): esa cadena bloqueaba el
   renderizado 1.500 ms para traer 2,8 KiB de CSS. El costo no era el
   peso, era la fila india.

   AHORA: los archivos viven en assets/fonts/ y se declaran acá abajo.

   Ir a <link> hacia fonts.googleapis.com fue el primer paso y bajó el
   bloqueo de renderizado de 1.500 ms a 400 ms, pero quedaba lo caro:
   dos ORÍGENES externos (fonts.googleapis.com para el CSS y
   fonts.gstatic.com para los .woff2), cada uno con su DNS y su TLS, y
   el CSS de Google teniendo que llegar y parsearse para recién ahí
   revelar dónde están las fuentes.

   Y eso además causaba el problema grande: como las fuentes llegaban
   DESPUÉS del primer pintado, el texto se reflowea al aplicarse, y
   hero-scroll.js vuelve a medir el hero en document.fonts.ready. Esa
   segunda medición daba distinto, prendía o apagaba el efecto de hero
   fijo, y el contenido visible SALTABA 940px — una pantalla entera.
   Medido: CLS 0.643 en PageSpeed desktop, con el resto de las métricas
   en verde. Era lo único que hundía el puntaje.

   Sirviéndolas desde el propio dominio no hay handshakes de más ni
   CSS intermedio, y con el preload de includes/header.php llegan antes
   del primer pintado: el texto se pinta ya con su fuente definitiva,
   así que no hay reflow, la medición del hero da bien a la primera y
   no hay salto.

   Sólo el subset "latin" — alcanza para el español (incluye á é í ó ú
   ñ ü ¿ ¡). Si alguna vez hace falta otro alfabeto, hay que bajar el
   subset correspondiente y sumar su @font-face acá.

   Los íconos son un subset de 11 glifos (los que el sitio y el panel
   usan de verdad) pedidos con &icon_names=: la fuente completa pesa
   946 KB, estos 11 pesan 4,8 KB. Si se agrega un ícono nuevo al markup
   hay que volver a generar el archivo incluyéndolo, o no se va a ver.
   Lista actual: arrow_back, arrow_forward, chevron_left, chevron_right,
   content_copy, delete, draw, edit, insights, lock, mail.
   ------------------------------------------------------------ */

/* --- Texto --- */
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/space-grotesk-500.woff2') format('woff2');
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/space-grotesk-700.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/ibm-plex-sans-400.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/ibm-plex-sans-600.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/ibm-plex-mono-500.woff2') format('woff2');
}

/* --- Íconos ---
   display: block y no swap: un ícono con fuente de respaldo mostraría
   la palabra suelta ("mail", "close") hasta que cargue. Mejor un hueco
   un instante que texto en crudo donde va un dibujo.

   OJO CON EL ?v= — no es decorativo.

   El .htaccess sirve los .woff2 con "Cache-Control: immutable" por un
   año, así que el navegador NO vuelve a pedir el archivo ni siquiera
   para preguntar si cambió. Y este archivo SÍ cambia: es un subset con
   sólo los íconos que el sitio usa de verdad (la fuente completa pesa
   946 KB, este subset 4 KB), o sea que cada vez que se agrega un ícono
   nuevo al markup hay que regenerarlo incluyéndolo.

   Sin el ?v=, reemplazar el archivo en el servidor no le llega a nadie
   que ya haya visitado el sitio: siguen con el subset viejo cacheado y
   el ícono nuevo se les ve como la palabra en crudo ("draw",
   "insights"). Pasó de verdad, no es teórico.

   AL AGREGAR UN ÍCONO: regenerá el subset con la lista completa y
   subile 1 a este número. Es lo único que fuerza la recarga. */
@font-face {
    font-family: 'Material Symbols Rounded';
    font-style: normal;
    font-weight: 300;
    font-display: block;
    src: url('../fonts/material-symbols-rounded.woff2?v=3') format('woff2');
}

.icono-material {
    font-family: 'Material Symbols Rounded';
    font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' -25, 'opsz' 24;
    font-weight: normal;
    font-style: normal;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    -webkit-font-smoothing: antialiased;
}

:root {
    /* --------------------------------------------------------
       Azul petróleo — color rector.
       Fondos de sección, acento de interfaz, links.
       -------------------------------------------------------- */
    --petroleo-900: #0A2A33;  /* fondo profundo            */
    --petroleo-800: #123A45;  /* botón primario deshabilitado (ver Componentes UI) */
    --petroleo-700: #124454;  /* bordes, cards             */
    --petroleo-600: #145A6D;  /* hover del botón primario (ver Componentes UI) */
    --petroleo-500: #1C6B80;  /* gráficos, botón primario  */
    --petroleo-400: #3A9DB2;  /* acento          · 5.5:1   */
    --petroleo-300: #6FC5D6;  /* links           · 9.4:1   */

    /* --------------------------------------------------------
       Bordó — acento de énfasis.
       CTA, números destacados, subrayados.
       -------------------------------------------------------- */
    --bordo-900: #3B0E18;     /* fondo                     */
    --bordo-700: #6B1626;     /* bordes                    */
    --bordo-500: #96263C;     /* botón secundario (borde)  */
    --bordo-400: #C0435A;     /* gráfico                   */
    --bordo-300: #D9647A;     /* texto           · 5.0:1   */
    --bordo-200: #E8879A;     /* hover botón secundario · 6.4:1 (ver Componentes UI) */

    /* --------------------------------------------------------
       Tierra rojiza — escala puente entre petróleo y bordó.
       Ilustración, tags, gráficos de proceso.
       -------------------------------------------------------- */
    --tierra-800: #2E1C16;    /* superficie                */
    --tierra-600: #5A3225;    /* borde cálido              */
    --tierra-500: #8A4E36;    /* relleno                   */
    --tierra-400: #B0724F;    /* gráfico                   */
    --tierra-300: #C98A6B;    /* texto           · 6.1:1   */

    /* --------------------------------------------------------
       Neutros — el negro es el lienzo, el hueso baja la dureza
       del blanco puro.
       -------------------------------------------------------- */
    --negro:      #1A1A1A;    /* fondo base                */
    --superficie: #212020;    /* superficie elevada        */
    --borde:      #34312D;    /* borde / divisor           */
    --gris:       #A8A29A;    /* texto secundario · 6.9:1  */
    --hueso:      #F4F1EA;    /* blanco hueso    · 15.5:1  */

    /* Intermedio usado en el cuerpo de texto largo del sistema */
    --hueso-dim:  #D6D2CA;

    /* Ver Componentes UI: placeholders y texto/borde deshabilitado —
       más apagados que --gris, que es para texto secundario LEGIBLE. */
    --gris-apagado: #6E6A64;  /* placeholders, texto deshabilitado    */
    --gris-oscuro:  #5C5851;  /* texto deshabilitado sobre fondo oscuro */

    /* --------------------------------------------------------
       Semánticos — NO son parte de la identidad.
       Sólo comunican estado en la interfaz (formularios,
       notificaciones, badges). Nunca reemplazan a petróleo,
       bordó ni tierra rojiza.
       -------------------------------------------------------- */
    --exito:        #00A37E;
    --exito-claro:  #7CC490;
    --exito-texto:  #5FCBA8;
    --exito-fondo:  rgba(0, 163, 126, 0.18);

    --error:        #E2645A;
    --error-texto:  #E88E85;
    --error-fondo:  rgba(226, 100, 90, 0.16);

    --info:         #5FADD9;
    --info-texto:   #8FC4E8;
    --info-fondo:   rgba(95, 173, 217, 0.16);

    --alerta:       #EFB810;
    --alerta-claro: #F9DB5C;
    --alerta-texto: #F9DB5C;
    --alerta-fondo: rgba(239, 184, 16, 0.18);

    /* --------------------------------------------------------
       Tipografía
       -------------------------------------------------------- */
    --font-titulo: 'Space Grotesk', system-ui, sans-serif;
    --font-texto:  'IBM Plex Sans', system-ui, sans-serif;
    --font-mono:   'IBM Plex Mono', ui-monospace, monospace;

    /* Escala fluida. Los tamaños ancla salen del documento de
       identidad medido a 1440px de ancho. */
    --t-display: clamp(2.5rem, 1.6rem + 4vw,   4rem);     /* 40 → 64px  hero        */
    --t-h1:      clamp(2rem,  1.4rem + 2.8vw, 3.25rem);   /* 32 → 52px  título caso */
    --t-h2:      clamp(1.6rem, 1.3rem + 1.4vw, 2.125rem); /* 26 → 34px  sección     */
    --t-h3:      clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);  /* 20 → 24px              */
    --t-body-lg: 1.0625rem;                               /* 17px  texto largo      */
    --t-body:    0.9375rem;                               /* 15px                   */
    --t-sm:      0.875rem;                                /* 14px                   */
    --t-xs:      0.8125rem;                               /* 13px                   */
    --t-mono:    0.75rem;                                 /* 12px  etiquetas mono   */

    --lh-tight: 1.05;
    --lh-snug:  1.3;
    --lh-body:  1.7;

    /* Space Grotesk pide tracking negativo en tamaños grandes */
    --ls-display: -0.035em;
    --ls-h1:      -0.03em;
    --ls-h2:      -0.02em;
    --ls-mono:     0.14em;  /* etiquetas mono en mayúsculas */
    --ls-mono-lg:  0.16em;

    /* --------------------------------------------------------
       Espaciado — base 4px
       -------------------------------------------------------- */
    --sp-1:  4px;
    --sp-2:  8px;
    --sp-3:  12px;
    --sp-4:  16px;
    --sp-5:  20px;
    --sp-6:  24px;
    --sp-8:  32px;
    --sp-10: 40px;
    --sp-12: 48px;
    --sp-14: 56px;
    --sp-16: 64px;
    --sp-20: 80px;
    --sp-22: 88px;
    --sp-24: 96px;

    /* --------------------------------------------------------
       Radios — el sistema es de esquinas casi rectas.
       No subir de 6px salvo en elementos circulares.
       -------------------------------------------------------- */
    --r-xs: 3px;
    --r-sm: 4px;
    --r-md: 6px;
    --r-full: 999px;

    /* --------------------------------------------------------
       Profundidad — sobre negro, la sombra dura no se ve.
       La jerarquía la dan el borde y el cambio de superficie;
       la sombra sólo acompaña en overlays.
       -------------------------------------------------------- */
    --sombra-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --sombra-md: 0 2px 4px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.35);
    --sombra-lg: 0 4px 8px rgba(0, 0, 0, 0.35), 0 16px 48px rgba(0, 0, 0, 0.45);

    /* --------------------------------------------------------
       Movimiento
       -------------------------------------------------------- */
    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --dur-rapido: 0.15s;
    --dur-medio:  0.28s;

    /* Ancho máximo de la grilla del sitio */
    --ancho-max: 1600px;
    --padding-lado: clamp(var(--sp-5), 6vw, var(--sp-22));

    /* ---- Alto del hero a pantalla completa ----
       La cabecera es sticky y vive ARRIBA del hero, así que el hero
       ocupa la pantalla menos ese alto. --cabecera-alto es un fallback:
       hero-scroll.js lo pisa con la medición real apenas carga (el alto
       depende del SVG del logo y del padding, no es un número fijo
       calculable acá).
       Acá va vh como base y dvh se aplica más abajo vía @supports: en
       mobile la barra del navegador aparece/desaparece y vh queda
       sobredimensionado, así que dvh es lo que se quiere — pero el
       truco habitual de declarar la propiedad dos veces y confiar en
       que la inválida se descarte NO sirve con custom properties: su
       valor no se valida al declararlo (se guarda tal cual y falla
       recién al sustituirlo), así que la segunda declaración pisaría a
       la primera aunque el navegador no entienda dvh, y el hero se
       quedaría sin alto. @supports sí se evalúa antes. */
    --cabecera-alto: 76px;
    --hero-alto: calc(100vh - var(--cabecera-alto));

    /* Lo que ocupa, DEBAJO del mockup, el bloque de título + bajada +
       métrica, más los gaps de la columna y el padding vertical del
       hero. Es el presupuesto que se le resta al alto disponible para
       saber cuánto le queda al mockup: subirlo achica la laptop,
       bajarlo la agranda y arriesga que el texto no entre.

       Este valor es sólo el RESPALDO para cuando el JS no corre.
       hero-slider.js mide el bloque de verdad y lo pisa con el número
       real (ver publicarPresupuestoTexto). Está deliberadamente alto
       porque errar para arriba sólo achica el mockup, mientras que
       errar para abajo lo hace desbordar la pantalla. */
    --hero-texto-alto: 380px;

    /* Alto que le queda al mockup una vez descontado ese bloque. El
       piso de 200px evita que en una pantalla muy baja la laptop
       colapse a nada (ahí es preferible que el hero scrollee). */
    --hero-mockup-alto: max(200px, calc(var(--hero-alto) - var(--hero-texto-alto)));

    /* Ancho equivalente a ese alto, para poder acotar el mockup por
       ancho (que es lo que respeta el aspect-ratio) en vez de por alto
       (que lo deformaría).

       La cuenta, despejada y no aproximada. Llamando H al alto
       disponible de arriba, lo que ocupa la composición es:
         marco 16/10 al 89.29% del ancho ....  0.558 × ancho
         base de la laptop ..................  13px
         el margen que reserva el teléfono
         que sobresale por abajo ............  0.09 × H
       Todo eso tiene que entrar en H:
         0.558 × ancho + 13px + 0.09 × H  <=  H
       o sea  ancho <= (0.91 × H - 13px) / 0.558.

       Acá estaba antes "H × 1.64", que sale de la misma geometría pero
       redondeada, y da unos 20px de más. Con el presupuesto de texto
       viejo (380px fijos) sobraba tanto lugar que esos 20px no se
       notaban; ahora que el presupuesto lo mide hero-slider.js y es
       ajustado, ese error alcanzaba para que la composición pasara el
       alto de pantalla por 2px — y con eso hero-scroll.js daba "no
       entra" y apagaba el efecto de hero fijo.

       Debajo de 1300px el teléfono se oculta y el término del 9%
       desaparece: esa variante está en sitio.css, sobre el propio
       .hero__dispositivos. */
    --hero-mockup-ancho: calc((var(--hero-mockup-alto) * 0.91 - 13px) / 0.558);
}

/* dvh donde esté soportado (Chrome 108+, Safari 15.4+, Firefox 101+).
   Los navegadores que no lo entienden se quedan con el 100vh de
   arriba — el hero sigue midiendo una pantalla, sólo que sin
   compensar la barra que aparece y desaparece en mobile. */
@supports (height: 100dvh) {
    :root {
        --hero-alto: calc(100dvh - var(--cabecera-alto));
    }
}

/* ------------------------------------------------------------
   Reset mínimo
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

/* scroll-behavior:smooth para los links de ancla (#trabajo del hero,
   del paginador, etc.) — el override de reduced-motion más abajo ya
   lo desactivaba para esa preferencia, pero acá arriba nunca se había
   llegado a activar; quedaba de gratis sin usarse. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* ------------------------------------------------------------
   Scrollbar del sitio.
   Sin esto queda la barra gris de fábrica del sistema operativo,
   clarísima sobre el fondo casi negro de toda la identidad — el
   elemento más grande de la pantalla desentonando con todo lo demás.
   Vale para el sitio público y para el panel: los dos cargan este
   archivo y los dos son el mismo tema oscuro (acá no hay claro/oscuro
   que alternar, así que un solo juego de colores alcanza).
   Firefox primero (scrollbar-width/-color), WebKit después
   (::-webkit-scrollbar-*) — Chrome y Safari ignoran las propiedades
   de Firefox por completo, así que hacen falta las dos formas.
   ------------------------------------------------------------ */
html {
    scrollbar-width: thin;
    scrollbar-color: var(--petroleo-700) var(--negro);
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--negro); }
::-webkit-scrollbar-thumb {
    background-color: var(--petroleo-700);
    border-radius: var(--r-full);
    /* El "borde" con el color del fondo angosta visualmente el thumb
       sin achicar el área de agarre real — más agradable que un
       rectángulo pegado a los dos bordes de la pista. */
    border: 3px solid var(--negro);
}
::-webkit-scrollbar-thumb:hover { background-color: var(--petroleo-500); }
::-webkit-scrollbar-corner { background: var(--negro); }

body {
    margin: 0;
    background: var(--negro);
    color: var(--hueso);
    font-family: var(--font-texto);
    font-size: var(--t-body);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--font-titulo);
    font-weight: 500;
    line-height: var(--lh-snug);
    text-wrap: pretty;
}

h1 { font-size: var(--t-h1); letter-spacing: var(--ls-h1); }
h2 { font-size: var(--t-h2); letter-spacing: var(--ls-h2); }
h3 { font-size: var(--t-h3); letter-spacing: var(--ls-h2); }

p { margin: 0; text-wrap: pretty; }

a {
    color: var(--petroleo-300);
    text-decoration: none;
    transition: color var(--dur-rapido) var(--ease);
}
a:hover { color: var(--tierra-300); }

img, svg { max-width: 100%; }

/* ------------------------------------------------------------
   Foco visible — nunca quitar sin reemplazo
   ------------------------------------------------------------ */
:focus-visible {
    outline: 2px solid var(--petroleo-400);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

/* ------------------------------------------------------------
   Utilidades de identidad
   ------------------------------------------------------------ */

/* Etiqueta mono en mayúsculas — el recurso tipográfico que más
   se repite en el sistema (kicker de sección, meta, badges). */
.eyebrow {
    font-family: var(--font-mono);
    font-size: var(--t-mono);
    font-weight: 400;
    letter-spacing: var(--ls-mono);
    text-transform: uppercase;
    color: var(--gris);
}
.eyebrow--acento { color: var(--petroleo-300); letter-spacing: var(--ls-mono-lg); }

.texto-secundario { color: var(--gris); }
.mono { font-family: var(--font-mono); }

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

/* ------------------------------------------------------------
   Movimiento reducido — se respeta en todo el sitio.
   Las animaciones de Motion One leen esta misma preferencia
   desde JS (ver assets/js/motion.js).
   ------------------------------------------------------------ */
@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;
    }
    /* El contenido con reveal queda visible sin animar */
    [data-reveal] { opacity: 1 !important; transform: none !important; }
}
