/* TOKENS DO LIGA — camada 0. UMA verdade por valor de marca.
 *
 * Intenção de design: `docs/design/intent.md`. Este arquivo é onde ela vira valor.
 *
 * Este arquivo não tem seletor além de `:root` — e desde 06/09/2026 tem também os
 * `@font-face`, que são at-rule e não seletor. Eles moram AQUI, e não numa folha
 * `base/fontes.css` própria, por um motivo medido: cada uma das ~88 páginas liga
 * suas folhas À MÃO no `<head>`, então uma folha nova custaria 88 edições, e o
 * `tokens.css` já é a PRIMEIRA folha de todas elas. Um arquivo em vez de 88 é
 * também o que o §D0 do intent.md pede: uma verdade, num lugar.
 * (Isto não reabre a regra abaixo: at-rule de fonte não é seletor, e nenhum dos
 * dois testes de faixa C olha para `@font-face`.)
 *
 * O que o mantém FORA do `tests/test_css_tablet_e_isa101.py` (faixa C). Aquele teste faz
 * `rglob("*.css")` e cobra `@media (pointer:coarse)` de toda folha que mencione
 * button/input/select/textarea, e proíbe `max-width` em seletor terminado em
 * `-wrap`. Folha só de token não dispara nenhuma das duas — então acrescentar
 * token aqui nunca abre um PR de faixa C.
 *
 * 🔴 ORDEM IMPORTA: carregar SEMPRE antes de `/static/style.css`.
 * Este arquivo é ADITIVO. Para todo nome que o `style.css` também declara, o
 * `style.css` VENCE por ordem de cascata (mesma especificidade, `:root` nos
 * dois) — então a seção 1 abaixo é hoje inerte, e a entrada desta folha repinta
 * ZERO pixel. É essa propriedade que permitiu criar a camada base sem tocar um
 * byte de `style.css`, que é faixa A e tem 576 usos de `var()`.
 * No dia em que o `:root` do `style.css` encolher, a ordem passa a ser
 * carregadora. Há teste: `tests/test_tokens_uma_verdade.py`.
 */
/* ═══ 0. AS FONTES ════════════════════════════════════════════════════════════
   🔴 ANTES DE 06/09/2026 A PLATAFORMA INTEIRA RODAVA EM system-ui, E NINGUÉM
   TINHA DECIDIDO ISSO. Não havia `@font-face` nenhum e nem pasta de fontes: o
   `--font-sans:'Archivo', system-ui…` do `style.css` nunca teve Archivo para
   carregar, então TODA tela caía no fallback — Segoe UI no Windows, SF no Mac.
   E o `sapucaia-core.css` especifica tracking de até −0,045em, desenhado PARA
   Archivo, aplicado a Segoe UI. Era essa a origem do "genérico, sem acabamento".

   A fonte é Inter, decisão do Juan em 06/09/2026: é a fonte do Espresso, e o
   Espresso é a gramática adotada (`docs/design/intent.md` §D1). Archivo continua
   sendo a fonte da MARCA fora do produto — site, deck, capa de documento do SGQ,
   impresso — onde o `sapucaia-core.css` manda. Aqui dentro, a voz é Inter.

   Variável (um arquivo cobre 100–900) porque o intent.md §D1 pede peso 420 no
   corpo, e 420 só existe em fonte variável. Custo medido: 133 KB de Inter e
   56 KB de JetBrains Mono, os quatro arquivos somando 189 KB — servidos da LAN,
   não de CDN (a fábrica é offline, e há teste provando que nenhuma folha importa
   da internet).

   `font-display: swap`: o texto aparece imediatamente na fonte de sistema e
   troca quando a Inter chega. O oposto (`block`) daria tela em branco por até
   3 s no tablete — inaceitável em §4, onde o retorno visual tem de vir em
   menos de 100 ms.

   ⚠ `unicode-range` NÃO é enfeite: sem ele o navegador baixa os dois arquivos
   de cada família mesmo numa tela que só tem português. Com ele, `latin-ext`
   (85 KB) só desce se a página tiver um caractere que o exija — e o português
   cabe inteiro em `latin`.
   Procedência e sha256: `web/static/vendor/LEIAME.md`. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/static/vendor/fontes/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/static/vendor/fontes/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/static/vendor/fontes/jetbrainsmono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/static/vendor/fontes/jetbrainsmono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* ═══ 1. Cópia VERBATIM do `:root` de `style.css` ═══════════════════════
     Copiada por VALOR de propósito: enquanto o `style.css` também os declarar,
     esta seção não faz nada, e o teste de divergência prova que os dois batem.
     Os comentários que explicam POR QUE cada valor é esse (contraste WCAG do
     `--ink-500`, o vermelho reservado ao anormal do ISA-101, o par texto/fundo
     dos estados) ficam no `style.css`, que continua sendo a origem. */
  --red-500: #EE1C25; --red-600: #D01820; --red-wash: #FEECEE;
  --ink-800: #231F20; --ink-600: #5A5458; --ink-500: #5A6870; --ink-100: #E6EAED;
  --page: #F5F6F7; --surface: #FFFFFF; --divider: #E6EAED; --divider-soft: #F0F2F4;
  --success: #1E7A3E; --success-600: #186531; --warning: #B85A0C;
  --ocupado: #5A6675; --ocupado-tinta: #FFFFFF;
  --ok-txt: #1E7A3E; --aviso-txt: #B8860B; --alarme-txt: #C0161D; --semcomm-txt: #6B7B84;
  --aviso-bg: #FEF3C7;
  /* ⚠ Mudou em 06/09/2026 (Archivo → Inter). Como esta seção é cópia verbatim e
     `test_tokens_uma_verdade.py` prova que os dois batem, os DOIS mudam juntos —
     é o §D0 em ação: o valor antigo sai no mesmo commit em que o novo entra. */
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --r-xs: 6px; --r-sm: 10px;
  --r-md: 14px; --r-lg: 18px; --r-xl: 24px; --pill: 999px;
  --shadow-sm: 0 1px 3px rgba(35,31,32,.08), 0 1px 2px rgba(35,31,32,.04);
  --shadow-md: 0 4px 12px rgba(35,31,32,.08);

  /* ⚠ `--pad-tela` e `--rail-w` NÃO entram aqui, e não é esquecimento:
     `test_css_tablet_e_isa101.py` (faixa C) afirma `--pad-tela` DENTRO do
     `style.css`, e os dois são layout do SCADA, redefinidos em 3 media queries
     de lá. Duplicá-los aqui criaria a segunda verdade que esta folha existe
     para apagar. */

  /* ═══ 2. A ESCADA DE ESPAÇAMENTO ═════════════════════════════════════════
     Usada 81 vezes no produto e declarada em lugar NENHUM até hoje: todo uso é
     `var(--s-3, 12px)`, sempre caindo no fallback. O sistema de espaçamento
     existia na cabeça de quem escreveu e em nenhum lugar do código.

     🔴 ESTA É A ESCADA DO PRODUTO, NÃO A DO CANVAS.
     `docs/sgi/design-system/liga.css` declara `--s-3: 8px`; os 49 usos no
     produto carregam `var(--s-3, 12px)`. A escala do canvas está deslocada um
     degrau INTEIRO. Adotá-la encolheria ~33% do espaçamento de
     `modulos/laboratorio/` (os únicos CSS que usam `--s-*`) — sem erro, sem
     teste e sem ninguém pedir. Quem muda é o canvas.

     Medidos no fallback: s-2=8 · s-3=12 · s-4=16 · s-5=20 (passo de 4px).
     Os degraus 1/6/7/8 estendem o MESMO passo e ainda não têm uso — entram
     porque uma escada com buracos faz a próxima tela inventar o degrau que
     falta, que é exatamente como nascem os 194 hex distintos de hoje. */
  --s-1: 4px;  --s-2: 8px;   --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px;  --s-7: 32px; --s-8: 40px;

  /* ═══ 3. APELIDOS, com o valor que o fallback já produzia ════════════════
     Cada um é usado UMA vez, sempre com o mesmo fallback — declarar não muda
     pixel nenhum. Existem porque a tela pediu um nome que o sistema não tinha. */
  --brand: var(--red-500);          /* style.css:1145 */
  --ink-400: var(--ink-500);        /* rh */
  --ink-700: var(--ink-800);        /* sgi/evolucao-mensal */
  --ink-900: var(--ink-800);        /* laboratorio */
  --ink-2: #6B7B84;                 /* style.css:299 */
  --surface-muted: var(--divider-soft);
  --warn-txt: #B45309;              /* 3 usos, fallback unânime */
  --warn-500: #B45309;              /* 3 usos, fallback unânime */

  /* ═══ FUNDO DE SUCESSO ═══════════════════════════════════════════════════
     🔴 Decidido pelo Juan em 06/09/2026, e era DEFEITO, não estética.
     `--ok-bg` tinha 7 usos e QUATRO valores. Em chamados, compras,
     flow/precos e pessoas ele caía em `var(--aviso-bg)` = #FEF3C7, que é o
     CREME DE AVISO: a faixa de SUCESSO daquelas quatro telas saía com a cor de
     problema. Quem grava e vê creme não sabe se deu certo — e §3 diz que cor
     tem significado, nunca enfeite.
     O valor é o par claro de `--ok-txt` (#1E7A3E), que já era verde. O
     laboratório usava #E7F6EC, a um dígito daqui. */
  --ok-bg: #E7F5EC;

  /* ═══ 4. O QUE NÃO ENTRA, E POR QUÊ ══════════════════════════════════════
     Três nomes são usados com fallbacks DIVERGENTES. Declará-los aqui não é
     "preencher uma lacuna": é ESCOLHER por 7 telas de uma vez, mudando a cor de
     algumas. Isso é decisão de produto (CLAUDE.md §5, "duas lógicas que se
     sobrepõem: pare e pergunte"), não conserto de fundação. Ficam de fora até a
     resposta, e o teste da catraca os guarda nominalmente:

       --surface-2 · 7 usos, CINCO valores (page / surface / divider /
                     divider-soft / rgba(0,0,0,.03)). É o fundo de :hover de
                     lista — todos quase-brancos, todos diferentes.
       --info      · 4 usos, DOIS azuis: #1F5A9E (flow, 3×) e #1E5F8A (sgi, 1×).

     E dois NÃO são tokens de design: `--pn-pct` e `--rs-pct` são entrada de
     runtime, escritas por `style.setProperty()` em painel/sequencia-decapagem e
     sgi/sgi.js. O fallback delas é o estado inicial, e é onde tem de ficar. */

  /* ═══ 5. A ESCALA DE TIPO ════════════════════════════════════════════════
     Onda 2 do `docs/design/intent.md` (§D1). ADITIVA: nenhuma folha consome
     ainda, então declarar isto repinta ZERO pixel. Os consumidores chegam na
     onda 3, tela por tela, sob a regra D0 (o valor velho sai junto).

     🔴 O PROBLEMA QUE ELA RESOLVE, MEDIDO EM 06/09/2026:
     o produto tem **112 valores distintos de `font-size`**. Só em px são 26
     degraus, de 9 a 30, de meio em meio — 9 · 9,5 · 10 · 10,5 · 11 · 11,5 · 12
     · 12,5 · 13 · 13,5 · 14 · 14,5 · 15 · 15,5 · 16 · 17 … Isso não é escala, é
     deslizador. E vêm em QUATRO unidades misturadas (px, rem, `pt`, em) mais
     `clamp`. Ninguém decidiu 112 tamanhos: foram ~15 decisões e ~97 sobras,
     porque sem escada cada tela inventa o degrau que falta.

     Os valores são os do Espresso, VERBATIM (licença MIT/CC BY permite copiar
     valor, não só ideia — ver `vendor/LEIAME.md`).

     ⚠ UMA DIVERGÊNCIA DELIBERADA DO ESPRESSO, e ela é de forma, não de valor:
     o Espresso publica `text-*` e `text-p-*` como escadas SEPARADAS, com os
     mesmos px e line-height diferente. Isso existe porque lá cada uma vira uma
     classe do Tailwind. Aqui não há Tailwind: duplicar 5 tamanhos só para mudar
     entrelinha criaria cinco pares de nomes com o mesmo número — a segunda
     verdade que o §D0 proíbe. Então é UMA escada de tamanho e DUAS entrelinhas,
     combinadas no uso: `font-size: var(--t-base); line-height: var(--lh-p)`. */
  --t-2xs: 11px;  --t-xs:  12px;  --t-sm:  13px;  --t-base: 14px;
  --t-lg:  16px;  --t-xl:  17px;  --t-2xl: 18px;  --t-3xl:  20px;
  /* Faixa de display: título de tela e número de indicador. O produto já usa
     21/22/23/24/26/28/30px hoje; estes três degraus cobrem a faixa inteira.
     ⚠ A zona de Painel (TV) NÃO usa estes: ela escala por viewport com `clamp`,
     e ganha escada própria quando o segundo módulo de TV existir (intent.md §6). */
  --t-4xl: 24px;  --t-5xl: 28px;  --t-6xl: 32px;

  /* Entrelinha: 1.15 para o que ocupa UMA linha (rótulo, célula, botão, título);
     1.5 para o que quebra em várias (parágrafo, descrição, mensagem de erro).
     Rótulo com 1.5 desalinha o baseline dentro de uma linha de tabela; parágrafo
     com 1.15 fica ilegível. É a única razão de existirem dois. */
  --lh-ui: 1.15;  --lh-p: 1.5;

  /* Quatro pesos, e só. O 420 é o "regular" do Inter em interface — 400 puro
     afina demais sobre fundo claro — e SÓ existe porque a fonte é variável.
     ⚠ Se algum dia a Inter variável for trocada por estáticas, o 420 cai para
     400 e este comentário tem de cair junto (§D0). */
  --w-regular: 420;  --w-medium: 500;  --w-semibold: 600;  --w-bold: 700;

  /* ═══ 6. A RAMPA CATEGÓRICA ══════════════════════════════════════════════
     Onda 3 do `docs/design/intent.md` (§D3/§D11).

     🔴 O QUE ESTES DOIS PARES SÃO, E POR QUE NÃO SÃO "COR DE ESTADO":
     categoria é `o QUE é` — beneficiamento, retrabalho externo, amostra.
     Estado é `como está` — bom, atenção, ruim. Verde/âmbar/vermelho estão
     RESERVADOS ao estado (§D11 e §A1: vermelho é do anormal), então categoria
     precisa de hues próprios, e sobram poucos: azul e violeta.

     ⚠ COMO ELES CHEGARAM AQUI, escrito porque a origem importa: eram
     `#6D28D9` e `#1D4ED8` soltos em pcp.css, retrabalho.css, sgi.css e
     painel.css — violet-700 e blue-700 da **paleta do Tailwind**, que vieram
     junto com as telas repatriadas do SGI (React/Tailwind). A auditoria de
     06/09/2026 achou 18 cores dela, 63 usos. A regra "componente não
     atravessa" (CLAUDE.md §10) tinha sido violada numa camada em que ninguém
     olhava.

     O primeiro rascunho do §D3 mandava esses valores SAÍREM. Olhar o USO, e
     não só o valor, mostrou que eles codificam distinção real e estável — e
     que já seguem, sem saber, o desenho do Espresso: um membro escuro para o
     tema claro e um par claro para o escuro. Então não saem: **viram token,
     com valor decidido em vez de herdado.**

     Os valores ficam os mesmos NESTA onda, de propósito: o ganho aqui é uma
     verdade por fato, não repintar tela. Trocar os hues é decisão de produto e
     está em aberto no §6 do intent.md — quando for tomada, muda AQUI e em
     lugar nenhum mais, que é o ponto de existir este bloco.

     ⚠ O `-par` NÃO é trocado aqui por um `body[data-theme="dark"]`, e a razão
     é a catraca: esta folha não pode ganhar seletor (é o que a mantém fora da
     faixa C — ver `test_tokens_css_nao_tem_seletor…`). Quem faz a troca é a
     folha do módulo, no `body[data-theme="dark"]` que ela JÁ tem hoje para
     essas mesmas classes. A folha do módulo passa a escrever
     `var(--cat-2-par)` onde escrevia `#C4B5FD`, e mais nada muda de estrutura. */
  --cat-1: #1D4ED8;  --cat-1-par: #93C5FD;  /* azul    — beneficiamento · amostra · KPI info */
  --cat-2: #6D28D9;  --cat-2-par: #C4B5FD;  /* violeta — retrabalho externo */
  /* 🔴 O TERCEIRO ENTROU EM 16/09/2026, escolhido pelo Juan, e ele existe por
     uma medição: a nota fiscal dividida por tratamento usa no máximo TRÊS
     tratamentos (107 notas multi em 12 meses, máximo 3, nunca mais), e cada
     grupo precisa de uma cor para o olho achar a fronteira sem ler.
     Teal e não verde/âmbar/vermelho: os três são cor de ESTADO, e foi
     exatamente esse o erro que as cinco fases do PCP cometeram até 06/09 —
     a fase 3 parecia alarme e a fase 2 parecia aprovação. Contraste 5,47:1
     sobre branco, na mesma faixa dos dois acima (6,70 e 7,10). */
  --cat-3: #0F766E;  --cat-3-par: #5EEAD4;  /* teal    — 2º tratamento na nota (Flow, desde 01/10/2026) */

  /* ═══ 7. A RAMPA SEQUENCIAL ══════════════════════════════════════════════
     🔴 DUAS RAMPAS PORQUE SÃO DOIS TIPOS DE DADO, e confundi-los é erro de
     gramática, não de gosto:
       categórica  → coisas SEM relação entre si. Beneficiamento não vem
                     "depois" de retrabalho; são espécies diferentes.
       sequencial  → UMA coisa em vários pontos de avanço. Um hue, várias
                     forças. É o que o Espresso chama de "sequential", e é o
                     padrão dele para eixo e mapa de calor.

     As cinco fases do PCP são 1-Decapagem → 2-Revestimento → 3-Inspeção visual
     → 4-Expedição → 5-Faturamento. Uma OS **atravessa** as cinco, em ordem: é
     progressão, não taxonomia. Até 06/09/2026 elas usavam cinco hues sem
     relação (azul, verde-mar, rosa, âmbar, violeta) — o que dizia ao olho
     "cinco coisas diferentes" quando a verdade é "uma coisa em cinco pontos".
     E três daqueles hues eram cor de ESTADO, então a fase 3 parecia alarme e a
     fase 2 parecia aprovação, sem significar nem uma coisa nem outra.

     ⚠ E A RAMPA NÃO VAI NO TEXTO — foi medindo que isso apareceu. O
     `.pp-fase-titulo` é 13,5px/700, o que NÃO é "texto grande" no WCAG e exige
     4,5:1. Cinco azuis que todos batam 4,5:1 sobre fundo quase-branco não
     cabem: a busca convergiu os degraus 4 e 5 para a MESMA cor. O contraste
     varia devagar demais na ponta clara.
     A saída não foi espremer mais: foi ver que a cor estava na camada errada.
     O título volta a ser `--ink-800` (10,7:1 a 15,1:1 no claro, 6,1:1 a 9,4:1
     no escuro — folga enorme, e quase-preto lê melhor que colorido a 13,5px),
     e a rampa vai para o PREENCHIMENTO do card, que é decorativo e não tem
     trava de 4,5:1. A cor ali nunca foi informação: o card já escreve
     "1 - Decapagem".

     UM token, cinco forças aplicadas por `color-mix` no `pcp.css`:
       fundo  5 · 10 · 15 · 20 · 26 %      (separação medida: 1,08–1,13)
       borda 22 · 32 · 42 · 52 · 62 %
     Azul porque é o default de rampa sequencial do Espresso, e porque
     verde/âmbar/vermelho estão reservados ao estado (§D11, §A1).

     `--seq-noite` é o par do tema escuro. A troca NÃO é feita aqui — esta folha
     não pode ganhar seletor (`test_tokens_css_nao_tem_seletor…`): quem troca é
     o `pcp.css`, em UMA linha no contêiner. */
  --seq: #1D4ED8;  --seq-noite: #93C5FD;
  /* ═══ 9. A CAMADA DENSA — o que o artboard de 07/09/2026 pediu ═════════════
     Catorze tokens, e a lista saiu de MEDIÇÃO: o artboard
     `Liga SGQ Calibracao.html` usa 36 tokens, o produto já declarava 27, e
     estes são os que faltavam mais os que as regras de componente portadas
     arrastam junto (`--alvo`, `--linha`, `--foco`, `--scrim`).

     🔴 O VALOR VEM DO `sapucaia-core.css`, QUE É A MARCA — e escrever isto
     custou uma reprovação de teste. A primeira versão desta seção tirou os
     valores do `liga.css`, que é a camada de APLICAÇÃO do canvas e tem rampa
     própria: de lá, `--ink-50` era #FAFAFA, `--ink-200` #E9E9EB e `--ink-300`
     #D6D6D9 — cinzas neutros que NÃO fazem escada com o `--ink-100` #E6EAED
     que o produto já tinha. Cheguei a documentar a não-monotonia como se fosse
     um fato da marca. Não era: era eu lendo o arquivo errado.
     `test_a_marca_nao_ganha_uma_divergencia_NOVA_em_silencio` reprovou os oito
     de uma vez. A marca é azulada e monotônica, e agora bate:
         --ink-50 #F3F5F7 · --ink-100 #E6EAED · --ink-200 #D3D9DD
         --ink-300 #B3BDC4 · --ink-500 #5A6870 · --ink-800 #231F20

     ⚠ DOIS NOMES DO CANVAS NÃO VIRARAM VALOR NOVO, e é de propósito — o
     produto já os tinha com outro nome, e repetir o hex seria a segunda
     verdade que aquele teste existe para impedir:
       --warning-wash → é EXATAMENTE o `--aviso-bg` (#FEF3C7 nos dois);
       --success-wash → a marca diz #E8F4EC e o produto diz #E7F5EC. Distância
                        2/765, invisível. Não entra como token: onde o canvas
                        o usava, o `sgq.css` escreve `var(--ok-bg)`. Declará-lo
                        com o valor da marca criaria dois verdes de estado a 2
                        de distância; com o nosso, uma divergência de marca.
       --surface-2    → também NÃO entra, e por outro motivo: está em
                        `_AGUARDANDO_DECISAO` no teste, com 5 fallbacks
                        divergentes em uso. Declará-lo escolhe por várias telas
                        de uma vez, e isso é decisão de produto (§5 "pare e
                        pergunte"), não conserto de fundação. Onde o canvas o
                        usava — o fundo do `.painel-pe` — o `sgq.css` escreve
                        `var(--ink-50)`. A decisão fica em aberto sem travar a
                        tela.

     ⚠ E `--sunken` vale #F0F2F4, o mesmo que `--divider-soft`. Não é
     duplicação nossa: os dois valem isso NA MARCA, e são papéis diferentes
     (rebaixo de fundo × traço de divisória). Se um dia divergirem, divergem
     lá. */
  --ink-50:  #F3F5F7;   /* fundo de hover e de trilha */
  --ink-200: #D3D9DD;   /* ponto da linha do tempo, anel do radio */
  --ink-300: #B3BDC4;   /* placeholder e traço do ícone de busca */
  --sunken:  #F0F2F4;   /* rebaixo: cabeçalho de grupo, bloco de anexo */
  --info-wash: #E9F1F7;
  --warning-wash: var(--aviso-bg);
  --red-700:   #B4151C;   /* texto sobre `--red-wash`; a rampa tinha 500 e 600 */
  --red-line:  #F0C4C6;   /* divisória DENTRO da linha selecionada */
  --shadow-xs: 0 1px 2px rgba(21, 20, 20, .05);
  --scrim:     rgba(21, 20, 20, .55);   /* o véu do modal */

  /* Métrica da tela densa — a marca não declara nenhuma das quatro, então
     aqui não há divergência possível: elas nascem no produto. `--alvo` é 36px
     porque é a altura de controle do artboard de desktop, e o §3 do CLAUDE.md
     continua valendo: quem sobe para 44px sob `@media (pointer:coarse)` é a
     folha do módulo, que PODE ter seletor. Esta não pode
     (`test_tokens_css_nao_tem_seletor…`). */
  --alvo:  36px;   /* altura de botão e de campo */
  --linha: 30px;   /* altura de linha de tabela densa */
  --topo:  52px;   /* altura do cabeçalho — o deslocamento do `thead` grudado */
  /* Texto sobre preenchimento SÓLIDO de cor — botão primário, selo de alarme
     cheio, o disco do veredito. Não é `--surface`: aquele é o fundo do cartão,
     e no tema escuro vira #343A43, o que apagaria o rótulo do botão vermelho.
     Este é branco nos dois temas, porque o fundo por baixo dele é a COR, e a
     cor não inverte. */
  --tinta-cheia: #FFFFFF;
  /* ⚠ NÃO ENTROU um `--radius-btn: 7px`, e o quase-erro merece registro. O
     `liga.css` dá 7px ao botão, e eu cheguei a declarar o token. Medido depois
     contra a MARCA (`sapucaia-core.css`): a escala de raio dela é
     6 · 10 · 14 · 18 · 24 · pílula — exatamente a do produto, exatamente o que
     o D4 do `docs/design/intent.md` diz que não muda. Os 7px eram invenção da
     camada de aplicação do canvas, não da marca. O botão usa `--r-xs`. */
  --foco: 0 0 0 2px var(--surface), 0 0 0 4px var(--red-500);
}
