/* ══════════════════════════════════════════════════════════════════
   GREY97 · TOKENS v1.2 — FUENTE DE VERDAD CANÓNICA del sistema
   Ningún valor de diseño (color, tipo, espaciado, geometría, preset)
   vive fuera de aquí. CLAUDE.md: assets/tokens.css manda.
   ──────────────────────────────────────────────────────────────────
   UBICACIÓN · assets/tokens.css es el canon. La copia de
              design_system/tokens.css es el SNAPSHOT CONGELADO de la
              entrega r3 (self-contained para que sus boards rendericen);
              no se edita. Si un valor cambia, cambia AQUÍ (01#36).
   ESTADO   · v1.0→v1.2: foco 1c (s8) + estados (s6) + campo-fondo 0.72
            · logo: usar SIEMPRE los SVG de assets/brand/ (no redibujar)
            · preset fotográfico v1.0 · CONGELADO 2026-07-12 (01#37):
              calibrado vs ref_estilo_01 sobre fotos crudas reales.
              Delta vs v0.9: contrast 0.90→1.05, tinte-op 0.22→0.34.
              Historia, cast y perillas → 04§5.
   USO      · <link rel="stylesheet" href="/assets/tokens.css">
              @font-face resuelve ./fonts/ → assets/fonts/ (sibling)
   FUENTES  · IBM Plex self-hosted (repo IBM/plex, licencia OFL-1.1)
   ══════════════════════════════════════════════════════════════════ */

/* 00 · IBM PLEX — self-hosted, nada más que estos 4 cortes.
   Rutas relativas a este archivo: assets/fonts/ (sibling de tokens.css) */
@font-face{font-family:'IBM Plex Sans';src:url('./fonts/IBMPlexSans-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:'IBM Plex Sans';src:url('./fonts/IBMPlexSans-Bold.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap;}
/* 5º corte (01#55, 2026-07-28): SOLO para la voz-comentario de Alex (clase .com). Ningún otro uso.
   Origen: IBM Plex Sans Italic variable (wdth,wght) de IBM/plex, OFL-1.1. Instanciada estática en
   wght 400 / wdth 100 (el sistema no usa ejes variables), subset latín: ASCII + Latin-1 + puntuación
   tipográfica y euro, 205 codepoints, 22,8 KB. Cubre castellano y nombres europeos con diacríticos.
   Si algún día hace falta más cobertura, la paridad total con la Regular son 891 codepoints y 71,9 KB. */
@font-face{font-family:'IBM Plex Sans';src:url('./fonts/IBMPlexSans-Italic.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap;}
@font-face{font-family:'IBM Plex Mono';src:url('./fonts/IBMPlexMono-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:'IBM Plex Mono';src:url('./fonts/IBMPlexMono-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap;}

:root{

/* 01 · COLOR — primitivos (sin #FFF ni #000 puros, nunca) */
--grey-98:#0E1114;      /* abismo    · fondo hondo, favicon, OG */
--grey-90:#171B1F;      /* antracita · fondo dark por defecto · texto sobre claro */
--grey-80:#232930;      /* marengo   · filetes y paneles sobre dark */
--grey-60:#4A525B;      /* plomo     · texto secundario sobre claro · líneas gráficas dark */
--grey-50:#6B747D;      /* medio     · meta grande dark · bordes de campo (3:1) */
--grey-30:#A9B1B8;      /* niebla    · texto secundario sobre dark */
--grey-15:#D3D8DC;      /* bruma     · filetes sobre claro · texto terciario dark */
--grey-05:#EEF1F2;      /* espuma    · texto principal dark · fondo de email */
--payne:#8FA3B8;        /* payne     · links/UI sobre dark · SIEMPRE subrayado */
--payne-tinta:#4E657B;  /* payne tinta · links/UI sobre claro (email) · nuevo en v1.0 */
--neon-cian:#2EE6D6;    /* neon      · HEX FINAL CALIBRADO · 11.0:1 sobre antracita
                           ≤1 uso por composición · nunca fondo · nunca gradiente
                           · nunca texto de lectura ni link */

/* 02 · COLOR — alias de función */
--fondo:var(--grey-90);
--fondo-hondo:var(--grey-98);
--panel:var(--grey-80);
--filete-dark:var(--grey-80);         /* hairline sobre antracita/abismo */
--filete-claro:var(--grey-15);        /* hairline sobre espuma */
--campo-fondo:rgba(14,17,20,0.72);    /* v1.1: 0.60→0.72 — anillo de foco legible sobre luces de foto */
--campo-borde:var(--grey-50);         /* v1.0: sube de plomo a medio → 3:1 (WCAG 1.4.11) */
--campo-borde-foco:var(--payne);

/* 03 · TIPOGRAFÍA — 2 familias, 5 cortes (era 4 hasta 01#55).
   Voz humana=Sans · dato de máquina=Mono · voz-comentario de Alex=Sans itálica.
   La itálica NO es recurso libre: solo marca comentario de autor (clase .com). */
--sans:'IBM Plex Sans','Helvetica Neue',Helvetica,Arial,sans-serif;
--mono:'IBM Plex Mono','Courier New',Courier,monospace;
--w-statement:700;   /* Sans — statements y títulos */
--w-cuerpo:400;      /* Sans — lectura */
--w-mono-marca:500;  /* Mono — wordmark y kickers */
--w-mono-dato:400;   /* Mono — metadatos y datos */

/* escala por rol (px · line-height · tracking) */
--fs-s1:64px;      --lh-s1:1.06;  --ls-s1:-0.015em;  /* statement 1 · hero, OG */
--fs-s2:44px;      --lh-s2:1.14;  --ls-s2:-0.01em;   /* statement 2 · cierres */
--fs-s3:28px;      --lh-s3:1.25;  --ls-s3:-0.005em;  /* statement 3 · hitos, email h1 */
--fs-s4:18px;      --lh-s4:1.4;                      /* título de item */
--fs-cuerpo:15px;  --lh-cuerpo:1.75;                 /* cuerpo Sans 400 */
--fs-cuerpo-s:14px;--lh-cuerpo-s:1.7;                /* cuerpo compacto */
--fs-dato:13px;    --lh-dato:1.7;                    /* dato Mono 400 */
--fs-kicker:11px;  --lh-kicker:1.2;  --ls-caps:0.14em; /* kicker Mono 500 VERSALITAS */
--fs-meta:10px;    --lh-meta:1.7;    --ls-meta:0.10em; /* meta Mono 400 */
--fs-micro:8.5px;  --ls-micro:0.08em;                /* marcadores [ PLACEHOLDER ] */
--fs-marca:15px;   --ls-marca:0.30em;                /* wordmark GREY97 · Mono 500 */

/* 04 · ESPACIADO — rejilla base 8px */
--u:8px;
--sp-2:16px; --sp-3:24px; --sp-4:32px; --sp-6:48px;
--sp-8:64px; --sp-12:96px; --sp-16:128px;
--gutter:48px;          /* margen de página */
--seccion:96px;         /* respiración vertical de sección */
--ancho-max:1280px;     /* medida de contenido */

/* 05 · GEOMETRÍA */
--radio-0:0px;          /* marca, swatches, imágenes */
--radio:2px;            /* campos, botones, tarjetas — máximo del sistema */
--filete:1px;           /* todo filete es 1px · SIN SOMBRAS en todo el sistema */

/* 06 · MARCA — horizonte con corte (proporciones, no px fijos)
   largo : corto ≈ 3 : 1 · hueco ≈ 0.6 × corto · grosor 2px a cuerpo 15
   el neon vive SOLO en el segmento corto y SOLO en estado activo
   IMPLEMENTACIÓN: usar los SVG de assets/brand/ (no redibujar la marca) */
--marca-largo:18px; --marca-corto:7px; --marca-hueco:4px; --marca-grosor:2px;

/* 07 · FOTOGRAFÍA — preset frío v1.0 · CONGELADO 2026-07-12 (01#37)
   calibrado vs ref_estilo_01 sobre fotos crudas reales; cast medios ≈ -14. Ver 04§5.
   receta por capas, aplicable a cualquier foto (ver Sistema §08):
   img       → filter: var(--foto-filtro)
   capa 1    → background:var(--foto-tinte);  mix-blend-mode:color;   opacity:var(--foto-tinte-op)
   capa 2    → background:var(--foto-negros); mix-blend-mode:lighten  (negros levantados a abismo)
   capa 3    → background:var(--foto-luces);  mix-blend-mode:darken   (luces contenidas en espuma)
   capa 4    → background-image:var(--grain); opacity:var(--foto-grano-op) */
--foto-filtro:grayscale(1) contrast(1.05) brightness(0.97);
--foto-tinte:#8FA3B8; --foto-tinte-op:0.34;
--foto-negros:#0E1114;
--foto-luces:#EEF1F2;
--foto-grano-op:0.07;
--grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");

/* 08 · MOVIMIENTO — mínimo, funcional. Regla dura (s6): hover/active/focus
   = payne sobre dark, payne-tinta sobre espuma; el neon jamás es estado.
   Press: entra 0ms / sale 120ms · anillo de foco: 0ms sin fade
   Error: entra 200ms / se retira 0ms al corregir */
--hover-ms:120ms;
--estado-ms:200ms;

/* 08b · FOCO (v1.2 · elección 1c · sesión 8) — filete perimetral 1px PEGADO
   botones/links/pestañas: outline:var(--anillo-grosor) solid var(--anillo-foco);
                          outline-offset:var(--anillo-offset) · solo :focus-visible
   campos: SIN filete — el foco es el cambio de borde a payne (--campo-borde-foco)
   pares verificados: antracita 6.7 · abismo 7.3 · espuma 5.3 · foto ≥3.3 condicionado
   prohibido outline:none sin sustituto equivalente */
--anillo-foco:var(--payne);             /* sobre dark / foto */
--anillo-foco-claro:var(--payne-tinta); /* sobre espuma / email */
--anillo-grosor:1px;                    /* v1.2: 2px→1px · todo filete es 1px */
--anillo-offset:0;                      /* v1.2: pegado al borde, sin offset */
}

/* 09 · CONTRASTE VERIFICADO (WCAG 2.1 · relaciones calculadas)
   ── sobre ANTRACITA #171B1F ─────────────────────────────────
   espuma  15.2 AAA cuerpo      bruma   12.1 AAA
   niebla   8.0 AAA             payne    6.7 AA  (link dark)
   neon    11.0 AAA*            medio    3.6     (solo ≥24px·700 o UI 3:1)
   plomo    2.2 ✗               *neon nunca es texto de lectura
   ── sobre ABISMO #0E1114 ────────────────────────────────────
   espuma  16.7 AAA · niebla 8.7 AAA · payne 7.3 AA · neon 12.1
   ── sobre ESPUMA #EEF1F2 (email, claro) ─────────────────────
   abismo     16.7 AAA          antracita 15.2 AAA cuerpo
   plomo       7.0 AA           payne-tinta 5.3 AA (link claro)
   medio       4.2  (solo ≥24px)
   payne       2.3 ✗ nunca texto sobre claro
   neon        1.4 ✗ solo gráfico mínimo (segmento), jamás texto
   ──────────────────────────────────────────────────────────── */
