/* ═══════════════════════════════════════════════════════════════════════════
   COSMERIUM ERA III · NCRT-3
   tokens.css — Sistema de tokens único. Fuente de verdad de toda la interfaz.

   Origen: DESIGN.md §3 (paleta), §4 (tipografía), §5 (bloque :root íntegro),
   §11.4 (presupuesto móvil).

   REGLA DURA: ninguna página, ningún componente y ninguna plantilla redefine
   estos valores localmente. Si un color no está aquí, no existe (Anexo B.12:
   "Cualquier valor de color escrito a mano fuera del bloque :root" está
   prohibido). El repo antiguo tenía tres paletas divergentes repartidas entre
   nueve ficheros; este fichero es la corrección estructural de eso.

   ORDEN DE CARGA OBLIGATORIO:  tokens.css → reset.css → chrome.css →
                                components.css → pages/*.css
   ═══════════════════════════════════════════════════════════════════════════ */

:root{

  /* La ficción por defecto es una terminal monocroma sobre carbón. Declararlo
     hace que los widgets nativos que no estilamos (scrollbar, calendario del
     date picker, selector de fichero) nazcan oscuros en vez de blancos.
     El modo COPIA IMPRESA lo invierte más abajo. */
  color-scheme: dark;

  /* ───────── PRIMITIVAS · NEGROS Y ESTRUCTURA ───────── */
  --k-void:      #05070A;
  --k-carbon:    #0A0D11;
  --k-carbon-2:  #0E1216;
  --k-carbon-3:  #141A20;
  --k-carbon-4:  #1A222A;
  --k-steel:     #1C242C;
  --k-steel-2:   #2A343E;
  --k-steel-3:   #3B4854;

  /* ───────── PRIMITIVAS · HUESO ─────────
     Blanco hueso cálido contra el carbón frío. Nunca #FFF puro. */
  --k-bone:      #E8E4DC;   /* 15.5:1 */
  --k-bone-2:    #B9B4AA;   /*  9.8:1 */
  --k-bone-3:    #8A9AAE;   /*  6.2:1 — SUELO LEGAL DE TEXTO */
  --k-bone-4:    #4A5058;   /*  2.2:1 — NUNCA TEXTO */

  /* ───────── PRIMITIVAS · ACENTOS ───────── */
  --k-red:       #E6142D;   /* 4.3:1 — ≥14px peso 600. Nunca microtexto ni prosa */
  --k-red-brt:   #FF3049;
  --k-red-deep:  #8C0A1C;
  --k-red-ink:   #2A060F;

  --k-amber:     #FCEE0A;   /* 13.9:1 — por eso es el color del foco */
  --k-amber-2:   #F2E900;
  --k-amber-3:   #B8AC00;
  --k-amber-ink: #262300;

  --k-cyan:      #00F0FF;   /* 12.1:1 */
  --k-cyan-2:    #0A7B84;
  --k-cyan-ink:  #04212A;

  --k-orange:    #FF6000;   /* 6.4:1 — mín. 14px */
  --k-ok:        #23C08A;   /* 9.1:1 */
  --k-ok-2:      #0E5C43;
  --k-purple:    #BD00FF;   /* 5.1:1 — mín. 16px/700, máx 1 uso/pantalla */

  /* ───────── PRIMITIVAS · PAPEL ───────── */
  --k-paper:     #F2EFE8;
  --k-paper-2:   #E4E0D6;
  --k-paper-3:   #D3CEC1;
  --k-ink:       #0B0E12;
  --k-indigo:    #1B2461;

  /* ───────── ESTADOS DEL MOD ─────────
     DESIGN §3.3. No son colores inventados: son los RGBA que el Master ya
     eligió en la configuración real del servidor (campo RGBA de cada
     StatusDef en `message (2).txt`). Fidelidad 1:1 y no cuesta nada.
     Se usan en la matriz de heridas de la ficha y en los chips de estado. */
  --st-critica:     #8C380A;  /* los 22 StatusDef de "Herdias Zonas" */
  --st-grave:       #B00808;  /* StatusDef 317 · Gravemente herido */
  --st-mortal:      #530101;  /* StatusDef 327 · Mortalmente Herido */
  --st-muerto:      #230000;  /* StatusDef 3021 · MUERTO */
  --st-psico:       #3E181C;  /* StatusDef 2972 · CYBERPSICÓPATA */
  --st-apuntar:     #D13C97;  /* StatusDef 2552 · Apuntar */
  --st-evasion:     #A845C0;  /* StatusDef 2934 · Evasión */
  --st-ventaja:     #1EFF17;  /* StatusDef 645 · Ventaja en tirada */
  --st-desventaja:  #FF2B2B;  /* StatusDef 516 · Desventaja en tirada */
  --st-descanso:    #00B028;  /* StatusDef 304 · Descansando */
  --st-hambre:      #73572B;  /* StatusDef 3055 · Hambriento */
  --st-comido:      #2F681A;  /* StatusDef 3056 · Bien Comido */

  /* ───────── BARRAS SMPTE · retrato sin señal ─────────
     Los siete grises coloreados del monitor vacío (§6.11). Estaban escritos a
     mano dentro del componente, contra el Anexo B.12 («cualquier valor de
     color escrito a mano fuera del bloque :root»). No son paleta de marca ni
     cambian con el tema: son la carta de ajuste de un tubo apagado, y por eso
     viven aquí, junto a las primitivas, y no entre las semánticas. */
  --smpte-1: #6E6E6E;
  --smpte-2: #6E6455;
  --smpte-3: #55666E;
  --smpte-4: #4C6450;
  --smpte-5: #6A5566;
  --smpte-6: #6E5A50;
  --smpte-7: #3A4048;

  /* ═══════════ SEMÁNTICAS · TEMA POR DEFECTO (oscuro, nivel 0) ═══════════
     Los componentes consumen SIEMPRE estas, nunca las primitivas de arriba.
     Ese es el motivo de que cambiar de nivel de acceso o de medio cueste
     exactamente dos bloques de variables y cero reglas nuevas. */
  --bg:            var(--k-carbon);
  --bg-deep:       var(--k-void);
  --surface:       var(--k-carbon-2);
  --surface-2:     var(--k-carbon-3);
  --field:         var(--k-carbon-4);

  --line:          var(--k-steel);
  --line-strong:   var(--k-steel-2);
  --grid:          rgba(59,72,84,.14);
  --grid-major:    rgba(59,72,84,.28);

  --text:          var(--k-bone);
  --text-2:        var(--k-bone-2);
  --text-3:        var(--k-bone-3);
  --text-off:      var(--k-bone-4);

  --accent:        var(--k-red);       /* CAMBIA con el nivel de acceso */
  --accent-brt:    var(--k-red-brt);
  --accent-deep:   var(--k-red-deep);
  --accent-ink:    var(--k-red-ink);
  --accent-on:     var(--k-void);      /* tinta sobre relleno de acento */

  /* EL TRAZO Y EL RELLENO NO SON EL MISMO ROJO (§11.1).
     --accent es el rojo institucional #E6142D y se queda donde tiene que
     estar: bordes, reglas, glifos, texto de ≥14px/600. Pero cuando ese mismo
     rojo se usa como RELLENO SÓLIDO CON TEXTO ENCIMA —cabecera de .reg-table,
     .btn--exec, .inject__bar, .banda— la tinta obligatoria --accent-on
     (--k-void) da 4,32:1, y 14px en negrita no es «texto grande» para WCAG
     (el umbral son 18,66px). Medido sobre el fondo compuesto real.
     --accent-fill sube el relleno a --k-red-brt: la misma tinta pasa a
     5,54:1 y el rojo institucional no se pierde, sólo deja de llevar texto
     encima. En nivel 1+ (cian, 14,32:1) y en calle (ámbar, 13,13:1) no hace
     falta y --accent-fill vuelve a ser --accent. */
  --accent-fill:   var(--k-red-brt);

  --alert:         var(--k-amber);
  --alert-ink:     var(--k-amber-ink);
  --focus:         var(--k-amber);     /* el foco SIEMPRE es ámbar, en los tres niveles */
  --system:        var(--k-cyan);
  --ok:            var(--k-ok);
  --danger:        var(--k-red-brt);
  /* Fondo hundido de un campo con incidencia. NO sigue al tema, por el mismo
     motivo que .ribbon.is-bleeding: una deficiencia es roja en nivel 0, en
     nivel 1 y en la calle (§3.4.1). Lo que sí cambia es el MEDIO: sobre papel
     un relleno granate deja el texto en negro sobre negro, así que ahí pasa a
     ser el mismo lavado claro que --accent-ink. */
  --danger-ink:    var(--k-red-ink);
  --warn:          var(--k-orange);
  --classif:       var(--k-red-deep);  /* banda de clasificación */

  /* ═══════════ TIPOGRAFÍA ═══════════
     Stack íntegramente OFL. Blender Pro (Gestalten) y Purista (Typekit/CDPR)
     no se autoalojan ni se enlazan — DESIGN §4.1 y Anexo B.14.2.4.
     Se cargan con <link rel="preconnect"> + <link rel="stylesheet">.
     JAMÁS con @import dentro de <style>: eso es la mitad del FOUC actual. */
  --ff-display: "Saira Condensed","Archivo Narrow","Arial Narrow",sans-serif;
  --ff-ui:      "Rajdhani","Saira Condensed",system-ui,sans-serif;
  --ff-body:    "Barlow","Rajdhani",system-ui,sans-serif;
  --ff-mono:    "IBM Plex Mono","JetBrains Mono",ui-monospace,monospace;
  --ff-osd:     "Share Tech Mono","IBM Plex Mono",monospace;
  --ff-jp:      "Noto Sans JP",var(--ff-ui);

  /* Escala modular base 16px. --fs-3xs (11px) es el SUELO ABSOLUTO y solo
     vale para OSD decorativo con aria-hidden. Un HUD ilegible no es
     inmersivo: es un HUD roto. */
  --fs-3xs: 0.6875rem;   --fs-2xs: 0.75rem;    --fs-xs:  0.8125rem;
  --fs-sm:  0.875rem;    --fs-md:  1rem;       --fs-lg:  1.0625rem;
  --fs-xl:  1.375rem;    --fs-2xl: 1.75rem;    --fs-3xl: 2.375rem;
  --fs-4xl: 3.25rem;
  --fs-5xl: clamp(3rem, 7.5vw, 6.5rem);
  --fs-6xl: clamp(4rem, 13vw, 11rem);

  --tr-tight:  -0.02em;  --tr-snug:  -0.01em;  --tr-none:   0;
  --tr-wide:    0.06em;  --tr-wider:  0.14em;  --tr-widest: 0.26em;
  --tr-slot:    0.32em;

  --lh-crush:   1.0;     --lh-display: 0.94;   --lh-ui:    1.25;
  --lh-data:    1.4;     --lh-body:    1.65;   --lh-loose: 1.85;

  /* ═══════════ ESPACIADO · base 4px ═══════════ */
  --sp-0: 0;      --sp-1: 4px;    --sp-2: 8px;    --sp-3: 12px;
  --sp-4: 16px;   --sp-5: 24px;   --sp-6: 32px;   --sp-7: 48px;
  --sp-8: 64px;   --sp-9: 96px;   --sp-10:128px;  --sp-11:192px;

  /* ═══════════ LIENZO Y RETÍCULA ═══════════ */
  --canvas-max:  1600px;
  --gutter:      24px;
  --margin:      clamp(16px, 4vw, 64px);
  --measure:     68ch;      /* medida de lectura de prosa */
  --measure-form:560px;
  --rail-w:      56px;      /* raíl scrubber — firma estructural */
  --bar-top:     22px;      /* banda de clasificación */
  --bar-bottom:  22px;
  --header-h:    64px;
  --command-h:   52px;      /* barra de comandos inferior */
  --grid-cols:   12;
  --grid-minor:  8px;
  --grid-major-sz: 64px;
  --skew-calle:  1px;       /* desalineación decorativa de zona calle */

  /* ═══════════ FORMA ═══════════ */
  --radius: 0;              /* CERO. En todo. Sin excepción. Anexo B.1. */

  --chf-xs: 6px;    --chf-sm: 10px;   --chf-md: 16px;
  --chf-lg: 28px;   --chf-xl: 32px;
  --chf-ang: 42.5deg;       /* NO 45°. El oficial es 16.65×18.14 */

  --bw-hair: 1px;   --bw-1: 1px;   --bw-2: 2px;
  --bw-3:    3px;   --bw-rule: 4px;  --bw-seal: 6px;

  /* ═══════════ ELEVACIÓN ═══════════ */
  --sh-flat:  none;
  --sh-sunk:  inset 0 1px 0 rgba(0,0,0,.55), inset 0 -1px 0 rgba(255,255,255,.03);
  --sh-lift:  0 18px 44px -24px rgba(0,0,0,.95);
  --sh-modal: 0 40px 90px -30px rgba(0,0,0,1);
  --sh-hard:  6px 6px 0 var(--k-void);
  --glow-accent: 0 0 0 1px var(--accent),
                 0 0 22px -6px color-mix(in srgb, var(--accent) 55%, transparent);
  --glow-alert:  0 0 0 1px var(--alert),
                 0 0 26px -8px color-mix(in srgb, var(--alert) 60%, transparent);
  --glow-system: 0 0 0 1px var(--system),
                 0 0 22px -6px color-mix(in srgb, var(--system) 50%, transparent);

  /* ═══════════ CAPAS ═══════════ */
  --z-base:      0;
  --z-content:  10;
  --z-raised:   20;
  --z-rail:    100;
  --z-header:  200;
  --z-command: 210;
  --z-dropdown:300;
  --z-toast:   400;
  --z-scrim:   490;
  --z-modal:   500;
  --z-texture: 700;   /* scanlines + grano, pointer-events:none */
  --z-classif: 750;   /* bandas de clasificación, siempre arriba */
  --z-boot:    900;

  /* ═══════════ MOVIMIENTO ═══════════ */
  --ez-term:  cubic-bezier(.16, 1, .30, 1);    /* salida rápida, asiento seco */
  --ez-mech:  cubic-bezier(.65, 0, .35, 1);    /* mecanismo ida y vuelta */
  --ez-snap:  cubic-bezier(.20, 0, .00, 1);    /* golpe, sello */
  --ez-in:    cubic-bezier(.55, 0, 1, .45);    /* salida de pantalla */
  --ez-back:  cubic-bezier(.175,.885,.32,1.275);/* toast */
  --ez-lin:   linear;

  --d-instant:  80ms;   --d-fast:  120ms;  --d-base:  180ms;
  --d-slow:    240ms;   --d-panel: 320ms;  --d-heavy: 480ms;
  --d-boot:    900ms;   --d-declass: 1400ms;

  /* ═══════════ TEXTURA ═══════════
     Se apaga por token, sin tocar una sola regla de efecto (§3.6 y §11.4).
     El valor de scanline del repo antiguo era .005 (1,3/255): invisible en
     cualquier pantalla. El rango real que se ve es .020–.030. */
  --fx-scan-alpha:  .028;
  --fx-grain-alpha: .045;
  --fx-halo:        1;      /* multiplicador 0–1 */
  --fx-vignette:    .55;
  --fx-noise-fps:   8;

  /* ═══════════ AUDIO ═══════════
     Los lee audio.js con getComputedStyle. El lowpass a 3200 Hz es lo que
     hace que todo suene A TRAVÉS DE UN ALTAVOZ BARATO y pertenezca a la
     ficción en vez de sonar a pitidos de app web (§9.1). */
  --audio-master: 0.10;
  --audio-lpf:    3200;     /* Hz */
}


/* ═══════════════════════════════════════════════════════════════════════════
   NIVEL DE ACCESO 1+ — el sistema te acepta y se enfría

   Esto es la progresión narrativa entera (§1.5): el rojo de vigilancia se
   retira y entra el cian de operador autorizado. Ocurre UNA VEZ en la vida
   del jugador y cuesta exactamente estas seis líneas. Ninguna animación del
   documento compra tanto por tan poco.
   El cian NUNCA aparece en nivel 0: es el color de "estás dentro" (§3.4.3).
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-acceso="1"],
:root[data-acceso="4"]{
  --accent:      var(--k-cyan);
  --accent-brt:  #6BF7FF;
  --accent-deep: var(--k-cyan-2);
  --accent-ink:  var(--k-cyan-ink);
  --accent-on:   var(--k-void);
  --accent-fill: var(--accent);   /* --k-void sobre cian: 14,32:1, va sobrado */
  --classif:     var(--k-cyan-2);
}

/* NIVEL 4 · Oficial Verificador — la banda de clasificación pasa a ámbar.
   La tinta de la banda la resuelve chrome.css, porque sobre relleno ámbar
   la tinta obligatoria es --k-amber-ink (§3.4.5) y eso es del componente. */
:root[data-acceso="4"]{ --classif: var(--k-amber-3); }


/* ═══════════════════════════════════════════════════════════════════════════
   ZONA CALLE — NETdir://era3.web

   El ámbar es la marca de la calle y el acento de nivel es la marca del
   sistema (§2.2 regla 4). En la calle el primario es SIEMPRE ámbar, sea cual
   sea el nivel de acceso: eso hace que la calle "se sienta" tuya y el
   registro "se sienta" ajeno sin cambiar un solo componente.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-zona="calle"]{
  --accent:      var(--k-amber);
  --accent-brt:  #FFF95C;
  --accent-deep: var(--k-amber-3);
  --accent-ink:  var(--k-amber-ink);
  --accent-on:   var(--k-amber-ink);
  --accent-fill: var(--accent);   /* --k-amber-ink sobre ámbar: 13,13:1 */
  --fx-scan-alpha:  .020;
  --fx-grain-alpha: .055;
  --grid:        transparent;   /* sin rejilla milimetrada en la calle */
  --grid-major:  transparent;

  /* Las bandas de clasificación están AUSENTES en la calle (§2.1). Se anulan
     aquí, a nivel de token, para que el relleno del chasis se recalcule solo:
     chrome.css oculta el elemento, pero es este cero el que impide que quede
     una franja de 22px de aire muerto arriba y abajo de la pantalla. */
  --bar-top:     0px;
  --bar-bottom:  0px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   MODO COPIA IMPRESA — data-medio="papel"

   No es "modo claro". Es la ficción de que has despegado el overlay y ves el
   documento oficial de debajo: papel térmico amarilleado, tinta índigo, sello
   de Night Corp. El mismo dato, contado por el poder (§3.6).
   La textura se apaga por token; ninguna regla de efecto se toca.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-medio="papel"]{
  color-scheme: light;

  --bg:          var(--k-paper);
  --bg-deep:     var(--k-paper-2);
  --surface:     #FFFFFF;
  --surface-2:   var(--k-paper-2);
  --field:       #FFFFFF;
  --line:        var(--k-paper-3);
  --line-strong: #A9A294;
  --grid:        rgba(11,14,18,.06);
  --grid-major:  rgba(11,14,18,.12);
  --text:        var(--k-ink);
  --text-2:      #3A4048;

  /* EL SUELO DE TEXTO TAMBIÉN ES SUELO EN PAPEL, Y NO LO ERA.
     Este token llevaba #6A7078, calculado a ojo contra el papel. Medido en
     Chrome sobre el fondo compuesto real: 4,35:1 contra --bg (#F2EFE8), 5,00:1
     contra --surface (#FFFFFF) y 3,79:1 contra --surface-2 (#E4E0D6). El
     tercero está por debajo del 4,5:1 de WCAG AA, no ya del 6,2:1 de §11.1 —y
     ahí es donde viven `.sys`, `.hint`, `.kv dt`, `.opline`, `.netdir`, el
     identificador del raíl, la línea de tiempo del registro y el descargo
     legal obligatorio del Anexo B.14.2.2.
     #484E56 mide 7,34 / 8,43 / 6,40:1 en esas tres superficies. La jerarquía
     con --text-2 (9,1:1) se conserva: en papel la separa el tamaño y el peso,
     no el desvanecimiento. */
  --text-3:      #484E56;
  --text-off:    #A9A294;

  --accent:      #B00F24;
  /* EN PAPEL, «BRILLANTE» ES «MÁS TINTA».
     --accent-brt llevaba el #E6142D de pantalla, que sobre el relleno casi
     blanco de `.btn--line` da 4,58:1. Sobre papel la prominencia no se
     consigue subiendo el brillo sino cargando el granate: --k-red-deep sobre
     ese mismo relleno da 9,44:1. */
  --accent-brt:  var(--k-red-deep);
  --accent-deep: #7A0817;
  --accent-ink:  #F7E6E8;
  --accent-on:   #FFFFFF;
  /* En papel el relleno de acento ya lleva tinta blanca a 7,14:1: no hace
     falta el rojo de fósforo, que además sobre papel canta. */
  --accent-fill: var(--accent);

  /* LOS CINCO SEMÁNTICOS DE ESTADO, BAJADOS AL SUELO DE PAPEL.
     Todos estaban en su versión «de pantalla trasladada», y todos caían por
     debajo del suelo en cuanto se medían sobre --surface-2, que es el fondo
     de las tarjetas y los avisos: --alert 3,57:1, --system 5,30:1, --ok
     4,65:1, --warn 4,79:1 y --danger —que ni siquiera tenía rebanada de
     papel— 2,76:1 con el #FF3049 de fósforo intacto. Los valores nuevos
     miden 6,8 / 7,5 / 7,0 / 6,4 / 7,3:1 sobre esa misma superficie.
     No es un cambio de paleta: es la misma tinta, impresa. */
  --alert:       #514A00;
  --alert-ink:   #FBF6C8;
  --focus:       #514A00;
  --system:      #044B51;
  --ok:          #085139;
  /* La negativa no sigue al tema (§3.4.1) pero SÍ sigue al medio: el rojo de
     fósforo no existe en una imprenta. --k-red-deep es el mismo granate que
     ya usa `.btn--deny` en su rebanada, así que el papel no estrena color. */
  --danger:      var(--k-red-deep);
  /* El granate de terminal deja el texto en negro sobre negro sobre papel:
     aquí la incidencia se marca con el mismo lavado claro que --accent-ink,
     y el rojo del estado sigue viviendo en la línea de escritura. */
  --danger-ink:  #F7E6E8;
  --warn:        #853400;
  --classif:     #7A0817;
  --fx-scan-alpha:  0;
  --fx-grain-alpha: 0;
  --fx-halo:        0;
  --fx-vignette:    0;

  /* Sobre papel una sombra negra profunda delata que esto es una pantalla.
     Se rebajan a marca de imprenta: desplazamiento corto y tinta gris. */
  --sh-sunk:  inset 0 1px 0 rgba(11,14,18,.10);
  --sh-lift:  0 2px 0 rgba(11,14,18,.18);
  --sh-modal: 0 6px 0 rgba(11,14,18,.22);
  --sh-hard:  4px 4px 0 rgba(11,14,18,.18);
}

/* GESTO DE IMPRENTA (§3.4.5): sobre relleno amarillo, en papel, la tinta es
   índigo. Nunca negro. Es la diferencia entre un PDF y un impreso oficial. */
:root[data-medio="papel"][data-zona="calle"]{
  --accent:    var(--k-amber);
  --accent-on: var(--k-indigo);
}


/* ═══════════════════════════════════════════════════════════════════════════
   COPIA (ciclos de corrección) — SOLO DATO, sin degradación

   Decisión explícita y deliberada de DESIGN §12.3: se evaluó ligar grano,
   scanline y halación al contador de COPIA y se DESCARTA. Castigar
   estéticamente al jugador que más notas de corrección tiene que leer es un
   antipatrón de accesibilidad disfrazado de narrativa. El dato queda visible
   en el chasis; el castigo no existe. Por eso aquí no hay ningún selector
   [data-copia]: su ausencia es la decisión.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTO MÓVIL — §8.9 y §11.4

   "Sin capas de textura bajo 768px salvo scanlines a .020". El grano animado
   y la viñeta son las dos capas que cuestan en una GPU de móvil, y son
   justamente las dos que menos aportan a esa distancia de lectura.
   Se resuelve aquí, en valores de token, porque el chasis no debe saber nada
   de presupuestos: solo pinta lo que los tokens le dicen.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px){
  :root{
    --fx-scan-alpha:  .020;
    --fx-grain-alpha: 0;
    --fx-vignette:    0;
    --fx-halo:        0;

    /* El raíl de 56px deja de ser columna y pasa a franja horizontal bajo el
       HUD (§11.4). El ancho a cero es lo que colapsa el sangrado izquierdo de
       todo el chasis de una sola vez. */
    --rail-w:     0px;

    /* Banda de clasificación a 16px y SOLO la superior (§11.4). */
    --bar-top:    16px;
    --bar-bottom: 0px;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   MOVIMIENTO REDUCIDO

   Único bloque de todo el sistema donde se permite !important, y se permite
   porque tiene que ganarle a cualquier animación declarada más abajo en la
   cascada, incluidas las de página.

   Ojo al detalle que hace que esto funcione sin apagar nada a mano: casi
   todos los bucles del catálogo (§7.2) terminan en su estado de reposo
   —pulse vuelve a opacidad 1, noise-shift a la posición 0, marquee a
   translateX(0), caret a bloque visible— porque no llevan animation-fill-mode.
   Con duración .01ms y una sola iteración, el resultado es la interfaz
   quieta y completa, no la interfaz rota a medio fotograma.
   Lo que no se resuelve solo (la marquesina, que necesita scroll manual) se
   corrige en chrome.css.

   La textura NO es movimiento: scanlines, grano estático, rejilla, viñeta,
   chaflanes, redacción, sellos y todos los colores se CONSERVAN (§11.3).
   Se pierde el 5% del efecto y se gana el 100% de los usuarios.

   ───────────────────────────────────────────────────────────────────────────
   EL INTERRUPTOR MODO DE RENDERIZADO ANULA LA MEDIA QUERY EN AMBAS DIRECCIONES

   §11.3 no pide un ajuste que ACOMPAÑE a la preferencia del sistema: pide uno
   que la ANULE en las dos direcciones, porque hay quien tiene el sistema en
   reducido y quiere el espectáculo aquí. `session.js` escribe `data-render`
   en <html> con cuatro estados —ausente (AUTOMÁTICO), `completo`, `reducido`
   y `plano`— y `hud.js` los cicla. Este bloque es el único sitio donde ese
   atributo se convierte en comportamiento, y funciona con dos guardas:

     A · dentro de la media query, `:root:not([data-render="completo"])`
         → el sistema manda, SALVO que el operador haya pedido COMPLETO.
     B · fuera de la media query, `:root[data-render]:not([data-render="completo"])`
         → REDUCIDO y TEXTO PLANO apagan el movimiento aunque el sistema no lo
           pida. Se escribe así, y no como lista `[="reducido"],[="plano"]`,
           porque session.js sólo admite esos tres valores o borra el atributo:
           «tiene atributo y no es completo» es exactamente el par que falta.

   Las dos guardas se repiten en las cabeceras de los bloques de movimiento
   reducido de chrome.css, components.css y pages/wizard.css. Es duplicación
   deliberada: no hay forma en CSS de compartir un cuerpo entre una condición
   de media query y una de atributo, y un `@container style()` para esto sería
   apostar el ajuste de accesibilidad obligatorio a una función de 2024.

   TEXTO PLANO es además el modo de bajo consumo de móvil: pone los --fx-* a 0
   y con eso apaga scanlines, grano, halación y viñeta sin tocar una regla de
   efecto, exactamente igual que hace COPIA IMPRESA.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  :root:not([data-render="completo"]),
  :root:not([data-render="completo"]) *,
  :root:not([data-render="completo"]) *::before,
  :root:not([data-render="completo"]) *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  :root:not([data-render="completo"]){ --fx-noise-fps: 0; }
}

/* RENDER: REDUCIDO y RENDER: TEXTO PLANO — el mismo apagado, forzado por el
   interruptor de la cabecera, sin media query de por medio. */
:root[data-render]:not([data-render="completo"]),
:root[data-render]:not([data-render="completo"]) *,
:root[data-render]:not([data-render="completo"]) *::before,
:root[data-render]:not([data-render="completo"]) *::after{
  animation-duration: .01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .01ms !important;
  scroll-behavior: auto !important;
}
:root[data-render]:not([data-render="completo"]){ --fx-noise-fps: 0; }

/* RENDER: TEXTO PLANO — además, la textura entera a cero. Es el tercer estado
   de §11.3 al pie de la letra y el modo de bajo consumo del móvil. */
:root[data-render="plano"]{
  --fx-scan-alpha:  0;
  --fx-grain-alpha: 0;
  --fx-halo:        0;
  --fx-vignette:    0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   RESET DE FORMA GLOBAL

   Anexo B.1: border-radius distinto de 0 está prohibido en cualquier
   componente. No se confía en la disciplina de nadie: se desactiva la
   propiedad en todo el árbol, incluidos los widgets nativos y cualquier CSS
   de tercero que llegue después. Un solo botón redondeado rompe la ficción de
   documento oficial troquelado.

   El box-sizing vive en reset.css para no declararlo dos veces.
   ═══════════════════════════════════════════════════════════════════════════ */
*,*::before,*::after{ border-radius: var(--radius); }
