/* ═══════════════════════════════════════════════════════════════════════
   TOKENS — copiados TAL CUAL de desarrollo/mockup-ux-interfaz.html.

   Es el §1 de ../../../../reglas/sistema-grafico-notion.md, y es el único
   archivo del front donde puede aparecer un hex o un radio en px.
   pruebas/estructura.test.js falla si aparece uno en cualquier otro lado.

   NO SE RE-DECIDE NINGUNO. Estos valores están verificados por contraste en
   los dos modos (probar-contraste.js, 30+ comprobaciones) y fueron corregidos
   TRES VECES por Alan en una misma noche. El acento pasó por azul → verde
   petróleo → violeta ciruela, y la tercera parada tiene su fundamento escrito
   (geometría, daltonismo, psicología de marca, precedente Cadbury) en el
   §1.2 bis del documento. Si algo parece mal, se dice y se sigue construyendo
   con lo que está: un sistema al que cada sesión le mueve una cosa razonable
   deja de ser un sistema en un mes.

   Los comentarios vienen del mockup a propósito: son el porqué de cada
   asignación, y perderlos al copiar es cómo un sistema se vuelve arbitrario.
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   TOKENS
   Color reducido a propósito: codifica UNA dimensión (urgencia),
   no ocho tipos de señal. El tipo lo dice el ícono y el rótulo.

   ── El sistema gráfico, rehecho (1/09) ─────────────────────────────
   Lo anterior lo había elegido Claude por instinto, tomando hexes de
   tres archivos de Figma que no eran de este producto. Esta versión
   sale de preguntarle a la skill por el PRODUCTO y no por su landing:
   `--domain product` para «B2B Service» devuelve *Dashboard Style:
   Sales Intelligence Dashboard · Color: professional blue + neutral
   grey*, que es literalmente lo que Campo es; «Analytics Dashboard»
   (Tecnología y SaaS) devuelve «blue data + amber highlights»; y
   «Banking/Traditional Finance» (Finanzas), «trust navy + premium
   gold». Las tres coinciden: AZUL DE DATO SOBRE GRIS NEUTRO.

   El ámbar NO puede ser el acento de marca aunque la skill lo sugiera:
   ya es un estado —«para mirar», que son 27 de los 86 clientes—. El
   azul estaba libre y no colisiona con ninguno de los tres estados.

   La escala de grises del modo oscuro no se toca: es lo único del
   sistema anterior que se conserva, por pedido explícito.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  /* Contraste verificado contra los cuatro fondos sobre los que se dibuja
     cada token (paper / raise / hover / tintes). Todo texto >= 4.5:1.
     Regla al editar: --muted-2 NO se usa nunca sobre los tintes suaves
     (--ember-soft, --ok-soft, --alerta-soft): ahí cae a ~4.2:1. */
  /* ═══ LA RAMPA NEUTRA ═══════════════════════════════════════════════
     Doce pasos de un solo gris cálido, del más claro al más oscuro.
     **Los valores no son nuevos: son exactamente los que ya tenía la
     paleta.** Se midió antes de tocar nada y resultó que ya formaban
     una rampa coherente — L* monótono de 99,7 a 6,7, tono clavado
     entre 43° y 51°, y la saturación subiendo con la oscuridad, que es
     como se comporta un neutro cálido bien construido. Así que esto no
     es un rediseño de color: es ponerle nombre de posición a lo que ya
     existía. Ni un píxel cambia de valor.

     **Por qué importa, y de dónde sale:** es el requisito que la quinta
     pasada (los archivos de Figma) le agregó al grupo 3. El CRM system
     Case Study dibuja las mismas pantallas en claro y en oscuro, y
     medido resultó que no tiene dos paletas: **superficie y tinta
     intercambian rol sobre la misma rampa**, y el contraste se
     conserva (17,74:1 en claro contra 16,98:1 en oscuro). Mientras los
     tokens fueran «rol → hex suelto», el modo oscuro del grupo 4 era
     re-derivar veintidós colores uno por uno con su ratio verificado.
     Con la rampa es un intercambio de extremos: --paper pasa a apuntar
     a n-10 y --ink a n-1, y todo lo demás sigue.

     El único hueco de la rampa está entre n-6 (L* 72,6) y n-7 (45,7).
     No molesta en claro porque nada cae ahí; el modo oscuro va a
     necesitar un paso intermedio, y esa es una decisión del grupo 4. */
  /* Los primeros seis pasos (n-0 a n-5) se entibiaron el 15/09 para el
     restyling Notion: mismo L* aproximado que antes, hue rotado hacia
     el cálido (menos azul, más rojo/verde) — es la diferencia entre
     «pantalla» y «papel» que pide la referencia. n-1 queda a un pelo de
     #F7F6F3, que es literalmente el gris de sidebar de Notion. Sólo
     estos seis: n-6 en adelante NO se toca porque son texto en modo
     oscuro (`--media`/`--muted`/`--muted-2` oscuros apuntan a n-6/7/8) y
     tocarlos ahí arriesga el mínimo de contraste ya verificado. Reverificado
     con `probar-contraste.js` después del cambio — ver ROADMAP/historial. */
  --n-0:#fdfcf9;   /* L* 99.0  — la superficie clara, entibiada */
  --n-1:#f7f5f0;   /* L* 96.9  — el fondo de pagina, entibiado (≈ sidebar de Notion) */
  --n-2:#f3f1ec;   /* L* 95.8 */
  --n-3:#ece9e2;   /* L* 93.1 */
  --n-4:#e6e2d8;   /* L* 91.6 */
  --n-5:#d5d0c3;   /* L* 85.6 */
  --n-6:#b9bbc4;   /* L* 76.0 */
  --n-7:#a9acb6;   /* L* 70.4 */
  --n-8:#9c9faa;   /* L* 65.6 */
  --n-9:#686d7a;   /* L* 46.0 */
  --n-10:#5f6470;  /* L* 42.3 */
  --n-11:#535864;  /* L* 37.4 */
  --n-12:#4d515b;  /* L* 34.4 */
  --n-13:#43454d;  /* L* 29.4 */
  --n-14:#3c3e43;  /* L* 26.2 */
  --n-15:#373a44;  /* L* 24.5 */
  --n-16:#333333;  /* L* 21.2  — el panel oscuro del archivo */
  --n-17:#2e2e2e;  /* L* 18.9  — idem */
  --n-18:#1e1e1e;  /* L* 11.3  — la tinta del archivo */

  /* ── Los roles, como posiciones de la rampa ────────────────────────
     Acá es donde se hace el modo oscuro: se cambian estas doce líneas,
     no los doce colores. Los ratios verificados siguen siendo los
     mismos porque los valores son los mismos. */
  --paper:var(--n-1);     /* #f6f6f8 — la pagina es GRIS, no blanca */
  --raise:var(--n-0);     /* #fcfcff — y la tarjeta es mas clara que la pagina.
                             Es la inversion que trae el archivo: antes el
                             contenido flotaba sobre crema con una linea; ahora
                             flota sobre gris con superficie propia. */
  /* El hover del archivo se separa 1,029:1 del fondo — practicamente
     invisible, y esta app se lee al sol. Se sube un paso de la MISMA rampa:
     sigue siendo un valor del archivo, con separacion que se ve. */
  --hover:var(--n-3);     /* 1.06:1 sobre paper */
  /* `--zebra` es la fila alternada de una tabla, y NO puede ser `--hover` ni
     `--paper`: los dos estan definidos contra `--paper`, y una tabla pone sus
     filas DENTRO de una superficie `--raise`. Ahi la relacion se da vuelta.
     Medido con `--paper`: 1.03:1 en claro y 1.21:1 en oscuro, o sea invisible
     en un tema y dos colores en el otro. Es el paso contiguo a `--raise` en
     cada modo — n-1 aca, n-17 en oscuro. */
  --zebra:var(--n-1);     /* 1.03:1 sobre raise */
  --line-soft:var(--n-5); /* 1.35:1 */
  --line:var(--n-6);      /* 1.94:1 */
  --ink:var(--n-18);      /* 15.2:1 sobre paper */
  --ink-2:var(--n-15);    /* 10.5:1 */
  /* Los tres se calculan contra --hover, que es la superficie mas OSCURA
     donde cae texto, y no contra --paper. Es la misma leccion que el modo
     oscuro: apuntando a paper, --muted-2 daba 4,8:1 ahi y 4,35:1 sobre el
     hover, o sea fallaba justo en la fila que el dedo esta tocando. */
  --media:var(--n-12);    /*  7.0:1 sobre paper · 6.3:1 sobre hover */
  --muted:var(--n-11);    /*  6.2:1 · 5.6:1 */
  --muted-2:var(--n-10);  /*  5.5:1 · 4.9:1 — mínimo del sistema */

  /* ── Acentos: tres ranuras iguales para los tres ───────────────────
     `soft` es el tinte de fondo, `base` el relleno y `tx` el texto
     sobre paper. Antes sólo ámbar tenía las tres y los otros dos
     usaban el relleno como texto — funcionaba, pero dejaba al sistema
     sin la ranura donde el modo oscuro tiene que rotar. Porque la otra
     mitad de la lección del Case Study es que **el acento rota, no se
     invierte**: usa azul-700 sobre blanco y azul-300 sobre el fondo
     oscuro. Dejar el mismo azul en los dos modos daba 2,65:1. Ámbar
     sobre --ink ya lo venía haciendo a mano, con el #f0b57a que estaba
     suelto en tres lugares; ahora tiene nombre. */
  /* El acento tuvo TRES familias en un mismo día (15/09). Vale la pena
     dejar escrito el recorrido completo porque cada parada falló por un
     motivo distinto y el que viene después tiene que conocerlos:

     1. AZUL de dato genérico — el de toda la primera pasada de este
        restyling. Técnicamente perfecto (lejos de los tres estados) pero
        Alan lo rechazó por genérico: es el azul de cualquier dashboard
        SaaS, Notion incluido, y no dice nada del rubro.
     2. VERDE AZULADO / petróleo — el segundo intento, mismo argumento
        que el azul (lejos de los tres estados) más una lectura de marca
        de alimentos gourmet. Cayó por lo mismo que el azul pero en la
        dirección opuesta: Alan lo vio y dijo, con razón, que un verde
        agua es un color de spa/wellness — la calma es exactamente lo
        contrario de la energía que necesita alguien que toca puertas
        todo el día. Ninguno de los dos análisis anteriores había mirado
        la psicología del color, sólo la geometría del círculo cromático.
     3. VIOLETA CIRUELA, saturado y de valor medio-oscuro — nunca
        lavanda pastel — es el que quedó, después de pedirle a un
        subagente en rol de consultor de marca (15 años de UX/UI) un
        perfil de cliente explícito y tres alternativas con su psicología
        de color. Gana en las tres dimensiones que importan:
          · Geometría: a 60-100° del rojo, 140-160° del ámbar y 120-140°
            del verde — el doble o el triple de margen que tenía el
            candidato más cercano descartado (un naranja, que quedaba
            literalmente encajonado en los ~55° que separan al rojo del
            ámbar de estado).
          · Daltonismo rojo-verde (el más común, deuteranopía/
            protanopía): el violeta conserva componente azul, percibido
            por el cono S que esa condición no afecta, así que sigue
            leyéndose distinto de rojo/ámbar/verde. El naranja y el
            magenta, al ser variantes de rojo, tienden a colapsar hacia
            el mismo marrón-amarillento que el rojo y el ámbar de estado
            bajo esa condición — literatura de color science general,
            no medido con una herramienta de simulación en esta sesión.
          · Psicología de marca: ambición y decisión, con precedente real
            en la categoría de alimentos — Cadbury construyó su identidad
            sobre un morado precisamente para diferenciarse en un rubro
            de commodities sin sonar frío (azul) ni delicado (verde
            agua). Ejecutado saturado y oscuro se lee firme, no frágil —
            el mismo error de fondo que el verde agua, evitado del otro
            lado de la paleta.

     El nombre del token —`--ember`, brasa— sigue sin describir el color
     que tiene adentro, y ya lleva tres cambios de familia sin cambiar de
     nombre (ámbar → azul el 1/09, azul → petróleo → ciruela el 15/09).
     Renombrarlo es un cambio mecánico de ~100 referencias sin necesidad
     funcional — se deja anotado, otra vez, para quien lo lea después. */
  --ember-soft:#f2e5f5;   /* 1.11:1 sobre paper — misma familia que los otros
                             tintes (ok 1.10, alerta 1.15) */
  --ember:#85259d;        /* relleno: blanco encima 7.64:1 (el azul daba 4.62, el
                             petróleo intermedio 5.22 — este es el más «fuerte» de
                             los tres en el sentido que pidió Alan: más oscuro,
                             más saturado, más margen de contraste) */
  --ember-tx:#651778;     /* el relleno como texto sobre paper no llega. Mismo
                             tono, mas oscuro: 9.90:1 sobre paper y 8.90:1 sobre
                             hover, que es la superficie mas oscura donde cae */
  --ember-on-ink:#d398e1; /* rotado — donde el fondo es la tinta (el toast).
                             7.42:1 sobre #1e1e1e */
  --alerta-soft:#f6e2e8;
  --alerta:#c81d50;       /* del #e10c4c del archivo, que como texto daba 3.9:1.
                             Mismo tono, 5.2:1 */
  --alerta-tx:var(--alerta);
  --ok-soft:#dbf1e1;
  --ok:#14772f;           /* el verde oscuro del archivo — 5.6:1 */
  --ok-tx:var(--ok);
  /* ── El amarillo, que faltaba ──────────────────────────────────────
     El archivo usa CUATRO colores para clasificar, no tres: violeta, rojo,
     verde y amarillo (#fcd583 en los cantos de tarjeta, tono 41°). Campo
     tenia tres, y su cuarto estado —«para mirar»— se dibujaba en gris,
     o sea que la mitad de la cartera no tenia color propio.

     Y con el amarillo entra la semantica del archivo, que es lo que hace
     que los colores signifiquen algo en vez de decorar:
       verde    = algo salio bien          (ventas diarias, «Sold»)
       rojo     = algo salio mal           (gastos, «Consumed»)
       amarillo = mirá esto                (el punto destacado del grafico)
       azul     = dónde estás parado       (el item activo del menu, lo tuyo) */
  --ojo-soft:#f6e5c2;
  --ojo:#7d5b16;          /* 5.8:1 sobre paper · 5.2:1 sobre hover */
  --ojo-tx:var(--ojo);
  --ojo-fill:#d99b1f;     /* SOLO relleno: 2.3:1 sobre paper, que alcanza
                             para una barra rotulada y no para texto */

  /* ── Rellenos fuertes (15/09, pedido de Alan) ───────────────────────
     El acento de urgencia dejó de ser un borde de canto: Alan lo vio y
     dijo lo que es — el patrón de tarjeta con barra de color a la
     izquierda es Material Design, no Notion, y acá desentonaba. Pasó
     primero a un punto sólido antes del nombre, y en una segunda vuelta
     el punto también se sacó — la urgencia se lee ahora en la chapa de
     estado (`chapaEstado()`, con sus tonos de texto normales, `--*-tx`
     sobre `--*-soft`), no en ningún color de fondo de `.row`. Estos
     rellenos quedaron sin más uso que `.ley-c` (la leyenda, que a su vez
     quedó sin llamador — ver su nota junto a `.leyenda`) pero se
     mantienen definidos: son la ranura correcta para cualquier futuro
     punto/relleno de estado que no sea texto y necesite más saturación
     que la que el mínimo de contraste permite. No son texto: no
     necesitan 4,5:1, necesitan distinguirse a simple vista y cumplir el
     pedido explícito de que el color sea más fuerte. `--ojo-fill` ya
     existía con exactamente este criterio («SOLO relleno»); acá se
     completa la familia para alerta/ok —
     mismo tono que su versión de texto, más saturación y más luz,
     porque sin el piso de 4,5:1 no hace falta oscurecerlos para que el
     texto encima entre. `--ember` ya cumplía este rol (es relleno de
     botón desde el origen) y se reusa tal cual. Constantes en los dos
     modos, como `--ojo-fill`: es un color de estado, no de tema. */
  --alerta-fill:#e0143f;
  --ok-fill:#159143;
  --ember-fill:var(--ember);

  /* AGREGADO AL PORTAR EL SISTEMA A public/ (16/09/2026). NO es un color
     nuevo ni una decisión reabierta: es el nombre de un color que YA estaba
     en el sistema, escrito como `#fff` suelto cinco veces (el botón primario,
     el FAB, el botón del micrófono, .fchip.on y .pick button.on).

     Se nombra por dos motivos, y ninguno es estético:
     1. R3 de la constitución del front dice que ningún color se escribe a
        mano fuera de este archivo, y pruebas/estructura.test.js lo verifica.
        Un `#fff` suelto en componentes.css es exactamente lo que ese chequeo
        existe para encontrar, y la respuesta correcta a un test que encuentra
        algo real no es aflojar el test.
     2. Es un ROL, no un valor: «lo que va encima del acento». El día que el
        acento cambie por cuarta vez, este token es el lugar donde se mira si
        el texto de encima sigue llegando al mínimo.

     Constante en los dos modos, como --alerta-fill y --ok-fill: `--ember`
     (#85259d) es el mismo hex en claro y en oscuro, y blanco encima da
     7,64:1 en los dos. Ni un pixel cambia respecto del mockup. */
  --sobre-ember:#fff;

  /* Rampa secuencial del gráfico apilado — tres tintes del mismo acento,
     que es la forma correcta para una sola dimensión ordenada. Era una
     rampa de rojos hasta el 1/09 (una dimensión ordenada dibujada con el
     color que significa «salió mal»), de azul hasta el restyling del
     15/09 (2), y de petróleo hasta que ese mismo día el acento pasó a
     violeta ciruela — sigue al color de marca, con el mismo hue. */
  --seq-1:#5d156f;
  --seq-2:#b24dcb;
  --seq-3:#e2c9e9;

  /* La caja .aviso — la advertencia de que el mapa de competencia es lo
     que dicen los clientes y no lo que pasa en el mercado. Los dos
     tokens se usaban desde siempre y no estaban definidos: la caja se
     dibujaba sin fondo y el ícono heredaba el gris del cuerpo, o sea
     que la frase más cuidada del producto estaba puesta como texto
     suelto. Registro neutro a propósito, no ámbar: no avisa de un
     peligro, acota el alcance de lo que se está mirando. */
  --media-bg:var(--n-4); /* 1.15:1 sobre paper — dentro de la familia de
                         tintes suaves (ember 1.12, ok 1.10, alerta 1.15) */

  /* Sobre --media-bg: --ink-2 da 9.4:1 y --muted 5.0:1, los dos pasan.
     --muted-2 da 4.3:1 y NO se usa acá, igual que en los otros tintes. */

  /* Gráficos. `--viz-acento` era `var(--alerta)`: o sea que la barra
     DESTACADA de cualquier gráfico se pintaba con el color que en toda
     la app significa «salió mal». Una barra señalada no es una barra
     mala. Pasó al azul el 1/09 (ΔE 67 contra el gris de contexto, era 31
     con el rojo), después a petróleo y ahora sigue al acento violeta del
     15/09 (2) — recalculado con CIE76 contra `--n-7`: **ΔE ≈ 77** en
     claro, el más alto de las cuatro paradas de este token. Muy por
     encima de cualquier umbral de distinción (10-20 según la referencia
     que se use) y del propio azul, que ya era holgado.
     El tono de contexto queda por debajo de 3:1 contra la superficie,
     así que toda barra lleva su valor escrito: eso no es adorno, es lo
     que la regla exige cuando el contraste no llega — y coincide con lo
     que pide la skill para «Compare Categories»: etiquetar categoría y
     valor directamente, y ordenar siempre descendente. */
  --viz-acento:var(--ember);
  --viz-col:var(--n-7);

  /* ── Escala tipografica: CINCO pasos, en rem ──────────────────────
     Antes habia quince tamanos, doce de ellos apretados en un rango de
     6,5px con razon media 1,045 — un escalon de medio pixel no es
     jerarquia, es invisible, y era la causa tipografica del reclamo
     original: si la diferencia entre estructura y contenido es 0,5px,
     el ojo no tiene donde engancharse. Ahora la razon es ~1,2 en los
     cuatro saltos, que es lo que usa una escala modular de verdad.

     En rem y no en px para respetar el tamano de letra que la persona
     configuro en su navegador o su sistema. El archivo tenia 65
     declaraciones en px y cero en rem: el zoom con pinza funcionaba,
     pero eso es un recurso del usuario, no soporte.

     Los nombres son de ROL y no de numero (--t-2) a proposito: quien
     edita elige por lo que la cosa ES, no por su lugar en una lista. */
  /* ── Las dos fuentes, y por que son dos ────────────────────────────
     Plus Jakarta Sans reemplaza a Inter. No es que Inter estuviera mal:
     es la fuente por defecto de todo, y este producto tiene que
     parecerse a si mismo. La entrada del dataset que la trae describe
     exactamente a Campo —«B2B SaaS apps, productivity tools, admin
     dashboards»— y viene con su escala de pesos ya resuelta.
     JetBrains Mono no es decorativa: sostiene las cifras y los
     micro-rotulos. Ver `.num` y `.rot` mas abajo. */
  --fuente:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,'SF Mono','Cascadia Mono','Segoe UI Mono',monospace;

  --t-meta:0.75rem;      /* 12px — paso 1: rotulos, conteos, letra chica */
  --t-body:0.9375rem;    /* 15px — paso 2: cuerpo, filas, controles */
  --t-sec:1.125rem;      /* 18px — paso 3: titulos de seccion, titulares */
  --t-titular:1.375rem;  /* 22px — paso 4: titulo de pantalla */
  --t-title:1.6875rem;   /* 27px — paso 5: la cifra grande */

  /* ── Ritmo vertical: interlineas en multiplos de 4px ───────────────
     Antes habia once interlineas distintas y una sola de seis cajas de
     linea caia en pixel entero (cuerpo 15x1,55=23,25px; nota
     12,5x1,55=19,375px; fila 14,5x1,55=22,475px). Cada bloque
     arrancaba en un desplazamiento fraccionario distinto. En rem, asi
     que el ritmo se mantiene si la persona agranda la letra base.
     Dos para el paso 1 porque la interlinea es funcion de la MEDIDA y
     no solo del tamano: un chip de una linea y un parrafo de cinco no
     quieren lo mismo. */
  --lh-0:1rem;      /* 16px — texto chico de una linea: chips, conteos */
  --lh-1:1.25rem;   /* 20px — texto chico corrido: notas, avisos */
  --lh-2:1.5rem;    /* 24px — cuerpo y titulos de seccion */
  --lh-3:1.75rem;   /* 28px — titulares */
  --lh-4:2rem;      /* 32px — la cifra grande */

  /* ── Escala de espaciado ───────────────────────────────────────────
     La escala existia desde antes y se usaba el 6% de las veces: 12
     declaraciones con var(--sp-*) contra 173 con px literal, en 22
     valores distintos que incluian 5, 7, 9, 11, 18, 22, 26 y 34. Todo
     el argumento de Carbon es que una escala fija saca la adivinanza
     del medio, y aca estaba declarada y esquivada.

     Nueve pasos sobre grilla de 2px, en rem para que acompanen a la
     escala tipografica: si alguien agranda la letra base, el aire
     crece con ella en vez de quedarse chico.

     El viejo --sp-7:44px salio de la escala. 44 es el OBJETIVO TACTIL,
     no un paso de espaciado — entraba por la puerta de atras y Carbon
     separa las dos cosas a proposito. Ahora es --tap, y lo usan los
     min-height; el margen de .sec pasa a --sp-8 (40px). */
  --sp-1:0.125rem;  /*  2px */
  --sp-2:0.25rem;   /*  4px */
  --sp-3:0.5rem;    /*  8px */
  --sp-4:0.75rem;   /* 12px */
  --sp-5:1rem;      /* 16px */
  --sp-6:1.5rem;    /* 24px */
  --sp-7:2rem;      /* 32px */
  --sp-8:2.5rem;    /* 40px */
  --sp-9:3rem;      /* 48px */
  --tap:44px;       /* objetivo tactil, NO un paso de espaciado */

  /* ── Escala de movimiento ──────────────────────────────────────────
     Habia catorce duraciones sueltas escritas a mano (.12s, .15s, .18s,
     .2s, .25s…) y ninguna decia por que. Tres pasos, elegidos por
     DISTANCIA recorrida, que es la variable que manda: un color que
     cambia en el lugar es instantaneo para el ojo; una hoja que sube
     media pantalla necesita tiempo para leerse como un movimiento y no
     como un salto.

       · --mov-1  el control responde al dedo (color, opacidad, escala)
       · --mov-2  algo aparece o cambia de estado en su lugar
       · --mov-3  algo recorre la pantalla (la hoja modal)

     La curva es la misma para todo lo que ENTRA: sale rapido y frena
     al final, que es como se mueve algo con masa. Lo que se va usa la
     inversa y mas corto — irse rapido no molesta, llegar de golpe si.
     El bloque `prefers-reduced-motion` de mas abajo las apaga todas. */
  --mov-1:110ms;
  --mov-2:200ms;
  --mov-3:300ms;
  --curva:cubic-bezier(.2,.8,.2,1);
  --curva-sale:cubic-bezier(.4,0,1,1);

  /* ── Sombras ───────────────────────────────────────────────────────
     Del archivo: `0 0 32px -4px rgba(208,210,218,.15)`. Es una sombra
     deliberadamente casi invisible, y esta bien que lo sea — en el Figma la
     tarjeta no se separa por sombra sino por SUPERFICIE: es blanca sobre una
     pagina gris. La sombra solo redondea el borde de esa diferencia.

     Restyling Notion (15/09): `--sombra-1` deja de usarse en tarjetas de
     contenido (.row, .hall.grande, .guion, .kpi, .tabla-wrap) — pasan a
     border:1px solid var(--line-soft), que es la regla de la referencia
     («sombras casi ausentes, sólo en elementos flotantes reales»). El
     token queda definido por si hace falta una superficie que sí flote
     sobre contenido (no hay ninguna hoy fuera de .sheet/.mtop-compacto,
     que usan --sombra-hoja y --sombra-2 respectivamente). */
  /* El velo del modal y la sombra de la hoja, por modo. En claro el velo
     oscurece; en oscuro tiene que oscurecer MAS, porque parte de un fondo
     que ya es oscuro y un 34% ahi no compone diferencia visible. */
  --velo:rgba(15,17,21,.42);
  --sombra-hoja:0 -8px 40px rgba(15,17,21,.18);
  --sombra-1:0 0 var(--sp-7) calc(-1 * var(--sp-2)) rgba(208,210,218,.55);
  --sombra-2:0 var(--sp-1) var(--sp-3) calc(-1 * var(--sp-1)) rgba(30,30,30,.10);

  /* ── Escala de radios ──────────────────────────────────────────────
     Antes habia CATORCE valores: 2,3,4,5,6,7,8,9,10,12,16,20,99 y 50%.
     Nada distingue visualmente 6px de 7px, asi que trece de esos
     valores eran decisiones que nadie podia ver. Cuatro pasos, mas la
     pildora y el circulo, que no son pasos de la escala sino formas.  */
  /* Escala achicada el 15/09 para el restyling Notion: «radios chicos,
     no burbujas». Y vuelta a achicar la misma noche, corrección de Alan
     sobre la muestra: el tipo de cliente de Campo (distribución
     mayorista de alimentos, trabajo de calle) pide contenedores más
     rectos y rígidos que el genérico «software prolijo» — Notion vive
     en un escritorio de oficina; esto vive en la vereda. Mismos cuatro
     escalones, un paso más chico cada uno: rozan el ángulo recto sin
     llegar a cortar (0px en un objetivo táctil de 44px se ve roto, no
     serio — por eso ninguno llega a 0). */
  --r-1:2px;      /* detalles, foco, barras de grafico */
  --r-2:4px;      /* controles y filas: boton, input, .row, .chip */
  --r-3:5px;      /* tarjetas y contenedores */
  --r-4:8px;      /* hojas y superficies grandes */
  --r-pill:999px; /* todo lo que ya queria ser pildora y lo pedia con 20px o 99px —
                     se queda redonda a propósito: es la forma de un valor/etiqueta
                     seleccionable, no de un contenedor, y esa distinción de forma
                     es la que separa pestaña de filtro en `.snav` vs `.fchip`. */

  --rail:232px;
  --tabbar:60px;
  --measure:680px;
  /* Alto de la barra superior de mobile. En desktop no existe, y el
     índice de pantalla se pega a 0. Se declara acá para que el
     scroll-margin de los destinos y el top del índice sean el mismo
     número y no dos constantes que se desincronizan. */
  --mtop:0px;
}

/* ═══════════════ MODO OSCURO ═══════════════════════════════════════════
   Un viajante que abre la app de noche recibia una pantalla crema a
   16,8:1 — una linterna. El archivo tenia `color-scheme: light` y cero
   `prefers-color-scheme` en 3.700 lineas: estaba apagado a proposito
   porque la paleta lleva cada ratio verificado en su comentario y
   hacerlo era rehacer esa verificacion, no invertir colores.

   Lo que lo hizo posible fue el grupo 3: los roles apuntan a posiciones
   de una rampa, asi que esto es reasignar y no re-derivar. Pero medirlo
   dejo claro que **espejar los indices no alcanza**, por dos motivos que
   valen mas que la lista de hexes:

   1. **`hover` cambia de direccion.** En claro es mas OSCURO que la
      superficie; en oscuro tiene que ser mas CLARO. Sobre fondo oscuro
      todo lo que se despega se despega hacia arriba, asi que las
      superficies se ordenan por ELEVACION —paper < hover < raise <
      media-bg < line-soft < line— y no copiando el ratio de su
      equivalente claro. Espejando indices, `raise` y `hover` caian en
      1,019:1 entre si: un hover invisible, que es un defecto funcional
      y no un redondeo.

   2. **El texto se calcula contra `--raise`, no contra `--paper`.** En
      claro la superficie elevada es mas clara y eso AYUDA al texto
      oscuro; en oscuro tambien es mas clara, y eso lo PERJUDICA.
      Apuntando a paper, `--muted-2` daba 4,81:1 ahi pero **4,00:1
      sobre raise**: fallaba justo adentro de las tarjetas. Se apunta al
      peor caso y sobra en el resto.

   Cada valor se genero resolviendo el contraste objetivo, no a ojo, y
   las 30 comprobaciones estan en `probar-contraste.js`. Los ratios
   contra --paper quedan al lado de cada token.

   `--ink` es `#f7f5f0`, que es literalmente el `--paper` del modo claro:
   el intercambio de verdad. No se usa blanco puro a proposito — sobre
   fondo oscuro produce halacion, y 16,43:1 ya es mas de lo necesario.

   **El interruptor manual no esta acá:** esto sigue al sistema operativo.
   Un control para forzar el tema es una preferencia del usuario y va
   donde van las preferencias, que es la pantalla de configuracion que
   todavia no existe — el cambio 20 del plan. */
/* El bloque de tokens oscuros aparece DOS veces, y tiene que ser identico en
   las dos: una bajo `prefers-color-scheme` para seguir al sistema, y otra bajo
   `[data-tema="oscuro"]` para cuando la persona elige. CSS no permite unir un
   selector de atributo con una media query en una sola regla, asi que la
   duplicacion es estructural y no un descuido — pero se verifica: hay una
   comprobacion en `probar-contraste.js` que falla si los dos bloques dejan de
   coincidir. Es la misma leccion de --mtop: si algo esta escrito dos veces,
   que lo compare una prueba y no la memoria de quien edita.

   `:not([data-tema="claro"])` es lo que deja que la eleccion manual gane
   sobre la preferencia del sistema en los dos sentidos. */
@media (prefers-color-scheme:dark){
  :root:not([data-tema="claro"]){
    /* Las tres superficies oscuras salen del archivo tal cual: #1e1e1e de
       fondo, #2e2e2e de panel y #333333 de tarjeta. La tarjeta sigue siendo
       mas clara que el fondo, igual que en claro. */
    --paper:var(--n-18);      /* #1e1e1e */
    --hover:var(--n-17);      /* #2e2e2e — 1.10:1 sobre paper */
    --zebra:var(--n-17);      /* 1.05:1 sobre raise — el mismo peso que en claro */
    --raise:var(--n-16);      /* #333333 — 1.21:1 */
    --media-bg:var(--n-14);   /* 1.55:1 */
    --line-soft:var(--n-13);  /* 1.75:1 */
    --line:var(--n-12);       /* 2.10:1 */

    /* texto: el objetivo es el ratio del modo claro contra --raise, que en
       oscuro es la superficie MAS clara y por lo tanto el peor caso */
    --ink:var(--n-0);         /* #fcfcff — 15.9:1 sobre paper */
    --ink-2:var(--n-3);       /* 10.5:1 sobre raise */
    --media:var(--n-6);       /*  6.6:1 */
    --muted:var(--n-7);       /*  5.5:1 */
    --muted-2:var(--n-8);     /*  4.8:1 */

    /* acentos: el azul se mantiene como relleno y rota para texto —esa
       es la regla del sistema, el acento rota y no se invierte */
    --ember-soft:#411c4a;     /* 1.18:1 sobre paper oscuro */
    --ember:#85259d;          /* blanco encima 7.64:1, igual en los dos modos */
    --ember-tx:#d398e1;       /* 5.62:1 sobre raise · 7.42:1 sobre paper */
    --ember-on-ink:#d398e1;
    --alerta-soft:#4a232f;
    --alerta:#e68ba7;         /* 5.2:1 */
    --alerta-tx:var(--alerta);
    --ojo-soft:#382e1b;
    --ojo-fill:#d99b1f;
    --ojo:#d59c26;            /* 6.8:1 sobre paper · 5.2:1 sobre raise */
    --ojo-tx:var(--ojo);
    --ok-soft:#18321f;
    --ok:#37be5c;             /* del #1ca842 del archivo, que con texto claro
                                 encima daba 3.1:1 — por debajo del AA que
                                 Campo exige. Mismo tono, 5.2:1 */
    --ok-tx:var(--ok);

    /* Velo mas denso y sombra de halo claro: sobre fondo oscuro una sombra
       negra no existe, igual que ya estaba resuelto para `--sombra-1`. */
    --velo:rgba(0,0,0,.62);
    --sombra-hoja:0 -8px 40px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.07);
    --viz-acento:var(--ember-tx);  /* ΔE ~46 contra --viz-col (CIE76), recalculado 15/09 (2), violeta */
    --viz-col:var(--n-9);
    --seq-1:#dbb3e6;
    --seq-2:#b24dcb;
    --seq-3:#5d156f;
  }
  /* Con el mismo guard que los tokens (23/09): sin él, con el sistema en
     oscuro y «Claro» elegido en Ajustes, el FAB se quedaba con la sombra negra
     del oscuro encima de un fondo claro. */
  :root:not([data-tema="claro"]) .fab{box-shadow:0 var(--sp-3) var(--sp-6) rgba(0,0,0,.5)}
  /* La sombra de tarjeta del archivo es un halo claro, no una sombra: sobre
     fondo oscuro una sombra negra no se ve. */
  :root:not([data-tema="claro"]){--sombra-1:0 0 var(--sp-4) 0 rgba(255,255,255,.06)}
}

:root[data-tema="oscuro"]{
    /* Las tres superficies oscuras salen del archivo tal cual: #1e1e1e de
       fondo, #2e2e2e de panel y #333333 de tarjeta. La tarjeta sigue siendo
       mas clara que el fondo, igual que en claro. */
    --paper:var(--n-18);      /* #1e1e1e */
    --hover:var(--n-17);      /* #2e2e2e — 1.10:1 sobre paper */
    --zebra:var(--n-17);      /* 1.05:1 sobre raise — el mismo peso que en claro */
    --raise:var(--n-16);      /* #333333 — 1.21:1 */
    --media-bg:var(--n-14);   /* 1.55:1 */
    --line-soft:var(--n-13);  /* 1.75:1 */
    --line:var(--n-12);       /* 2.10:1 */

    /* texto: el objetivo es el ratio del modo claro contra --raise, que en
       oscuro es la superficie MAS clara y por lo tanto el peor caso */
    --ink:var(--n-0);         /* #fcfcff — 15.9:1 sobre paper */
    --ink-2:var(--n-3);       /* 10.5:1 sobre raise */
    --media:var(--n-6);       /*  6.6:1 */
    --muted:var(--n-7);       /*  5.5:1 */
    --muted-2:var(--n-8);     /*  4.8:1 */

    /* acentos: el azul se mantiene como relleno y rota para texto —esa
       es la regla del sistema, el acento rota y no se invierte */
    --ember-soft:#411c4a;     /* 1.18:1 sobre paper oscuro */
    --ember:#85259d;          /* blanco encima 7.64:1, igual en los dos modos */
    --ember-tx:#d398e1;       /* 5.62:1 sobre raise · 7.42:1 sobre paper */
    --ember-on-ink:#d398e1;
    --alerta-soft:#4a232f;
    --alerta:#e68ba7;         /* 5.2:1 */
    --alerta-tx:var(--alerta);
    --ojo-soft:#382e1b;
    --ojo-fill:#d99b1f;
    --ojo:#d59c26;            /* 6.8:1 sobre paper · 5.2:1 sobre raise */
    --ojo-tx:var(--ojo);
    --ok-soft:#18321f;
    --ok:#37be5c;             /* del #1ca842 del archivo, que con texto claro
                                 encima daba 3.1:1 — por debajo del AA que
                                 Campo exige. Mismo tono, 5.2:1 */
    --ok-tx:var(--ok);

    /* Velo mas denso y sombra de halo claro: sobre fondo oscuro una sombra
       negra no existe, igual que ya estaba resuelto para `--sombra-1`. */
    --velo:rgba(0,0,0,.62);
    --sombra-hoja:0 -8px 40px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.07);
    --viz-acento:var(--ember-tx);  /* ΔE ~46 contra --viz-col (CIE76), recalculado 15/09 (2), violeta */
    --viz-col:var(--n-9);
    --seq-1:#dbb3e6;
    --seq-2:#b24dcb;
    --seq-3:#5d156f;
  --sombra-1:0 0 var(--sp-4) 0 rgba(255,255,255,.06);
}
:root[data-tema="oscuro"] .fab{box-shadow:0 var(--sp-3) var(--sp-6) rgba(0,0,0,.5)}

/* EL TEMA ELEGIDO TAMBIÉN MANDA SOBRE LO QUE PINTA EL NAVEGADOR (23/09).
   Los HTML declaran `<meta name="color-scheme" content="light dark">`, que
   le deja al navegador elegir según el sistema los controles nativos (el
   <select>, la barra de scroll, el autocompletado). Con el tema forzado desde
   Ajustes eso quedaba al revés: la página en claro con un <select> oscuro
   encima. La propiedad en :root le gana al meta.

   Van DESPUÉS del bloque oscuro a propósito: probar-contraste.js ubica ese
   bloque buscando la primera aparición de `:root[data-tema="oscuro"]{`. */
:root[data-tema="claro"]{color-scheme:light}
:root[data-tema="oscuro"]{color-scheme:dark}

