# SEED engenharia — Design Tokens v1.23

> ⚠ **ERRATA DE CABEÇALHO, declarada em 2026-08-20.** Esta linha dizia **v1.17** enquanto os gêmeos
> (`seed-tokens.json` + `seed-tokens.css`) já estavam em **v1.19** — o cabeçalho do CSS até registra a
> defasagem por escrito (*"este cabecalho dizia v1.17 depois de a v1.18 ter nascido"*), mas a correção
> nunca chegou aqui. **Três versões de atraso num H1 de arquivo canônico.** Corrigido junto com a
> **v1.20**, que nasce `--seed-font-expressive`.
> *Por que isso vale registro e não só conserto: número de versão em cabeçalho é a primeira coisa que
> alguém lê para decidir se o arquivo está atual. Cabeçalho atrasado faz um documento correto parecer
> velho — e um documento velho parecer correto.*

> **Arquivo canônico da camada de tokens.** Primeira entrega (Fase 1) do rebranding do design system SEED iniciado em julho/2026. Este documento é a fonte de verdade conceitual; os valores executáveis vivem em dois arquivos gêmeos gerados juntos: `seed-tokens.json` (formato DTCG/W3C, para ferramentas e agentes) e `seed-tokens.css` (CSS custom properties, para web). Os três arquivos formam uma unidade: alterar um exige alterar os três.
>
> **Quem consome:** o site público do DS (Lovable), o ERP SEED, o sistema de chat, o site institucional, as skills `seed-ds-*` do Claude, e qualquer sistema futuro. Componentes e peças NUNCA usam hex direto: consomem tokens semânticos; tokens semânticos consomem primitivos.
>
> **Contexto para leitor novo:** a SEED engenharia é um HUB de engenharia elétrica (ES/MG/BA, desde 2016). A paleta de marca (8 cores, definida no rebrand de 2018 e mantida) não mudou neste trabalho — o que este arquivo faz é transformá-la de "lista de 8 hex" em sistema de 3 camadas capaz de servir produto digital, dark mode, dataviz e acessibilidade WCAG 2.2 AA. Identidade visual geral: `marca-seed.md` (v5.0 em produção). Institucional: `sobreaseed.md`.
>
> **Data:** 2026-07-30 · **Editado:** 2026-08-25 (v1.22 — **a SEGUNDA leva da camada 3 entra nos gêmeos, e a classe ganha INSTRUMENTO**: 19 tokens de botão, cartão, divisor, lista, item destrutivo de menu e espera, todos nomes que o `seed-componentes.md` já usava e o gêmeo não definia. A diferença de método em relação à v1.21 é que a lacuna deixou de ser procurada por `grep` e passou a ser medida pela guarda `guarda-spec-gemeo.py` (contrato **SG1**), que varre os canônicos e reprova todo custom property nomeado no canon e ausente do gêmeo — placar dela: **121 PASS · 29 FAIL → 140 PASS · 10 FAIL**. Dos 29 acusados, 19 tinham origem de valor declarada e foram emitidos; **10 não se emite**, e a lista com o motivo de cada um está na entrada v1.22 do §9 — inclusive três nomes que o canon cita apenas para registrar um defeito, um descarte ou um exemplo de diagrama. Anterior: v1.21 — **nasce a PRIMEIRA CAMADA 3 (componente) dos gêmeos, fechando a AD-P6**: os 21 tokens `--seed-field-*` do form-field, especificados e medidos na §2.5 do `seed-componentes.md` desde 2026-08-02 e até hoje ausentes dos gêmeos — a spec citava `seed-field-` 116 vezes, os gêmeos tinham ZERO, e o ERP consome exatamente essa camada. Adição pura (nenhum valor anterior muda), hex resolvido dos aliases da §2.5, gate **G5** novo na `paridade-tokens.py` (fidelidade alias→valor + espelho `prefers-color-scheme` conferido pela primeira vez); placar 85·0. Detalhe na fronteira do §6; v1.17 — **a MARCA QUE CARREGA TEXTO desce um degrau**: o gate visual do Rafael vetou a tinta escura sobre a marca e pediu texto branco; com o branco fixado, a superfície passa a ser turquesa-600 `#098475` (4,60) e nascem `surface-brand-strong` e `text-on-brand-strong` — estado vigente no **§5-d**, que supersede metade do §5-b. A marca chapada `#11B0A0` segue a âncora, reservada para área sem texto; v1.16 — **a TINTA DO BOTÃO DESTRUTIVO**, que fecha a **AD-P1**: o destrutivo clareia no tema escuro e a tinta continuava branca, medindo 2,71→2,76 contra piso 4,50; nasce `text-on-action-destructive`, branca no claro e vermelho-900 no escuro, com o RITO de três rodadas registrado no **§5-c**; v1.15 — **as TRÊS TINTAS DE MARCA**, que fecham a **MR-P1** e a **MR-P2**: um único token de tinta servia três fundos de marca com necessidades opostas e errava dois deles, um em cada tema; agora são `text-on-brand` (escura, sobre a marca chapada), `text-on-brand-deep` (branca) e `text-on-action-primary` (inverte) — estado vigente no **§5-b**, com errata dupla no §5; v1.14 — **`surface-brand-subtle`**, que fechou o BT-P6 na causa, mais a primeira errata do "3,22"; v1.13 — **`row-selected-*`**: o realce de linha selecionada ganha dono no canônico, fechando uma lacuna que a bancada `banco-dados.html` já vivia com definição local; adição pura, três tokens, quatro guardas novas na paridade; v1.12 — **`border-interactive` fecha a SH-P1/PN-P5**, promoção medida do empréstimo declarado do shell; v1.11 — **semânticos de COMPOSIÇÃO E CHROME do CP-P3**: `rail-background` gradiente CP20, dois overlays de chrome do SUP-6, paleta de entidade `entity-1…6`+tinta do CP23 e `marker-now` do CP24 — todos invariantes de tema, todos medidos, inclusive em composição; histórico completo no §9, com a restauração retroativa das entradas v1.7–v1.10 que faltavam na tabela) · **Autoria:** Claude + Rafael (decisões aprovadas em conversa de projeto)

---

## 1. Arquitetura em 3 camadas

Padrão da indústria (Carbon, Polaris, Atlassian), com dependência estritamente unidirecional:

```
1. PRIMITIVOS   --seed-turquesa-400        valor bruto, sem opinião de uso
       ↓ (referenciados por)
2. SEMÂNTICOS   --seed-action-primary      intenção de uso; é AQUI que light/dark trocam
       ↓ (referenciados por)
3. COMPONENTE   --seed-button-primary-bg   exceção local, definida junto de cada componente
```

Regras invioláveis:
- **Componentes consomem semânticos**, nunca primitivos, nunca hex.
- **Referência reversa é proibida** (primitivo não aponta pra semântico) — quebra o build e o raciocínio.
- **A camada 3 só nasce quando um componente precisa divergir do semântico.** Ela será criada componente a componente na Fase 3; este arquivo entrega as camadas 1 e 2 completas.
- **Só se tematiza o que precisa de tema:** cor, sombra, foco. Spacing, tipografia e radius são invariantes entre light/dark.

## 2. Camada 1 — Primitivos

### 2.1 Rampas tonais (o coração da entrega)

Cada cor de marca virou uma rampa de 10 stops (50→900). Método, para auditoria e regeneração futura:

- **Espaço de cor OKLCH** (perceptualmente uniforme): garante que "400" tenha o mesmo peso visual em qualquer rampa.
- **Curva de luminosidade compartilhada** entre todas as rampas (L 0.972 no stop 50 → 0.294 no 900), com chroma em sino (pico no meio, dessaturando nas pontas).
- **Âncora automática:** cada hex canônico de marca foi cravado EXATO (sem alteração de um dígito) no stop cuja luminosidade da curva é a mais próxima da sua luminosidade real. Os demais stops são interpolados.
- **Calibração funcional:** o stop 600 de cada rampa foi verificado (e ajustado quando preciso) para contraste ≥ 4.5:1 com branco — é o stop que serve botões e texto funcional.
- **Monotonicidade verificada:** luminosidade estritamente decrescente em todas as rampas (a v1 do algoritmo produzia inversões; corrigido).

| Rampa | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 |
|---|---|---|---|---|---|---|---|---|---|---|
| turquesa | #E8FBF7 | #CDF3EC | #9CE4D8 | #66D1C2 | **#11B0A0** ⚓ | #00A192 | **#098475** ⚓ | #006C62 | #005048 | #00352F |
| amarelo | #FFF6D2 | #FDEA9E | **#FAD61D** ⚓ | #DABA00 | #BDA100 | #A28A00 | #877200 | #6D5C00 | #504300 | #352C00 |
| dourado | #FFF4E4 | #FFE6C0 | #FECA76 | **#F9B11C** ⚓ | #D49400 | #B67F00 | #986900 | #7B5500 | #5B3E00 | #3D2800 |
| azul | **#ECF4FC** ⚓ | #CDF1FF | #96E0FD | **#53C2E9** ⚓ | #01B3E0 | #0099C1 | #007FA1 | #006783 | #004C61 | #003241 |
| cinza | #F2F6F9 | #E3EBF0 | #C8D6DF | #ACBECA | #90A6B3 | #788F9D | **#617683** ⚓ | #4D606C | #38464F | #242E34 |
| vermelho | #FFF2F1 | #FFE2DF | #FFC2BD | #FF9C95 | #FC6F6A | **#D94545** ⚓ | #C6393B | #A5272A | #7A1C1E | #521112 |

⚓ = hex canônico de marca, preservado exato. Pantones (do Manual 2018, confirmados): Turquesa 3275C · Amarelo 115C · Verde 327C · Cinza 5487C · Dourado 7409C · Azul 2985C · Azul-claro 656C. CMYK no `marca-seed.md`.

### 2.2 Três descobertas estruturais (fatos, não opiniões — medidos em OKLCH)

1. **O verde institucional #098475 É o turquesa-600.** As duas cores "diferentes" da marca são a mesma rampa em stops diferentes — e o 600 é exatamente o stop de ação acessível (4.60:1 com branco). Consequência: **o botão primário da SEED em fundo claro é o verde institucional**, de graça, sem inventar cor nova. A rampa turquesa tem âncora dupla (400 e 600).
2. **O azul-claro #ECF4FC É o azul-50.** Nunca foi uma oitava cor independente; era o primeiro stop da rampa azul. Absorvido como âncora do stop 50 (rampa azul tem âncora dupla: 50 e 300).
3. **O turquesa principal #11B0A0 é um stop 400, não 500.** Sua luminosidade real (OKLCH L 0.712) o coloca no 400. Implicação prática de acessibilidade documentada na §5.

### 2.3 Vermelho funcional (adição, não é cor de marca)

A paleta de 2018 não tem vermelho — mas nenhum sistema digital vive sem estado de erro. Em vez de inventar, formalizamos o **#D94545** que o DS digital v1 já usava informalmente em `.alert-danger` (âncora do stop 500; o hover informal #c63838 morre, substituído pelo vermelho-600 #C6393B gerado). Classificação: **cor funcional** — proibida em material de marca (posts, capas, propostas), permitida apenas em estados de erro/perigo de interface e dataviz negativa.

### 2.4 Superfícies do modo escuro

Quatro superfícies tintadas no hue do cinza da marca (OKLCH h≈235°, o azul-acinzentado do #617683), do fundo ao topo: `page #0B1419` · `default #141D23` · `elevated #1D272D` · `overlay #273137`. Nunca preto puro. **Supersede:** substituem os hex ad-hoc `#0d1f25`, `#1d3138`, `#11272f` da seção dark do `seed-design-system.html` v1 (mesma direção estética, agora derivados por método).

### 2.5 Tipografia

- `--seed-font-sans`: **Montserrat** (marca e interface; pesos carregados: 300/400/600/700). Regra de legibilidade: texto corrido longo usa Light/Regular com line-height 1.65 — pesos médios em massa ficam monótonos nesta fonte.
- `--seed-font-mono`: **JetBrains Mono** (pesos 400/500/700). Papel exclusivo: dados de medição (kWh, kWp, demanda), identificadores (UC, ART, nº de proposta), código, timestamps, acento em labels micro. **Nunca em títulos ou parágrafos.** Motivo da escolha: algarismos tabulares nativos (colunas de números alinham), maior nota de acessibilidade entre monos gratuitas, Google Fonts, licença aberta.
- Escala (herdada do DS v1, mantida — decisão: a escala estava correta, o problema era aplicação): display 64/72 · h1 42 · h2 32 · h3 24 · h4 18 · body-lg 17 · body 14 · small 12 · caption 11 (SemiBold, UPPERCASE, tracking 2px).
- **Escala fluida (v1.2 — mobile/app):** os 4 topos da escala respondem ao viewport via `clamp()`; de h4 para baixo, invariante. Valores: display `clamp(2.5rem, 1.9rem + 2.6vw, 4rem)` (40→64px) · h1 `clamp(1.875rem, 1.58rem + 1.3vw, 2.625rem)` (30→42px) · h2 `clamp(1.5rem, 1.3rem + 0.87vw, 2rem)` (24→32px) · h3 `clamp(1.25rem, 1.15rem + 0.43vw, 1.5rem)` (20→24px). Interpolação calibrada entre 360px (Android BR mais comum) e 1280px. **Regra WCAG 1.4.4 embutida:** a fórmula SEMPRE combina termo `rem` dominante + termo `vw` — clamp com vw puro não responde ao zoom do navegador e reprova em redimensionamento de texto 200%; o teste de zoom 200% faz parte do preview de cada bloco. Desktop puro pode continuar usando os valores fixos; peças de marketing usam a camada expressiva da Marca v5.0 normalmente.
- `--seed-font-expressive`: **Caveat** (pesos 400/600/700). **Papel exclusivo: peça de MARKETING que precise de algo alegórico, fora do normal, festivo.** Nunca em interface, nunca em documento técnico, nunca como assinatura padrão de peça de rotina. *Token nascido em 2026-08-20 — ver a errata abaixo.*
- **Supersede tipográfico:** Indie Flower **aposentada** (tagline manuscrita "Soluções Sustentáveis" sai de cena nas peças novas — decisão de 2026-07-30). Neo Tech **aposentada** (não tinha papel definido nem uso real).

> ### ERRATA FORMAL — 2026-08-20: o sistema tem TRÊS famílias, não duas
> Esta subseção dizia *"Sistema final: 2 famílias, papéis sem sobreposição"*, e a tabela de decisões do
> §"Decisões" registrava **"3ª família"** como **alternativa descartada** (*"necessidade inexistente
> hoje; decidir se/quando surgir"*). **A necessidade surgiu e foi decidida pelo Rafael em 2026-08-20**,
> verbatim:
>
> > *"nós ja temos decisao das 3 fontes canonicas, principal, a secundaria e a terciaria é extritamente
> > para uso do marketing em peças que precise criar algo alegorico, fora do normal, festivo, etc"*
>
> **Papéis, sem sobreposição:** **principal** Montserrat (marca e interface) · **secundária** JetBrains
> Mono (dado, identificador, código) · **terciária** `--seed-font-expressive` (marketing alegórico).
>
> **Nome do token — e a alternativa descartada.** Escolhido `--seed-font-expressive` em vez de
> `--seed-font-display`, que é o terceiro slot convencional dos design systems. Motivo: *"display"*
> nomeia **tamanho** e seria lido como "fonte de título grande", que é exatamente o uso que esta família
> **não** tem — a escala de display desta casa é Montserrat. `expressive` nomeia o **propósito**, e
> propósito é o que impede consumo errado. *Regra da casa: quando o valor está certo e o propósito não
> tem nome, o conserto é NOME.*
>
> ⚠ **A família é `Caveat` por INFERÊNCIA declarada, não por fala dele.** Ele decidiu o papel e o escopo;
> o único canônico que **nomeia** a terciária é o `marca-seed.md` **v5.0** §4.3, que não está na pasta
> (pendência **MR-P3**). *Confirmar o nome antes de qualquer peça sair com ela.*
>
> ⚠ **Fronteira que esta errata NÃO abre:** a terciária **não** volta a ser a assinatura manuscrita
> padrão que a Indie Flower era. A Indie Flower foi aposentada porque a tagline manuscrita aparecia em
> **toda** peça; a terciária existe para o **excepcional**. *Trocar a fonte e manter o uso onipresente
> seria desfazer a decisão de 2026-07-30 com outra letra.*

### 2.6 Spacing, radius

- Spacing: base 4px mantida (decisão: já era correta), escala estendida `sp-0…sp-24` (0→96px).
- Radius: sm 4 (chips) · md 8 (controles) · lg 12 (cards) · xl 16 (modais) · full (pills). O DS v1 não tinha escala de radius formal — cada componente inventava a sua; agora é token.

### 2.7 Motion — dois registros (modelo Carbon)

- **Produtivo** (tarefa; sutil, sai do caminho): 100ms (hover/foco) e 150ms (dropdowns, estados), easing `cubic-bezier(0.2, 0, 0.38, 0.9)`.
- **Expressivo** (momentos significativos): 300ms (modais, notificações) e 400ms (transições de tela), easing `cubic-bezier(0.4, 0.14, 0.3, 1)`.
- **Saída — `--seed-ease-out` = `cubic-bezier(.2,.8,.4,1)`** (v1.23, 2026-08-26). Entradas e revelações de componente: thumb do switch (120ms), toast (160ms), barra de progresso (200ms), modal e drawer. ⚠ **Não é apelido do produtivo, e isso foi medido, não suposto:** contra o `ease-productive` a diferença é **36,8% do percurso e 24,9 ms** — quase um quadro e meio a 60 Hz. O `seed-componentes.md` usava este nome **quatro vezes sem nunca fixar a curva**, e o acervo carregava dois valores; os dois, medidos em 21 instantes de um movimento de 120 ms, diferem **0,3 ms**, que é 1/56 de um quadro. ⭐ *Dois nomes para a mesma curva; e a curva de verdade diferente era a terceira, que ninguém estava comparando.*
- **Acessibilidade embutida no token:** com `prefers-reduced-motion`, durações produtivas zeram e expressivas caem para crossfade de 100ms (regra do Uber Base). Quem consome o token respeita a preferência sem escrever media query.

### 2.8 Elevação — par superfície+sombra (modelo Atlassian)

Elevação nunca é só sombra: é o par. `surface-raised` + `shadow-raised` (cards) · `surface-overlay` + `shadow-overlay` (menus, popovers) · modal usa `shadow-modal`. Sombras tintadas no cinza-900 (#242E34), nunca preto. No dark, a sombra escurece e a **borda sutil assume a separação** (sombra sozinha some em fundo escuro). Existe também `surface-sunken` para áreas rebaixadas (wells, blocos de código).

### 2.9 Breakpoints, toque e app (v1.2)

**Breakpoints — escala oficial (alinhada ao Tailwind, stack dos produtos):** sm 640 · md 768 · lg 1024 · xl 1280 · 2xl 1536 (px, min-width). **Limitação técnica documentada:** media query NÃO lê CSS custom property — por isso breakpoint não existe como `--seed-*` no CSS; as fontes canônicas são o `seed-tokens.json` (consumo por app nativo e ferramentas) e o `theme.screens` do Tailwind (consumo pelos produtos web). O corte 960 do HTML v1 fica superseded (§ Supersedes abaixo). Faixa de projeto: mobile <640 · tablet 640–1023 · desktop ≥1024. Pior caso de teste: **360px** (largura Android mais comum no Brasil — o mercado é ~80% Android).

**Tokens de toque:**
```css
--seed-fs-field-touch: 16px; /* fonte mínima de CAMPO em superfície de toque —
  campo <16px dispara zoom automático no iOS Safari ao focar */
@media (pointer: coarse) { /* detector correto: TOQUE, não largura —
  tablet grande também é toque; desktop estreito não é */
  .seed-field__control { font-size: var(--seed-fs-field-touch); }
}
```

**Safe areas (PWA/WebView/app com notch e barra de gesto):**
```css
--seed-safe-top: env(safe-area-inset-top);
--seed-safe-bottom: env(safe-area-inset-bottom);
--seed-safe-left: env(safe-area-inset-left);
--seed-safe-right: env(safe-area-inset-right);
```
Barras fixas (header, tab bar, CTA fixo de rodapé) somam o safe-area ao próprio padding. Requer `viewport-fit=cover` no meta viewport.

**Supersede (v1.2):** breakpoints do `seed-design-system.html` v1.0 (mobile 0–639 / tablet 640–959 / desktop 960+) → escala Tailwind acima. Motivo: os produtos rodam Lovable/Tailwind/shadcn; manter 960 exigiria configuração divergente em todo produto, fricção diária sem ganho. Diferença prática (960→1024) é mínima.

## 3. Camada 2 — Semânticos (light + dark)

Grupos entregues (valores completos no JSON/CSS): `surface` (page, subtle, raised, sunken, overlay, brand, brand-deep, inverse) · `text` (primary, secondary, muted, disabled, brand, inverse, on-brand, link) · `border` (subtle, default, strong, focus, interactive — v1.12) · `action` (primary±hover/active, secondary, ghost, destructive) · `feedback` (success/warning/danger/info × bg/text/border/solid) · `chart` (cat-1…6, positive, negative, grid, axis).

Decisões dignas de registro:

- **`action-primary` light = turquesa-600 (verde institucional).** Dark = turquesa-300 com texto turquesa-900 (7.39:1) — padrão moderno de "fill claro + texto escuro" no dark, em vez de escurecer o botão.
- **`text-primary` = **#0B3330** *(v1.9 — SUPERSEDE de `cinza-900 #242E34`)*.
  A v1.0 superseava o `#2a3942` ad-hoc do HTML v1; a **v1.9 tinge a tinta na família da marca**.

> ### NORMALIZAÇÃO DO `focus-ring` — v1.10 (2026-08-14)
>
> **O que muda:** nada de valor. O `--seed-focus-ring` do tema **claro** deixa de consumir o
> primitivo `--seed-branco` e passa a consumir o semântico `--seed-surface-page`, que é o que o
> bloco **escuro** já fazia. `surface-page` claro **é** `#FFFFFF`, então a cor renderizada é
> idêntica — o que muda é a EXPRESSÃO.
>
> **Por que importa, e o achado veio de fora:** os previews `componentes` e `tokens` já usavam
> `surface-page` nos DOIS temas, e a guarda `paridade-previews.py` os acusou de divergir do gêmeo.
> Ao apurar, **eles estavam mais corretos que o canônico**: um token semântico composto não deve
> depender de primitivo, e ter expressão diferente por tema para o mesmo papel é a porta por onde
> um tema envelhece sem o outro. Quem se ajustou foi o gêmeo.
>
> **Efeito colateral bom:** o `--seed-branco` deixa de ser exigido por qualquer preview que embuta
> o `focus-ring`. A pendência de `--seed-branco` sem definição em `formfield` **fecha por
> consequência**, sem precisar acrescentar token.
>
> ### COMPOSIÇÃO E CHROME — v1.11 (2026-08-14 · CP-P3, executa o SUP-6 em escopo mínimo)
>
> **Contexto para leitor novo:** o gate visual da Fase 2 da composição (2026-08-14, vereditos
> G1–G5 registrados no `seed-composicao.md` §11) adotou o **gradiente do rail** (CP20, G2),
> aprovou a **paleta de entidade** (CP23, G3) e o **marcador de "agora"** (CP24, G4). A adoção do
> gradiente disparou o gatilho do SUP-6 (hover/pressed em cinza sólido falham sobre superfície
> gradiente), resolvido aqui em **escopo mínimo**: dois tokens de overlay, não a rampa alpha
> completa do C27 (custo declarado dela: valores a olho, reauditados a cada superfície — e o CP20
> proíbe gradiente fora do chrome, então só existe UMA superfície gradiente no sistema).
>
> **Os quatro grupos são INVARIANTES DE TEMA — nenhum se redeclara no bloco dark dos gêmeos**, e
> cada um declara aqui o seu par light/dark (que é o mesmo valor) com o porquê:
>
> | Token | Valor (light = dark) | Por quê invariante | Medido |
> |---|---|---|---|
> | `--seed-rail-background` | `linear-gradient(180deg, #006C62 0%, #005048 100%)` (`turquesa-700 → turquesa-800`) | **Por DECISÃO** — SH15: chrome não segue o tema; CP20 exige semântico próprio, senão o tema escuro vira regra manual (o ClickUp escreveu 22 regras à mão) | Branco sobre os **dois extremos**, não na média: **6,32** e **9,37** (≥4,5) |
> | `--seed-chrome-overlay-hover` | `rgba(255, 255, 255, 0.12)` | **Por CONSTRUÇÃO** — compõe sobre superfície invariante (o rail) | Rótulo branco sobre a **COMPOSIÇÃO** (overlay composto sobre cada extremo): **4,88** e **6,82** (≥4,5) |
> | `--seed-chrome-overlay-active` | `rgba(255, 255, 255, 0.14)` | Idem. É o estado **pressionado**; o item ATIVO (`aria-current`) segue sendo a pílula clara do SH15-b | Branco sobre a composição: **4,68** e **6,50** (≥4,5) |
> | `--seed-entity-1…6` + `--seed-entity-N-ink` | E1 `#11B0A0`+`#242E34` · E2 `#D49400`+`#242E34` · E3 `#01B3E0`+`#242E34` · E4 `#005048`+`#FFFFFF` · E5 `#006783`+`#FFFFFF` · E6 `#7B5500`+`#FFFFFF` | **Por CONSTRUÇÃO** — o par medido é interno ao chip (fundo × tinta) e não inverte com o tema; o CP23 define **um hex por posição** | Admissão CP22 (≥4,5 com a tinta declarada): **5,11 · 5,30 · 5,63 · 9,37 · 6,43 · 6,68** |
> | `--seed-marker-now` | `#098475` (`turquesa-600`) | **Por DECISÃO** — CP24: terceiro membro nomeado da classe invariante de tema (SH15 · DG12 · CP24) | ≥3,0 (non-text) contra as cinco superfícies canônicas: **4,60 · 4,23 · 4,05 · 3,72 · 3,31** |
>
> **Decisões de forma, com as alternativas descartadas:**
> **(a) Tinta POR POSIÇÃO** (`entity-N-ink`), não só o par `ink-dark`/`ink-light` com mapa em
> prosa: consumidor que precisa saber um mapeamento de cor é exatamente a classe de defeito que
> produziu a E-CP-01 (artefato consumindo a escala errada). Custo: 6 tokens a mais; ganho: o
> consumo vira `background: var(--seed-entity-3); color: var(--seed-entity-3-ink)` sem decisão local.
> **(b) NÃO redeclarar os invariantes no bloco dark** (nem no espelho `prefers-color-scheme`):
> redeclarar valor idêntico é duplicação, e duplicação é o vetor de deriva que os gêmeos existem
> para matar — quem editar um bloco e esquecer o outro criaria divergência silenciosa. No JSON,
> os quatro grupos ficam **sem `seed.mode` de propósito** (a ausência declara a invariância; a
> guarda `paridade-tokens.py` G2 pula a exigência de bloco dark exatamente nesse caso).
> **(c) Overlays em vez da rampa alpha do C27**: veredito do gate registrado no MANIFESTO v6.7 —
> a rampa completa segue adiada porque só o chrome admite gradiente.
> **(d) Os alphas .12/.14 não foram inventados**: são os dois valores que os artefatos aprovados
> já praticavam (o shell no hover; o preview da composição no ativo do gate), fixados **depois**
> da medição em composição — a quinta camada existe porque par isolado verde já escondeu 1,48.
>
> **Fronteira (mesma do CP23/PN7):** o DS declara o MECANISMO de identidade; **qual entidade usa
> qual posição** vem do PRODUTO, via `data-ident="1..6"`. Acima de 6 entidades repete-se a cor e
> distingue-se pelo **glifo** (nunca letra — decisão do MANIFESTO v6.4, mantida); nunca nasce uma
> sétima cor.
>
> ### `border-interactive` — v1.12 (2026-08-14 · FECHA A PENDÊNCIA SH-P1/PN-P5)
>
> **Contexto para leitor novo:** a SH-P1 nasceu no bloco 6A (2026-08-11), achada pelo
> `contraste-shell.py`: **nenhum token semântico de borda passava 3:1 contra `surface-raised`
> no tema claro** — `border-default` mede 1,49 e `border-strong` 2,53 — e o campo de busca do
> shell consumia o **primitivo `cinza-500`** por *empréstimo declarado*, violando a lei
> "componente consome semântico". O CP17 já havia fechado a metade "separação de peça" da
> pendência (separação virou tarefa do par sombra+anel); restava a metade menor: **fronteira de
> componente interativo** (SC 1.4.11, piso 3:1). A regra GI2 mandava fechá-la "quando a camada 2
> fosse editada por outro motivo" — o motivo foi a CP-P3 (v1.11), e o Rafael decidiu fechar na
> mesma janela (2026-08-14: *"vamos resolver logo"*).
>
> **O token:** `--seed-border-interactive` = `cinza-500` `#788F9D`, **nos dois temas**, medido
> contra as seis superfícies onde borda de componente aparece: raised/page/subtle claro
> **3,38 / 3,38 / 3,11** · raised/page/subtle escuro **4,50 / 5,51 / 5,05** — todos ≥3,0.
> **Não é invariante de tema:** o slot dark fica declarado (o valor idêntico hoje é
> *coincidência medida*, não lei — o dark pode divergir no futuro sem mudar a expressão),
> diferente dos quatro grupos da v1.11, invariantes por decisão ou construção.
>
> **Alternativa descartada, com o número:** `cinza-600` `#617683` também passa as seis
> (3,21–4,74) — mas mudaria a cor **renderizada** que o gate visual do shell já aprovou, sem
> nenhum motivo além da troca: a pendência pedia promoção de **expressão** (primitivo →
> semântico), não de valor. Mesma lógica da normalização do `focus-ring` na v1.10.
>
> ### `row-selected-*` — v1.13 (2026-08-15 · F7.2 · fecha uma lacuna que o sistema já vivia)
>
> **Contexto para leitor novo:** ao produzir o gabarito A2 (`tela-lista.html`), a linha
> selecionada foi pintada com o primitivo `turquesa-100`. O `contraste-f72.py` reprovou:
> **1,57** no tema escuro. A causa é estrutural, não de escolha — **um primitivo é fixo, e
> realce de seleção precisa virar por tema**, senão reprova sempre em um dos dois lados.
>
> Ao procurar o semântico certo, o achado: **a bancada `banco-dados.html` já consumia
> `--seed-row-selected-bg`, `-text` e `-border` desde a Fase 3 — com definição LOCAL, dentro
> do próprio arquivo, ausente deste gêmeo.** O nome existia no sistema sem dono no canônico.
> Não era drift de valor, era drift de PROPRIEDADE: enquanto o token não é do gêmeo, cada
> artefato que precisar dele reinventa o valor, e ninguém mede o par.
>
> **Os tokens** (adição pura — nenhum valor anterior muda; os hex são exatamente os que a
> bancada já usava, para que a promoção não altere um pixel do que o gate já aprovou):
>
> | Token | Claro | Escuro | Papel |
> |---|---|---|---|
> | `--seed-row-selected-bg` | `#E8FBF7` (turquesa-50) | `#00352F` (turquesa-900) | fundo da linha selecionada |
> | `--seed-row-selected-text` | `#242E34` (cinza-900) | `#E3EBF0` (cinza-100) | tinta sobre o realce |
> | `--seed-row-selected-border` | `#098475` (turquesa-600) | `#66D1C2` (turquesa-300) | marcador de 3px na borda da linha |
>
> **Medido:** `bg × text` = **12,53** claro / **11,12** escuro (piso 4,5) · `border × bg` =
> **3,42** / **4,64** (piso 3,0 — o marcador é elemento de interface, SC 1.4.11).
>
> **Alternativa descartada:** manter o realce como primitivo e escrever a exceção do tema à
> mão em cada artefato — que é literalmente o que o CP20 alerta e o que a `tela-lista.html`
> fazia antes desta edição. **Guarda:** `paridade-tokens.py` ganhou quatro verificações,
> incluindo uma que exige que o `bg` **mude entre os temas** — realce fixo é o defeito, não a
> ausência do token. A guarda foi provada real: rodada contra o CSS v1.12, reprova em 7.
>
> ### SUPERSEDE DA TINTA DE TEXTO — v1.9 (2026-08-13)
>
> **O que muda:** os três tokens de tinta de CONTEÚDO passam da família cinza para a família
> turquesa da marca, nos dois temas. **Bordas, superfícies e a régua de ação NÃO mudam.**
>
> | Token | Antes (claro/escuro) | Agora (claro/escuro) | Croma | Pior contraste |
> |---|---|---|---:|---|
> | `text-primary` | `#242E34` / `#E3EBF0` | **#0B3330** / **#DDECE8** | 0,063 → **0,157** | 11,49 → **11.37** |
> | `text-secondary` | `#4D606C` / `#ACBECA` | **#2F5A54** / **#A3C4BE** | 0,122 → **0,169** | 5,43 → **6.42** |
> | `text-muted` | `#788F9D` / `#90A6B3` | **#40706A** / **#8FB5AD** | 0,145 → **0,188** | **2,80 (reprovava)** → **4.65** |
>
> **POR QUÊ.** O `estudo-viver-de-ia.md` §2.1 mede a tinta de texto da plataforma em
> **#0A1F3B — croma 0,192**, declarada como *"navy-tinta, não preto puro, MESMA FAMÍLIA do escuro
> estrutural"*. Como texto e borda ocupam a maior parte da área de qualquer tela, tinta neutra faz
> a tela inteira ler cinza mesmo com a âncora colorida — foi o achado do gate do Rafael em
> 2026-08-13. Os valores adotados ficam em **82% e 88% do croma da referência**: mesma família, na
> mesma intensidade, sem exagero.
>
> **O QUE FOI DESCARTADO, com o número que descartou.**
> **(a) Usar primitivos existentes da escala** (`turquesa-900` + `turquesa-700`): o secundário
> daria croma **0,424 — 2,2× o da referência**. Deixaria de ser tinta discreta e viraria verde
> forte; serve a título, não a corpo de texto.
> **(b) Esverdear BORDAS e SUPERFÍCIES**, como a 1ª redação da proposta previa: **a plataforma não
> faz isso** — as bordas dela medem croma 0,027/0,031 e a página é **branco puro**; o próprio
> estudo diz que *"a sensação de cinza claro vem só das bordas e sombras"*. E há razão nossa,
> medida: a âncora do painel é **cromática**, e o mecanismo **P4** (ritmo neutro↔cromático) depende
> de a página ser neutra. Contra `surface-sunken` esverdeada a âncora cairia de **2,71 para 2,21**,
> e a série `chart-cat-1` cairia junto — perderíamos contraste de saturação exatamente no único
> elemento que precisa dele.
>
> **SUPERSEDE FORMAL DA RESTRIÇÃO "NENHUM HEX NOVO".** Os quatro valores de tinta não existem na
> escala de primitivos. Eles entram como **valores SEMÂNTICOS — nunca como primitivos** —, e os
> **8 hex canônicos da paleta 2018 seguem intocados**, que é a lei do `marca-seed.md`. Precedente
> exato: a **escala categórica estendida** fez este mesmo supersede na v1.6 destes gêmeos.
>
> **ERRATA FECHADA NA MESMA EDIÇÃO (regra GI2): o `text-muted` REPROVAVA no canônico vigente.**
> `#788F9D` (cinza-500) é declarado para *"metadados, placeholders, captions"* — texto pequeno,
> piso 4,5 — e media **3,38** contra page/raised, **3,11** contra subtle e **2,80** contra sunken:
> reprovava nas quatro superfícies do tema claro. O defeito é **anterior a esta rodada** e não foi
> introduzido por ela; foi encontrado na medição que precedeu esta edição. `cinza-600 #617683`
> também reprovaria (3,93). O valor adotado é o único candidato medido que fecha os dois
> requisitos ao mesmo tempo — família e piso nas quatro superfícies.
>
> **A RÉGUA DE AÇÃO NÃO MUDA, E ISSO É O REGISTRO MAIS IMPORTANTE DESTA EDIÇÃO.** Conferido nos
> gêmeos: `action-primary` já era **`#098475` (turquesa-600)** no claro e **`#66D1C2`
> (turquesa-300)** no escuro. **A camada de tokens nunca saiu do §3.5 do `marca-seed.md`** — só o
> preview do painel havia desviado, com o azul, e o desvio foi retirado. Nenhuma linha de token de
> ação precisou mudar.
- **`surface-brand-subtle` = `#E8FBF7` no claro / `#1A3833` no escuro (NOVO em 2026-08-17).** É a superfície de marca **sutil**: balão de mensagem própria, faixa de destaque leve — coisas que precisam de tinta de marca sem virar `surface-brand`. **Nasceu de um defeito, e o defeito era DESTA camada, não do artefato.** A `tela-chat.html` pintava o balão da mensagem própria com a **primitiva** `--seed-turquesa-50` porque **não existia semântico para isso** — e primitiva não inverte com o tema, enquanto o texto (`--seed-text-primary`) inverte: no tema escuro o par media **1,14** contra o piso 3,00, ou seja, **mensagem branca sobre branca** (defeito BT-P6, achado pela `validacao/guarda-gi2.mjs` na primeira varredura da pasta inteira). *O artefato alcançou a primitiva porque era a única coisa disponível — culpar o artefato aqui seria culpar o sintoma.* **Alternativas descartadas:** (a) reusar `--seed-row-selected-bg` ou `--seed-action-secondary-bg`, que já carregam `#E8FBF7` no claro — recusado porque o semântico estaria mentindo: balão de mensagem não é linha selecionada nem fundo de botão secundário; (b) usar `--seed-surface-subtle` como o balão **alheio** já usa — recusado porque apagaria a distinção de tinta entre mensagem própria e alheia, que é desenho aprovado. O valor escuro `#1A3833` **não é valor novo**: é o que esta camada já escolheu para superfície de marca que assenta na página (`--seed-action-secondary-bg` no escuro), então a coerência é com decisão existente. **Medido** contra `--seed-text-primary`: **12,79** no claro e **10,40** no escuro, piso de texto **4,50**. E era o **único** consumo de `--seed-turquesa-50` no acervo inteiro — medido por comando em 29 artefatos.
- **`surface-brand-deep` = turquesa-700/800.** Supersede formalmente a "variante não-oficial tolerada #0d8f82" registrada no `marca-seed.md` v4 — a necessidade (fundo de capa profundo) agora tem resposta oficial dentro da rampa.
- **`feedback-success` usa a família turquesa/verde institucional.** Alternativa descartada: criar rampa verde-folha nova (adicionaria cor fora da marca para resolver ambiguidade que ícone+contexto já resolvem; na SEED, êxito É verde da marca).
- **`chart`: sequência categórica de ordem fixa** — ~~cat-1 turquesa-400, cat-2 dourado-300, cat-3 azul-500, cat-4 turquesa-800, cat-5 cinza-400, cat-6 dourado-700~~ **SUPERSEDIDA na v1.5 pela categórica ESTENDIDA da §3c** (2 matizes exclusivos de dado; sequência turquesa → dourado → magenta → azul → violeta → azul-800; o cinza sai da categórica e fica exclusivo de "sem dado"). Positivo/negativo = turquesa-500/vermelho-500 (inalterado). Regra de acompanhamento inalterada: diferenciar séries também por forma e espessura (acessibilidade).

## 3b. Hierarquia de uso da paleta (decisão de 2026-07-30, lei na Marca v5.0)

Análise competitiva que motivou (fatos verificáveis): no setor elétrico brasileiro, Neoenergia/Coelba usa verde-folha+azul+laranja, EDP usa verde+azul+roxo, Cemig é verde, Engie é azul — o mercado se divide entre o clichê "verde-sustentabilidade" e o clichê "azul-utility". O turquesa SEED ocupa o espaço entre os dois e foi validado por tendência (WGSN elegeu "Transformative Teal" cor de 2026 — a SEED escolheu a família em 2018). Conclusão: **nenhum hex muda; a hierarquia de uso muda.** Três regras:

1. **Proporção 70/20/10.** ~70% branco e neutros claros, ~20% família turquesa (majoritariamente em tons da rampa, não o 400 chapado), ~10% acentos. Supersede a regra de 2018 de "45% de turquesa na identidade", causa raiz das peças cobertas de onda ("efeito infantil"). O turquesa passa de cobertura a assinatura.
2. **Hierarquia dos amarelos.** Os dois amarelos distam ~25° de matiz e eram usados de forma intercambiável (lia como inconsistência). Agora: **amarelo #FAD61D = acento oficial de marca** (grifos, marcadores, EEny, símbolo) — token `accent-highlight`; **dourado #F9B11C = cor de trabalho** (warning, dataviz cat-2, detalhe fotográfico). **Nunca os dois na mesma peça.**
3. **Papel do azul #53C2E9.** LIVRE e empregado no produto digital: é a família de `info` (banners, badges, estados informativos), cat-3 do dataviz, badges/tags, céu/água em ilustração. CONTIDO em material de marca (posts, capas, títulos), onde compete com o turquesa. **Ação primária é sempre família turquesa/verde — nunca azul:** botão azul é a convenção de quem não tem cor própria de ação; a SEED tem (`#098475`, AA). Registro de mal-entendido resolvido: a contenção do azul NUNCA se aplicou a sistemas — só a peças de marca.

Token novo desta decisão: grupo semântico `accent` (`highlight` = amarelo-200, `highlight-subtle`, `on-highlight` = cinza-900, contraste 9.70:1 — texto sobre amarelo é sempre escuro).

## 3c. Dataviz — escalas de dado (Fase 5: DT v1.3 e categórica estendida v1.5, ambas **`estável`**)

> **Estado:** `estável` desde 2026-08-09, por "aprovo" explícito do Rafael no gate visual do preview `seed-dataviz-tokens-preview.html` v0.2 completo. Consumidor primário e dono das REGRAS de consumo: `seed-dataviz.md` v0.3 (9º canônico) — esta seção é dona dos VALORES, aquele arquivo é dono das leis (DF7: uma fonte, referência sem duplicação).
>
> Entrega prometida desde a v1.0 ("escalas sequenciais e divergentes para heatmap/mapa/desvio · tokens de gauge"), produzida no sub-bloco DT da F5 em 2026-08-09. **Regra-mãe (DF7 do `seed-dataviz.md`): este arquivo é a ÚNICA fonte dos valores; o `seed-dataviz.md` referencia, nunca duplica.** Todos os stops das escalas do DT (sequencial, no-data, divergente, gauge, strokes v1.3) vêm das rampas do §2.1 — nenhum hex novo foi criado NO DT. **A categórica estendida v1.5 (subseção própria abaixo) supersede essa restrição para o domínio categórico**, com racional medido. Medições do DT por `contraste-dataviz.py` em 2026-08-09; fundos de referência do DT: branco (light) e `#0B1419` dark-page (§2.4). A categórica v1.5 declara os seus próprios fundos de referência na subseção.

### Sequencial — `--seed-chart-seq-1…7` (heatmap, mapa coroplético, intensidade)

Rampa turquesa em 7 classes, **stops 100→900 no light** (saltando 500 e 700) e o espelho
**800→100 no dark** (entrando o 500). Semântica: **valor cresce, tinta cresce** (light) /
**valor cresce, luz cresce** (dark) — em ambos os modos o mínimo se aproxima do fundo,
mapeamento perceptual correto de intensidade.

> **Achado do gate visual do Rafael (2026-08-09) — supersede da escala proposta
> originalmente.** A primeira versão desta tabela usava os stops 50→800; no preview, o
> Rafael apontou que as duas primeiras classes **liam como cinza** ("essa escala inicial
> era pra ser toda em cinza mesmo?"). O chroma dos stops 50/100 é tão baixo que em tela
> eles perdem o hue — e cinza, em dataviz, significa **"sem dado"**: valor baixo e
> ausência de medição ficavam ambíguos. Correção (opção A, aprovada pelo Rafael sobre
> preview comparativo): a rampa desloca um stop (100→900) e o cinza fica reservado ao
> token novo `chart-no-data`. *Alternativa descartada (opção B):* manter 50→800 e
> resolver só pela regra do no-data — rejeitada porque a leitura "primeiras classes
> parecem cinza" permaneceria na tela.

| Classe | Light (stop) | Dark (stop) | vs fundo light | vs fundo dark |
|---|---|---|---|---|
| seq-1 | turquesa-100 | turquesa-800 | 1.19 | 1.99 |
| seq-2 | turquesa-200 | turquesa-700 | 1.45 | 2.94 |
| seq-3 | turquesa-300 | turquesa-600 | 1.83 | 4.05 |
| seq-4 | turquesa-400 | turquesa-500 | 2.71 | 5.77 |
| seq-5 | turquesa-600 | turquesa-400 | 4.60 | 6.86 |
| seq-6 | turquesa-800 | turquesa-200 | 9.37 | 12.85 |
| seq-7 | turquesa-900 | turquesa-100 | 13.55 | 15.62 |

**Isenção declarada (mesmo padrão da §4.3 do `seed-email.md`, agora com respaldo normativo direto):** o WCAG 1.4.11 isenta explicitamente situações onde mudar a cor muda o significado — heatmap é o exemplo nomeado pela norma. As razões acima são **informativas**, não gate. **Condições de acompanhamento obrigatórias:** (a) célula/região de heatmap sempre com valor acessível por rótulo, tooltip ou tabela-fallback (1.1.1); (b) fronteira entre células sustentada por `chart-grid`, nunca só pela diferença de cor; (c) legenda de escala sempre presente com os limites numéricos das classes. **Gatilho de revisão:** se uma classe sequencial passar a portar significado categórico isolado (ex.: "acima do limite regulatório"), aquela classe sai da isenção e entra na régua de 3:1.

### Sem dado — `--seed-chart-no-data` (célula/região sem medição)

| Token | Light | Dark | Regra dura |
|---|---|---|---|
| `chart-no-data` | cinza-100 | cinza-800 | **SEMPRE com hachura diagonal** (padrão repetido ~45°), nunca cor lisa |
| **`chart-no-data-hatch`** *(novo na v1.7)* | **cinza-600 `#617683`** | **cinza-400 `#90A6B3`** | A tinta das linhas da hachura. Medido contra o preenchimento: **3,93** (light) · **3,84** (dark), ambos ≥3 |

Nasce do mesmo achado do gate: o cinza agora é **exclusivo** de "sem dado" em qualquer
gráfico SEED — nenhuma escala de valor pode usá-lo — e a hachura garante que a distinção
"gerou pouco × não reportou" nunca dependa de cor (1.4.1), inclusive em grayscale e
impresso. A legenda do gráfico ganha o item "sem medição" sempre que houver célula no-data.

> **SUPERSEDE formal na v1.7 (2026-08-11) — a hachura ganha token próprio.** *História
> completa, porque ela é instrutiva:* na v1.0 a hachura era desenhada em `cat-5-stroke`, que
> naquela paleta era cinza-600. Na v1.5 o `cat-5` virou **violeta**, e a hachura de "sem
> medição" passou a ser desenhada com cor de categoria viva — o pior lugar possível para
> esse erro, já que "sem medição" é exatamente o que não pode parecer uma categoria. A
> errata **E3** corrigiu isso em 2026-08-11 apontando a hachura para `chart-axis`. **A
> correção resolveu a semântica e quebrou a medição:** `chart-axis` é cinza-500 no light e
> mede **2,80** contra o preenchimento cinza-100 — abaixo do piso de 3:1 do 1.4.11. O defeito
> foi encontrado em 2026-08-11 pela reescrita do `contraste-dg.py` (v2, DI18), que passou a
> medir esse par; a v1 do script não o media.
>
> *Fato desconfortável e registrado de propósito:* o valor **correto já estava em uso antes
> da correção, por acidente** — o cinza-600 da paleta antiga passava com 3,93. A E3 trocou um
> valor certo com semântica errada por um valor errado com semântica certa, porque a troca não
> foi remedida.
>
> **Regra que sai daqui e vale para todo o sistema: toda substituição de token exige
> remedição dos pares que aquele token participa** — não basta a substituição ser
> semanticamente correta. A E3 e esta v1.7 são o par de exemplos.
>
> *Alternativa descartada:* fazer a hachura consumir o primitivo `cinza-700` diretamente,
> sem token novo (5,43 contra o preenchimento, passa folgado). Rejeitada porque **repetiria a
> estrutura do erro original em outra forma**: a causa raiz da E3 foi um papel de desenho
> ("a tinta da hachura de ausência") existir sem token próprio, tomando emprestado o token de
> outro papel. Emprestar de um primitivo, em vez de emprestar de uma categoria, ainda é
> emprestar — e viola a lei "componente consome semântico".

### Geografia — `--seed-chart-geo-base` e `--seed-chart-geo-boundary` — **v1.8, ADIÇÃO** — **`estável`**

| Token | Light | Dark | Papel |
|---|---|---|---|
| **`chart-geo-base`** *(novo na v1.8)* | **`#F2F6F9`** | **`#141D23`** | **Território de CONTEXTO** de um mapa: a área geográfica que **não é objeto de medição** |
| **`chart-geo-boundary`** *(novo na v1.8)* | **`#788F9D`** | **`#90A6B3`** | **Fronteira de município** desenhada. Medida contra o `chart-geo-base`: **3,11** (light) · **6,74** (dark), ambas ≥3 |

**Por que dois tokens novos se os valores já existem no arquivo.** Os hex são idênticos a
`surface-subtle` e a `chart-axis` vigentes, e isso é proposital: **o que muda não é a cor, é a
responsabilidade de mantê-la.** É o mesmo racional que criou o `chart-no-data-hatch` na v1.7,
e o precedente é literal — a errata **E3** provou que *papel de desenho sem token próprio acaba
tomando emprestado o token de outro papel*, e que a troca silenciosa do emprestado quebra o
emprestador.

**O que a medição de 2026-08-11 (`contraste-dp.py`) achou, e que motivou a decisão:**

1. **`chart-grid` e `chart-no-data` têm o MESMO HEX nos dois temas** — `#E3EBF0` no light e
   `#38464F` no dark. Consequência: a condição (b) da isenção do 1.4.11 desta seção
   (*"fronteira entre células sustentada por `chart-grid`"*) **é impossível de cumprir sobre uma
   célula sem medição** — a razão é **1,00**, a linha desaparece. No heatmap isso nunca apareceu
   porque a célula no-data é hachurada e as vizinhas são sequenciais saturadas; num mapa, onde
   metade do território pode ser "sem medição", o defeito é estrutural.
2. **No tema escuro, `chart-axis` e `chart-no-data-hatch` também têm o mesmo hex** (`#90A6B3`).
   Emprestar `chart-axis` para a fronteira faria a linha do contorno e a tinta da hachura de
   "sem medição" serem o mesmo token por acidente — exatamente a estrutura da E3.
3. Contra o território, as candidatas existentes reprovam o piso de 3:1: `chart-grid` mede
   **1,11**, `border-default` **1,37** e `border-strong` **2,33** no light. Só a tinta adotada
   passa (**3,11**).

**Alternativas descartadas:** (a) consumir `surface-subtle` e `chart-axis` diretamente, sem
tokens novos — repetiria a estrutura da E3 em dois papéis novos de uma vez; (b) usar
`chart-grid` como fronteira, como a redação original do DP4 previa — reprovado pela medição
acima, e a errata **E19** do `seed-dataviz.md` registra a correção; (c) criar um token só, para
território e fronteira — são papéis diferentes com pisos diferentes (um é preenchimento, outro é
linha que porta informação), e unificá-los devolveria o problema no primeiro supersede.

**Consumidor:** sub-bloco **DP** (mapas MG-ES-BA) do `seed-dataviz.md` — DP3 (os três estados do
território) e DP4 (fronteira). O `chart-geo-base` **nunca** é usado como "sem medição": ausência
de medição continua exclusiva do `chart-no-data`, sempre hachurado.

### Divergente — `--seed-chart-div-neg-3…pos-3` (desvio, esperado×medido, variação)

Vermelho ↔ neutro ↔ turquesa, 7 posições, alinhada por construção à dupla `chart-positive`/`chart-negative` da v1.0 (turquesa-500/vermelho-500 são exatamente os stops ±2). Uso canônico imediato: o gráfico do alerta de geração (slot ET5 da F4).

| Posição | Light (stop) | Dark (stop) | vs fundo light | vs fundo dark | Gate 3:1 |
|---|---|---|---|---|---|
| neg-3 | vermelho-700 | vermelho-300 | 7.18 | 9.25 | PASS |
| neg-2 | vermelho-500 | vermelho-500 | 4.30 | 4.33 | PASS |
| neg-1 | vermelho-200 | vermelho-800 | 1.53 | 1.78 | zona-zero |
| zero | cinza-100 | cinza-800 | 1.21 | 1.91 | zona-zero |
| pos-1 | turquesa-200 | turquesa-800 | 1.45 | 1.99 | zona-zero |
| pos-2 | turquesa-500 | turquesa-500 | 3.22 | 5.77 | PASS |
| pos-3 | turquesa-800 | turquesa-300 | 9.37 | 10.16 | PASS |

**Regra da zona-zero (declarada, não é isenção):** as posições ±1 e o neutro representam "perto de zero" — aproximar-se do fundo É a semântica. Consequência dura: **dado cuja distinção do fundo é necessária ao entendimento nunca usa sozinho as posições ±1/zero** — barra de desvio pequena leva borda `chart-axis` ou rótulo de valor. As posições plenas (±2, ±3) passam o gate 1.4.11 medido nos dois modos.

### Gauge — `--seed-gauge-*` (monitoramento, medidor)

| Token | Light | Dark | Medição que o aprova |
|---|---|---|---|
| `gauge-track` | cinza-200 | cinza-700 | trilha de fundo (decorativa em si; o contraste exigido é do valor CONTRA ela) |
| `gauge-value` | turquesa-600 | turquesa-300 | 3.09 vs track · 4.60 vs branco (light) — 3.58 vs track · 10.16 vs page (dark) |
| `gauge-range-ok` | = `feedback-success-solid` (turquesa-600 / turquesa-300) | idem value | herda as medições acima |
| `gauge-range-warning` | **dourado-600** | dourado-300 | 3.25 vs track · 4.82 vs branco (light) — 3.54 vs track · 10.04 vs page (dark) |
| `gauge-range-critical` | vermelho-600 | **vermelho-300** | 3.49 vs track (light) — 3.26 vs track · 9.25 vs page (dark) |

**Dois achados de medição desta entrega (o script corrigiu a proposta antes da spec):** o warning light nasceu proposto como dourado-500 e **reprovou** contra a trilha (2.35) — corrigido para dourado-600; o critical dark nasceu vermelho-400 e **reprovou** (2.38) — corrigido para vermelho-300, coerente com o padrão dark do sistema (stops claros: vermelho-300 já é o div-neg-3 dark). *Alternativas descartadas:* clarear a trilha para salvar os stops originais (enfraqueceria a trilha contra o fundo) · criar hex novo fora da rampa (proibido pela regra-mãe do §2.1). Faixas de gauge referenciam a taxonomia de feedback existente — **nenhuma paralela de severidade nasce aqui** (mesma lei do Bloco 3).

> **SUPERSEDE DM3 (2026-08-10, formalizado na v1.5) — os PAPÉIS do gauge invertem; nenhum
> hex muda.** Medido no sub-bloco DM da F5: as três faixas coloridas (`range-ok/warning/
> critical`) ficam a **1 ponto** de claridade entre si no light (46/45/43%) e **0** no dark
> (75/75/72%) — diferem quase só por matiz, exatamente o que a spec do bullet graph de
> Stephen Few previu ao mandar codificar faixas em INTENSIDADES, não em matizes. A partir do
> DM3: **as bandas de faixa do medidor são intensidades de cinza** (consomem os primitivos
> cinza-100/200/300 no light e cinza-800/700/600 no dark — distâncias de claridade 9/10/19 e
> 9/8/17 pontos, medidas), e **quem carrega a severidade é a BARRA DE VALOR**, que assume
> `gauge-range-ok/warning/critical` conforme a faixa em que o valor cai. Os tokens desta
> tabela permanecem com os mesmos hex — muda o elemento que os consome. As leis de desenho do
> medidor (anatomia, rótulo de estado, textura DM11) vivem no `seed-dataviz.md` §DM (DF7).
> *Alternativas descartadas:* manter bandas coloridas + texturizar as três (ruído em objeto
> pequeno) · mudar os hex das faixas (supersede caro, sem necessidade). *Fronteira:* aliases
> nomeados `gauge-band-*` nos gêmeos só nascem quando o produto consumir o medidor
> (decisão registrada como pendência, não antecipada).

### Stroke reforçado da categórica — `--seed-chart-cat-N-stroke` (traço fino)

> ⚠ **Tabela histórica (v1.3).** A coluna "Fill (v1.0)" e os strokes de cat-3/4/5/6 abaixo
> foram **supersedidos pela categórica ESTENDIDA v1.5** (subseção adiante) — os valores
> vigentes estão lá. Esta tabela permanece como registro do racional que criou a variante
> `-stroke` (o mecanismo continua valendo; mudaram os hex de parte das posições).

A remedição de conferência da categórica v1.0 sob o critério de **traço fino** (linha ≤3px, marcador pequeno — o pior caso do 1.4.11) reprovou cat-1 (2.71), cat-2 (1.85) e cat-5 (2.53) contra branco. A categórica de preenchimento **não mudou naquele lote** (mudaria depois, na v1.5); nasceu a variante de stroke:

| Série | Fill (v1.0, inalterado) | Stroke light (novo) | Stroke light vs branco | Stroke dark (novo) | Stroke dark vs dark-page |
|---|---|---|---|---|---|
| cat-1 | turquesa-400 | **turquesa-600** | 4.60 | **turquesa-300** | 10.16 |
| cat-2 | dourado-300 | **dourado-500** | 3.49 | **dourado-300** | 10.04 |
| cat-3 | azul-500 | = fill | 3.32 | **azul-300** | 9.09 |
| cat-4 | turquesa-800 | = fill | 9.37 | **turquesa-100** | 15.62 |
| cat-5 | cinza-400 | **cinza-600** | 4.74 | **cinza-300** | 9.72 |
| cat-6 | dourado-700 | = fill | 6.68 | **dourado-100** | 15.36 |

> **Achado V2 (render de 2026-08-09, ANTES do gate humano):** a primeira versão desta
> tabela definia stroke só para light; o screenshot dark do preview mostrou a cat-4-stroke
> (turquesa-800) a ~2:1 do fundo escuro — linha quase apagada. Os pares dark acima nasceram
> dessa reprovação, todos medidos ≥3:1. **Dependência declarada:** no dark, cat-2 e cat-6
> comprimem para stops vizinhos da rampa dourado (300/100) — a distinção mútua dessas duas
> séries em modo escuro é sustentada pelo tracejado/marcador (1.4.1), nunca só pela cor.
> Os valores dark do FILL categórico vivem nos gêmeos JSON/CSS da v1.0 (não reproduzidos
> aqui); a regeneração do §7.0 deve conferi-los contra os strokes desta tabela.

**Regra de consumo:** gráfico de linha e sparkline usam `cat-N-stroke`; barra, área e fatia usam `cat-N` (fill). A regra de acompanhamento da v1.0 permanece intocada e vira lei da F5: **cor nunca é o único diferenciador de série** — forma de marcador, espessura ou tracejado acompanham (DF3-a do `seed-dataviz.md`).

### Categórica ESTENDIDA — `--seed-chart-cat-1…6` (+`-stroke`) — **v1.5, supersede formal** — **`estável`**

> **Estado:** `estável` desde 2026-08-11, por "aprovo" explícito do Rafael sobre o lote de
> formalização da F5 (o gate visual que a aprovou foi o de 2026-08-10, sobre os previews de
> gráficos v1.2 e de monitoramento v0.7 — ambos reanexados e conferidos por MD5 em 2026-08-11).
> Consumidor primário e dono das REGRAS de consumo: `seed-dataviz.md` v0.6 §4.6 (DF7).

> **O que esta subseção supersede:** (a) os **valores** da categórica v1.0 (fills e strokes,
> tabela antiga acima e bullet da seção 3); (b) a **restrição "nenhum hex novo"** que o
> próprio DT declarou. **O que ela NÃO toca:** sequencial, no-data, divergente e a regra de
> consumo fill×stroke — tudo do DT permanece `estável` como está.
>
> **Racional medido do supersede (por que a restrição caiu).** Medição de matiz (H) de todos
> os primitivos do §2.1, feita em 2026-08-10 durante o gate do redesenho DG14–DG17: para DADO
> a marca tem exatamente **3 matizes livres** — turquesa (~170–174°), dourado/amarelo
> (~36–50°, uma família só de matiz) e azul (~192–197°) — porque o **vermelho** (~358°) é
> reservado a `feedback-danger`/`chart-negative` (lei do Bloco 3) e o **cinza** é reservado a
> "sem dado" (achado do gate do DT, token `chart-no-data`). Com 3 matizes, qualquer categórica
> de 6 posições repete família e produz "escalas da mesma cor" — exatamente a crítica do
> Rafael no gate de 2026-08-10. A resposta consolidada da indústria para este dilema (IBM
> Carbon, GitLab) é uma **paleta estendida específica de dataviz**, com matizes que não
> existem na marca e **nunca aparecem em UI**. *Alternativa descartada com limite honesto
> declarado:* recurar a sequência só com stops existentes — continua sendo 3 matizes
> revezando; em 6 séries sempre haveria 2 pares da mesma família.

**Dois matizes novos, exclusivos de dado.** Calibrados na claridade das âncoras SEED
(fills light ~49–56% de claridade, como turquesa-500 e azul-500) e aprovados no gate visual
de 2026-08-10: **magenta 332°** e **violeta 268°**. São 6 hex novos no total (fill light,
fill dark e stroke light de cada matiz; no dark o stroke = fill, padrão do DT). Regra dura:
**esses hex não têm rampa no §2.1 de propósito** — não são cor de marca nem de UI; são
`chart-*` e só. Se algum dia um deles aparecer em botão, badge ou superfície, é defeito.

**Sequência v1.5 (ordem obrigatória): turquesa → dourado → magenta → azul → violeta →
azul-800.** As posições 1–5 cobrem **5 famílias de matiz, todas distintas**; a 6ª posição é
a única que reutiliza família (azul, em claridade distante: 28 pontos da cat-4 no light).
A posição 2↔3 foi decidida pelo gate: turquesa e magenta são ambos tons médios saturados e
liam parecidos como vizinhos de pilha; o dourado (75% de claridade) entre eles separa por
peso, não só por matiz. O **cinza saiu da categórica** — resolvendo o conflito com a reserva
de "sem dado" que a própria v1.0 carregava sem ver (o antigo `cat-5` era cinza-400).

| Série | Família | Fill light | vs branco | Stroke light | vs branco | Fill dark | vs cartão dark | Stroke dark |
|---|---|---|---|---|---|---|---|---|
| cat-1 | turquesa | **turquesa-500 `#00A192`** | 3.22 | turquesa-600 `#098475` | 4.60 | turquesa-300 `#66D1C2` | 8.50 | = fill |
| cat-2 | dourado | dourado-300 `#F9B11C` | **1.85 ⚠ (regra abaixo)** | dourado-500 `#B67F00` | 3.49 | dourado-300 `#F9B11C` | 8.40 | = fill |
| cat-3 | **magenta (novo)** | `#CD518B` | 4.08 | `#B23871` | 5.68 | `#E8A1C2` | 7.64 | = fill |
| cat-4 | azul | azul-500 `#0099C1` | 3.32 | = fill | 3.32 | azul-300 `#53C2E9` | 7.61 | = fill |
| cat-5 | **violeta (novo)** | `#966AC8` | 4.04 | `#7B42BD` | 6.26 | `#BD9CE2` | 6.69 | = fill |
| cat-6 | azul (única repetição) | azul-800 `#004C61` | 9.52 | = fill | 9.52 | azul-200 `#96E0FD` | 10.66 | = fill |

**Fundos de referência desta tabela (declarados):** branco no light; **cartão
`surface-raised` dark `#1D272D`** no dark — o palco real do gráfico é o cartão
(`figure.seed-chart`), não a página; é o mesmo referencial da camada de validação do DG.

**Mudança do `cat-1` (era turquesa-400 `#11B0A0`, vira turquesa-500 `#00A192`).** Motivo:
o redesenho DG14 removeu o contorno das superfícies de dado, então o fill precisa passar
**3:1 sozinho** contra o fundo — o turquesa-400 media 2.71 e reprovava; o turquesa-500 mede
3.22 e passa. Bônus de coerência: `cat-1` fica idêntico ao `chart-positive` (turquesa-500),
que sempre foi o "verde" do dado.

**Regra do dourado (a exceção declarada da tabela).** O dourado a 1.85 é insolúvel dentro da
família: escurecê-lo até 3:1 o transforma em mostarda e mata a cor de trabalho da marca.
Regra de consumo: **dourado (`cat-2`) é permitido em área grande COM rótulo direto**
(a informação não depende da fronteira — mesma lógica que o 1.4.11 comporta) e **vetado como
fill solitário sem rótulo**; em traço fino, vale a variante `cat-2-stroke` (3.49), como
sempre. Guarda de consumo: gráfico de série única nunca nasce em `cat-2`.

**Claridades e espalhamento (o instrumento do DG13, remedido para a v1.5):**

| Modo | cat-1…6 (% claridade) | Distância entre vizinhas | Trio da empilhada (1×2 · 2×3 · 1×3) |
|---|---|---|---|
| Light | 56 · 75 · 49 · 55 · 50 · 27 | 19 · 26 · 6 · 5 · 23 | 19 · 26 · 7 |
| Dark | 75 · 75 · 71 · 71 · 67 · 84 | **0 · 4 · 0 · 4 · 17** | 0 · 4 · 4 |

> **Emenda GI2 (registro que faltava à §3c, devido desde o marco v1.7): a rampa categórica
> ESCURA colapsa em escala de cinza — e isso NÃO é defeito de token.** Na paleta antiga,
> `cat-1/2/3` dark mediam 75/75/71% de claridade (duas séries idênticas em P&B); na v1.5 o
> quadro persiste (75/75/71/71/67). A causa é estrutural: todo fill dark precisa ser CLARO
> para contrastar com o fundo escuro (todos medem ≥6.69 contra o cartão), e claridade alta
> comprimida é o preço disso. É este fato que **obriga o DG13** (textura por série na
> interseção escuro+grayscale, lei no `seed-dataviz.md`): a paleta estendida melhora o
> colorido, **não revoga a textura**. Quem lê esta seção isolada precisava saber disso.

**Deriva corrigida na formalização (achado de 2026-08-11):** os previews aprovados no gate
embutiam 5 hex com deriva do canônico (`#66D2C2`→turquesa-300 real `#66D1C2` ·
`#4FC3E8`→azul-300 `#53C2E9` · `#00506F`→azul-800 `#004C61` · `#A8DCEF`→azul-200 `#96E0FD` ·
`#FFD166`→dourado-300 `#F9B11C` no stroke dark da cat-2). Esta seção ancora nos **stops
reais do §2.1**; remedição completa provou que **nenhum veredito de gate muda** (deltas de
claridade ≤2 pontos). Errata aberta contra os previews: alinhar os hex embutidos quando os
arquivos forem reanexados/editados.

### Texto de gráfico (referência de consumo, não token novo)

Rótulo/eixo/legenda consomem os tokens de texto existentes, com os pares aprovados para as superfícies de gráfico: cinza-700 sobre branco 6.55 · cinza-600 sobre branco 4.74 (light) · cinza-200 sobre dark-page 12.53 · cinza-300 sobre dark-default 8.92 — todos ≥4.5:1 (1.4.3).



`--seed-{grupo}-{variação}` para semânticos, `--seed-{cor}-{stop}` para primitivos. Prefixo `seed` evita colisão com Tailwind/shadcn/bibliotecas nos produtos. No Tailwind v4 dos produtos Lovable, os semânticos entram via `@theme` mapeando para estes nomes (guia de integração será entregue na Fase 3 junto dos componentes).

## 5. Acessibilidade — pares auditados (WCAG 2.1, medidos programaticamente em 2026-07-30)

| Par | Razão | Veredicto |
|---|---|---|
| branco sobre turquesa-600 (botão primário) | 4.60 | AA texto normal |
| branco sobre turquesa-700 | 6.32 | AA |
| ~~branco sobre turquesa-400 `#11B0A0`~~ | ~~3.22~~ → **2,71** | ❌ **REPROVA em qualquer tamanho — ver a errata abaixo. O 3.22 é o número do turquesa-500 `#00A192`, transplantado de endereço** |
| **turquesa-900 `#00352F` sobre turquesa-400 `#11B0A0`** | **4,99** | **AA texto normal — é a tinta VIGENTE sobre a marca chapada (v1.15)** |
| cinza-900 sobre amarelo `#FAD61D` | 9.70 | AAA |
| cinza-900 sobre dourado `#F9B11C` | 7.48 | AAA |
| cinza-600 (corpo) sobre branco | 4.74 | AA |
| cinza-700 (corpo) sobre branco | 6.55 | AA |
| branco sobre vermelho-600 (botão danger) | 5.19 | AA |
| vermelho-700 sobre vermelho-50 (alerta) | 6.57 | AA |
| azul-800 sobre azul-50 (info) | 8.57 | AAA |
| dourado-800 sobre dourado-50 (warning) | 9.05 | AAA |
| cinza-100 sobre dark-default (texto dark) | 14.16 | AAA |
| turquesa-300 sobre dark-default (ação dark) | 9.32 | AAA |
| turquesa-900 sobre turquesa-300 (texto do botão dark) | 7.39 | AAA |

> ### ⚠ ERRATA MEDIDA EM 2026-08-17 — O NÚMERO DESTA REGRA ESTÁ ERRADO, E A REGRA CAI COM ELE
>
> **O parágrafo abaixo fica como HISTÓRICO. O estado vigente é esta errata.**
>
> Ele declara que branco (`#FFFFFF`) sobre `surface-brand` (`#11B0A0`) dá **3,22:1** e conclui que
> *"passa AA-large (≥3.0)"*, e é sobre essa conclusão que a regra *"texto branco somente ≥24px ou
> ≥19px bold"* foi construída. **Recalculado pela fórmula da WCAG 2.x (luminância relativa) e medido
> por pixel em artefato real: o valor é 2,71.** Duas medições independentes concordam — o cálculo
> direto dá **2,74** e a leitura por pixel do `validacao/contraste-composicao.mjs` dá **2,71** (a
> diferença é o antialias do glifo).
>
> **ERRATA DA ERRATA (2026-08-17, edição v1.15):** o parágrafo acima diz que *"o cálculo direto dá
> **2,74**"* e explica a diferença pelo antialias do glifo. **Não há diferença: o cálculo direto dá
> `2,7126`, isto é 2,71, exatamente o que o pixel lê.** O 2,74 nunca existiu, e a explicação do
> antialias explicava uma diferença inexistente. Recalculado três vezes por implementação
> independente. *Errata dentro de errata — o número certo entrou no lugar certo e um número errado
> entrou na justificativa.*
>
> **DE ONDE VEIO O 3,22 — e ele NÃO foi inventado (medido em 2026-08-17):** 3,22 é o número
> **correto** de branco sobre **`turquesa-500` `#00A192`** (medido `3,2243`). Ele foi transplantado
> para o **`turquesa-400` `#11B0A0`**, que é a `surface-brand`. Este mesmo arquivo usa 3.22
> **corretamente** onde fala de turquesa-500 (a escala de prioridade e a categórica `cat-1`) e
> **incorretamente** onde falava de turquesa-400. *O erro é de ENDEREÇO, não de aritmética.*
>
> **Consequência:** 2,71 **reprova até o piso AA-large de 3,00**. Portanto **texto branco sobre
> `surface-brand` não é permitido em NENHUM tamanho** — nem em 24px, nem em 19px bold. A regra
> vigente não é "só grande": é **não usar branco ali**.
>
> **Como o defeito apareceu:** rodando o `contraste-composicao.mjs` no `tela-chat.html`, alvo em que
> ele nunca havia sido apontado. Dois textos reprovaram no tema claro — `button "Recolher chat"`
> (12px/600) e `div.avatar "RS"` (12px/700) —, ambos branco sobre `#11B0A0`, ambos a **2,71**.
> *Ausência de medição não era aprovação: era ausência de medição.*
>
> **A resposta já existe dentro da casa, e ela está no tema ESCURO deste mesmo artefato:** lá o mesmo
> botão usa tinta escura sobre a marca — `#00352F` sobre `#11B0A0` = **4,99**, que passa o piso de
> texto 4,50. Medido também: `#0B3330` sobre `#11B0A0` = **5,06** e `#005048` sobre `#11B0A0` = **3,45**.
> **Substituto recomendado: tinta escura da rampa turquesa (`turquesa-900`, `#00352F`) ou o texto
> primário claro (`#0B3330`).**
>
> **✅ DECIDIDO E EXECUTADO em 2026-08-17 (v1.15) — a MR-P1 está FECHADA.** O Rafael acatou a
> recomendação; o conserto foi feito **nesta camada**, não nos artefatos, e o censo por pixel em
> **48 artefatos × 2 temas** devolve **49 textos assentando sobre a marca chapada e ZERO violando**.
> Como foi feito e por que assim: **§5-b** abaixo. Registro completo no `validacao/MANIFESTO.md`
> **§86**. *O parágrafo seguinte ficou como histórico:*
>
> **NÃO EXECUTADO — vai a GATE, e o motivo:** trocar branco por tinta escura sobre a marca é decisão
> de **identidade visual**, não conserto de token: ela muda a aparência de todo botão e selo de marca
> do acervo, e a regra antiga está referenciada no `marca-seed.md`. Pendência **MR-P1**. *Enquanto não
> houver decisão, os textos brancos sobre `surface-brand` são DEFEITO MEDIDO em aberto — o número está
> aqui e não passa por aprovação por silêncio.*

**~~Regra crítica reformulada~~ — SUPERSEDIDA em 2026-08-17 pelo §5-b abaixo, que é o estado VIGENTE. Fica como histórico, e o que está errado nela é o número: 3.22 é o contraste do turquesa-500, não do turquesa-400.** *(texto original preservado:)* a regra antiga "texto branco sobre turquesa apenas em 24px+/bold 19px+" foi auditada: branco sobre #11B0A0 dá **3.22:1**, que passa AA-large (≥3.0) mas **reprova para texto normal**. A regra nova, mais precisa: sobre `surface-brand` (#11B0A0), texto branco **somente ≥24px ou ≥19px bold** (mantida, agora com o número que a justifica); qualquer texto funcional/normal sobre fundo turquesa deve usar `surface-brand-deep` ou o par `action-primary` (turquesa-600+). O amarelo mantém a regra absoluta: **sempre texto escuro** (cinza-900), nunca branco.

## 5-b. A TINTA SOBRE FUNDO DE MARCA — três tokens, um por fundo (v1.15, 2026-08-17) · ⚠ PARCIALMENTE SUPERSEDIDO PELO §5-d

> **Esta seção SUPERSEDE a "Regra crítica reformulada" do §5** e é o estado VIGENTE. Ela fecha a
> **MR-P1** (decisão do Rafael) e a **MR-P2** (defeito medido na mesma edição). Registro completo, com a
> prova de reprovação das guardas, no `validacao/MANIFESTO.md` **§86**.

**O que estava errado não era um valor — era a ARQUITETURA.** Até a v1.14 **um único token de tinta**
(`text-on-brand`) servia **três fundos de marca** com necessidades **opostas**. O gêmeo de JSON descrevia
esse token, com essas palavras, como *"texto sobre action.primary"* — isto é, o próprio gêmeo declarava
para qual fundo ele havia sido feito, e ele estava sendo consumido em outros dois.

| Fundo | Valor | branco `#FFFFFF` | escura `#00352F` |
|---|---|---|---|
| marca **chapada** — `surface-brand` | `#11B0A0` nos dois temas | **2,71** ❌ | **4,99** ✓ |
| marca **profunda** — `surface-brand-deep` claro | `#006C62` | **6,32** ✓ | **2,14** ❌ |
| marca **profunda** escuro | `#005048` | **9,37** ✓ | **1,45** ❌ |
| **botão primário** — `action-primary` claro | `#098475` | **4,60** ✓ | **2,95** ❌ |
| **botão primário** escuro | `#66D1C2` | **1,83** ❌ | **7,39** ✓ |

*Piso 4,50 (SC 1.4.3, texto normal). Nenhum valor único satisfaz as três linhas.* O token acertava o botão
primário — o fundo para o qual nasceu — e errava os outros dois, **um defeito em cada tema**: branco sobre a
marca chapada media **2,71** no claro (**MR-P1**, medido por pixel em 9 artefatos) e tinta escura sobre a
marca profunda media **1,45** no escuro (**MR-P2**, medido por pixel em 3 textos do `tela-tabela.html` — o
contador dentro de botão e a página corrente do rodapé). **Lacuna de token, a mesma família do BT-P6.**

**O ESTADO VIGENTE — três tintas, e o nome diz o fundo:**

| Token | Claro | Escuro | Mede | Use sobre |
|---|---|---|---|---|
| `--seed-text-on-brand` | `#00352F` | `#00352F` | **4,99** nos dois | `surface-brand` (`#11B0A0`) — a marca **chapada** |
| `--seed-text-on-brand-deep` *(novo)* | `#FFFFFF` | `#FFFFFF` | **6,32** · **9,37** | `surface-brand-deep` — a marca **profunda** |
| `--seed-text-on-action-primary` *(novo)* | `#FFFFFF` | `#00352F` | **4,60** · **7,39** | `action-primary` — o **botão primário** |

**A REGRA, em uma frase:** *sobre a marca chapada a tinta é **escura**, nos dois temas e em qualquer
tamanho — **branco ali não é permitido nem em 24px, nem em 19px bold**. Sobre a marca profunda, e sobre o
botão primário no tema claro, a tinta é branca. Sobre o botão primário no tema escuro, escura.* O amarelo
mantém a regra absoluta: **sempre texto escuro** (cinza-900), nunca branco.

**Por que `text-on-brand` não inverte com o tema:** porque `surface-brand` **não inverte** — vale `#11B0A0`
nos dois temas, por decisão de identidade. Tinta que inverte sobre fundo que não inverte é exatamente o
defeito que o contrato **BT3** mede.

**O botão primário NÃO muda de aparência nesta edição:** os valores de `text-on-action-primary` são
exatamente os que a tinta única tinha.

**ALTERNATIVAS DESCARTADAS, com o número que as descarta:**

- **trocar só o valor claro da tinta única** — consertaria a MR-P1 e **abriria** o mesmo defeito no botão
  primário claro, que cairia de **4,60 para 2,95**;
- **parar de usar a marca chapada como fundo de texto**, mandando tudo para a marca profunda — muda a
  identidade visual (o turquesa médio **é** a cor da marca em herói e selo) e contraria a decisão do
  Rafael, que manteve a marca chapada e trocou a tinta;
- **calcular a tinta no consumidor** — não existe cálculo condicional em custom property, e empurrar a
  escolha para o consumidor foi o que produziu a lacuna;
- **manter a tinta única e só acrescentar os dois nomes novos, deixando a antiga como legado depreciado** —
  seria mais seguro contra consumidor esquecido, e foi descartado porque a migração é enumerável por
  comando e porque **nome que engana é o mecanismo que gerou este defeito**.

**COMO A MIGRAÇÃO FOI FEITA, por REGRA e não por arquivo:** o token era consumido sobre fundos diferentes
**dentro do mesmo arquivo**, então substituição global trocaria certo por errado em massa. O script
`validacao/migra-tinta-marca.py` percorre **bloco de regra CSS** e escolhe a tinta pelo fundo declarado na
**mesma regra** — 39 consumos sobre a marca chapada, 28 sobre o botão primário, 4 sobre a marca profunda e
1 caso de fundo `transparent` que ele **não tocou** e imprimiu para decisão humana.

**GUARDA QUE PROVA ESTA REGRA:** `validacao/guarda-tinta-marca.mjs`, contrato **MR1**, alvo de **pasta**,
nos dois temas. Ela mede duas coisas: o **piso** da SC 1.4.3 e a **mão da tinta** (a luminância da tinta
tem de ser menor que a da marca — porque a decisão não foi "passe do piso", foi "tinta escura"). Placar em
2026-08-17: **23 PASS · 0 FAIL · 73 `[n/a]`** em 48 artefatos × 2 temas, com **49** textos assentando
sobre a marca chapada e **zero** violando. *Contrato sem guarda é contrato sem prova.*


## 5-c. A TINTA SOBRE O BOTÃO DESTRUTIVO (v1.16, 2026-08-18) — fecha a AD-P1

> Seção **acrescentada**. Mesma forma do §5-b, um degrau adiante: **faltava o token de tinta daquele fundo**.

**O defeito, medido por pixel em dois artefatos:** o botão destrutivo **clareia no tema escuro** — como toda
superfície de ação desta casa — e a tinta dele continuava **branca literal**. Resultado: `#FFFFFF` sobre
`#FC6F6A` = **2,76**, contra piso 4,50.

| Fundo | branco `#FFFFFF` | vermelho-900 `#521112` |
|---|---|---|
| destrutivo **claro** `#C6393B` | **5,19** ✓ | 2,80 ❌ |
| destrutivo hover claro `#A5272A` | **7,18** ✓ | 2,02 ❌ |
| destrutivo **escuro** `#FC6F6A` | 2,76 ❌ | **5,26** ✓ |
| destrutivo hover escuro `#FF9C95` | 2,01 ❌ | **7,21** ✓ |

**ESTADO VIGENTE:** `--seed-text-on-action-destructive` = `#FFFFFF` no claro · `#521112` no escuro.
**A tinta INVERTE com o tema**, exatamente como a do botão primário.

**RITO de três rodadas, resumido:** o **Material Design 3** faz assim — o papel `on-error` é branco no claro
e um tom escuro do próprio vermelho no escuro. O **IBM Carbon** faz o oposto: mantém `text-on-color` branco
nos dois temas **porque não clareia** o fundo de perigo no escuro. **Adotado o caminho do M3**, porque é o
que esta casa já pratica em toda superfície de ação; adotar o do Carbon exigiria parar de clarear o vermelho
no tema escuro, mudando a aparência de toda superfície de perigo do acervo.

**Alternativas de tinta descartadas com número:** cinza-900 `#242E34` mede **5,03** e turquesa-900 `#00352F`
mede **4,92** sobre o destrutivo escuro — as duas passam, e as duas foram recusadas porque a tinta desta
camada sai do **degrau mais escuro da própria rampa**, e vermelho-900 ainda mede mais.

**GUARDA:** contrato **MR2** no `validacao/guarda-tinta-marca.mjs`
(`SUP=--seed-action-destructive COD=MR2 MAO=livre`). Placar: **22 PASS · 0 FAIL · 74 `[n/a]`** em 48
artefatos × 2 temas, com **50** textos sobre a superfície destrutiva e **zero** violando. *A metade da MÃO
não se exige aqui: sobre o destrutivo a mão inverte com o tema por decisão.*


## 5-d. SUPERSEDE do §5-b — a tinta sobre a marca é BRANCA, e a superfície desce um degrau (v1.17, 2026-08-18)

> **Esta seção SUPERSEDE a metade do §5-b que manda usar tinta ESCURA sobre a marca.** O §5-b continua
> válido no que descreve a arquitetura de três tintas e nos números que mede; o que muda é **qual superfície
> recebe texto**. Registro completo no `validacao/MANIFESTO.md` **§88**.

**O gate visual reverteu a decisão anterior, e a reversão melhorou o resultado.** Verbatim do Rafael:
*"ter o turquesa com o texto Branco dentro no tema claro é algo visualmente bonito, e fica melhor do que o
texto preto. vamos manter o texto branco."*

**Com o texto fixado em branco, a pergunta deixou de ser a tinta e passou a ser a SUPERFÍCIE:**

| | fundo | tinta | mede | veredito |
|---|---|---|---|---|
| A | turquesa-400 `#11B0A0` | branco | **2,71** | reprova em qualquer tamanho |
| **B** | **turquesa-600 `#098475`** | **branco** | **4,60** | ✅ **VIGENTE** |
| C | turquesa-700 `#006C62` | branco | 6,32 | passa; recusada por ficar mais escura que o pedido |
| D | turquesa-400 | escura `#00352F` | 4,99 | era o estado aplicado; **vetado no gate visual** |

**ESTADO VIGENTE:**

| Token | Claro | Escuro | Mede | Use sobre / para |
|---|---|---|---|---|
| `--seed-surface-brand-strong` | `#098475` | `#098475` | — | **superfície de marca que CARREGA TEXTO** |
| `--seed-text-on-brand-strong` | `#FFFFFF` | `#FFFFFF` | **4,60** | a tinta dela |
| `--seed-surface-brand` | `#11B0A0` | `#11B0A0` | — | **âncora visual, área SEM texto funcional** |
| `--seed-text-on-brand` | `#00352F` | `#00352F` | 4,99 | **exceção**: se algum dia houver texto sobre a chapada |

**A FRONTEIRA do controle contra a página (SC 1.4.11, piso 3,00), medida:** turquesa-600 dá **4,60** no
claro, **4,05** sobre a página escura e **3,31** sobre a superfície elevada escura. Passa nos dois temas —
e é por isso que esta superfície **não inverte**: uma cor, uma tinta, os dois temas.

**A REFERÊNCIA DE MERCADO FOI MEDIDA, e ela reprova.** No produto de referência (ClickUp), sessão logada,
somente leitura, tema claro, 2026-08-18: botão primário com fundo `#12a594` e texto branco a 12px/500 =
**3,07** contra piso 4,50. *Referência de mercado é prova de PRÁTICA, não de conformidade. A opção B vai um
degrau além dela, de propósito.*

**Migração:** 19 regras em 9 arquivos, por REGRA CSS e nunca por arquivo — o mesmo arquivo usa a marca
chapada também em área sem texto. Depois da migração, **zero** regras do acervo põem texto sobre a chapada,
medido por comando. **Guarda: contrato MR3** no `guarda-tinta-marca.mjs`
(`SUP=--seed-surface-brand-strong COD=MR3 MAO=livre`) — **21 PASS · 0 FAIL · 75 `[n/a]`**, com **65** textos
assentando sobre o turquesa-600 e **zero** violando, em duas execuções idênticas.


## 5-e. NENHUM TOKEN NASCEU EM 2026-08-18 (noite) — e os três fatos de camada que a sessão registrou

> Seção **acrescentada**, e ela é curta de propósito. A sessão que fechou os seis defeitos de contraste
> **não criou nenhum token**: os gêmeos ficam em **v1.17**, sem alteração. Todos os consertos foram de
> **CONSUMO**. O que mudou é o que se sabe sobre a camada. Registro completo em `validacao/MANIFESTO.md`
> **§89**; a regra de consumo em `seed-componentes.md` **§64.17**.

**FATO 1 — `--seed-feedback-danger-solid` e `--seed-action-destructive` são A MESMA COR com DOIS NOMES, e
a tinta é UMA SÓ.**

| | claro | escuro |
|---|---|---|
| `--seed-action-destructive` | `#C6393B` | `#FC6F6A` |
| `--seed-feedback-danger-solid` | `#C6393B` | `#FC6F6A` |
| **tinta dos dois: `--seed-text-on-action-destructive`** | `#FFFFFF` | `#521112` |
| medido | **5,19** | **5,26** |

É o mesmo papel que o Material Design 3 chama de `onError` e usa tanto no botão de erro quanto no badge de
contagem. **Não nasceu `--seed-text-on-feedback-danger-solid`**, e o motivo está escrito: seria um token
com os mesmos dois valores do que já existe, e duplicar a tinta é o caminho mais curto para as duas
divergirem numa edição futura.

> **Consequência de COBERTURA, e ela é uma pendência nomeada (AC-P3):** o contrato **MR2** do
> `guarda-tinta-marca.mjs` varre por `SUP=--seed-action-destructive` e só enxerga artefato que **declare
> esse nome**. O `banco-feedback.html` declara só o nome de feedback — por isso a MR2 devolveu `[n/a]`
> exatamente sobre o defeito FB-P1. O instrumento é parametrizável; a varredura que falta é
> `SUP=--seed-feedback-danger-solid COD=MR4 MAO=livre`.

**FATO 2 — o valor de reserva em `var()` é ANESTÉSICO, e por isso é PROIBIDO para token de cor
(contrato BT8, `seed-componentes.md` §64.17).**

```
PROIBIDO   color: var(--seed-action-primary-bg, #098475)
CERTO      color: var(--seed-action-primary)
```

O nome `--seed-action-primary-bg` **não existe nesta camada** — o canônico é `--seed-action-primary`, sem
o sufixo. Medido: **15 consumos** num único artefato, todos caindo no literal fixo, e **seis componentes**
que nunca inverteram no tema escuro. **Token consumido e não definido tem de NÃO PINTAR** — só assim a
lacuna aparece. *É a NV-01 vista pelo outro lado, e a guarda dela é a pendência **NV-02**.*

**FATO 3 — artefato que REDECLARA um par semântico pode derivar do gêmeo no VALOR, e ninguém mede isso.**

O `banco-dados.html` declarava localmente `--seed-success-text:#098475` no tema claro, enquanto o gêmeo diz
`--seed-feedback-success-text: #006C62`. Não é lacuna de token nem consumo errado: é **deriva de valor**,
nascida de o artefato ter renomeado o par. Medido: **4,28** contra o piso 4,50; com o valor do gêmeo,
**5,89**. *Pendência nomeada **AC-P4**: nenhum instrumento compara o valor de par semântico redeclarado no
artefato com o valor do gêmeo.*

**Tinta de marca sobre superfície neutra — lembrete de qual token é o certo.** O `--seed-text-brand`
(`#098475` no claro · `#66D1C2` no escuro) já existia e é o token que carrega tema. Consumir
`var(--seed-turquesa-600)` como tinta é consumir **primitivo**, que por definição não inverte: mediu
**3,31** no tema escuro. Com o token semântico: **4,60** e **8,31**.

## 5-g. A TINTA DE MARCA NÃO SOBREVIVE A NENHUMA SUPERFÍCIE DE INTERAÇÃO — nasce `text-brand-strong` (v1.19, 2026-08-20)

> Seção escrita na **nona parte**, ao fechar a pendência **HV-P5**. Ela **acrescenta** ao §5-e, que já
> dizia *"tinta de marca sobre superfície neutra: use `--seed-text-brand`, 4,60 e 8,31"* — a frase está
> certa e **estava incompleta**: aqueles 4,60 e 8,31 foram medidos **contra a página**, e nenhum outro
> fundo havia sido medido. Registro completo em `validacao/MANIFESTO.md` **§100** e em
> `seed-componentes.md` **§73**.

**A LACUNA, medida.** `--seed-text-brand` e `--seed-text-link` valem `#098475` no claro:

| superfície | valor claro | mede com `#098475` | veredito |
|---|---|---|---|
| `surface-page` · `surface-raised` | `#FFFFFF` | **4,60** | passa, com **0,10** de margem |
| `surface-subtle` · `action-neutral-hover` | `#F2F6F9` | **4,23** | **reprova** |
| `action-neutral-active` · `surface-sunken` | `#E3EBF0` | **3,81** | **reprova** |
| `row-selected-bg` | `#E8FBF7` | **4,28** | **reprova** |

> **O NÚMERO QUE FECHA A DECISÃO, e ele é o que impede este assunto de virar gosto:** para `#098475`
> alcançar 4,5 o fundo precisa de **luminância ≥ 0,978**. O cinza neutro mais escuro que serve é
> **`#FDFDFD`** — dois passos do branco puro. **NÃO EXISTE superfície de interação possível para aquela
> tinta.** Qualquer sombreado de sobrevoo perceptível a derruba. Logo escurecer a **tinta** no estado não
> é preferência: é a única saída que não desliga o estado.

**O TOKEN, e ele não traz hex novo:**

| Token | Claro | Escuro | Mede no claro | Use para |
|---|---|---|---|---|
| `--seed-text-brand-strong` | `#006C62` | `#66D1C2` | **6,32** página · **5,82** `surface-subtle` · **5,24** `action-neutral-active` · **5,89** `row-selected-bg` | **tinta de marca sobre superfície de INTERAÇÃO** — sobrevoo, pressionado, linha selecionada |

No claro o valor é o de `surface-brand-deep` e de `action-primary-hover`; no escuro é o mesmo de
`text-brand` (`#66D1C2`, que já media **8,31 a 10,16** sobre todas as superfícies escuras). **No tema
escuro nada muda de aparência em nenhum pixel** — a lacuna era só do claro, e o motivo é estrutural: no
escuro a tinta de marca é **clara** e as superfícies de interação **escurecem**, então a interação
**aumenta** o contraste em vez de consumi-lo.

**ALTERNATIVA DESCARTADA, com número:** reusar `action-primary-hover` como tinta **PASSA** (5,24 a 12,85
nos dois temas) e foi recusada por **acoplamento de propósito** — é token de **FUNDO** de botão, e uma
mudança futura no sobrevoo do botão moveria a tinta do link em silêncio. *Mesmo critério com que a v1.18
recusou `action-ghost-hover` para o sobrevoo neutro.*

**PRECEDENTE DE MERCADO, e ele é direto.** O **Carbon (IBM)** tem exatamente este par —
`$link-primary` (Blue 60 `#0f62fe`) e **`$link-primary-hover`** (Blue 70 `#0043ce`) — mais
`$link-secondary` (Blue 70), descrito como *"Secondary link color for **lower contrast backgrounds**"*.
A issue **#7647** do Carbon nomeia o **mesmo caso fundador** desta seção, verbatim:
*"The current link color for selected rows and rows with hover doesn't have enough visual contrast."*
O **GOV.UK** teve o defeito idêntico (hover `#2b8cc4` sobre branco = **3,72**) e o resolveu **escurecendo
a paleta** em 2019. **NORMA:** WebAIM, verbatim — *"the 4.5:1 (or 7:1) contrast requirement to the
background does apply to all link states."*

> ⚠ **CONSEQUÊNCIA PARA A ORDEM DO TRABALHO, e ela não estava escrita em lugar nenhum:** os dois tokens
> que nasceram na v1.18 (`action-neutral-hover` e `action-neutral-active`) são **exatamente** as
> superfícies que derrubam a tinta de marca. **Aplicar a gramática HV1-d ao acervo sem `text-brand-strong`
> teria CRIADO casos de violação de norma em massa**, em todo controle cuja tinta é de marca. *A HV-P5 era
> pré-requisito técnico da HV-P4, e não só prioridade normativa.*

**FRONTEIRA DECLARADA — o que este token NÃO resolve.** Ele é **tinta**. Onde o defeito é a
**superfície** carregar texto — a marca chapada `#11B0A0` com branco em cima, **2,71** — a saída é a que o
**§5-d** já fixou no gate de 2026-08-18: **descer a superfície** para `surface-brand-strong` `#098475`
(**4,60**). *Ali a opção de escurecer a tinta sobre a chapada (`#00352F`, 4,99) foi a **opção D** e ficou
**VETADA** pelo Rafael.*

**ERRATA declarada e corrigida nesta edição:** o cabeçalho do `seed-tokens.css` dizia **v1.17** depois de
a **v1.18** ter nascido (os dois `action-neutral-*` de 2026-08-19). O conteúdo estava em v1.18; só o
cabeçalho ficou atrasado. Corrigido junto com a v1.19.

**PENDÊNCIA NOVA (TK-P1), medida:** o bloco de tokens injetado em cada artefato **declara de qual versão
do gêmeo ele nasceu**, e nenhum instrumento mede a defasagem. Censo por comando: o acervo declara **seis**
versões — **v1.5** (1 arquivo) · **v1.7** (2) · **v1.8** (1) · **v1.9** (15) · **v1.12** (1) · **v1.17**
(23) · e **v1.19** (3, desta sessão).

## 5-f. A SUPERFÍCIE VERMELHA SÓLIDA TEM TRÊS NOMES NO ACERVO, e um deles tem VALOR DIVERGENTE (2026-08-18)

> Seção **acrescentada**. Ela não cria token nenhum — os gêmeos seguem em **v1.17**. Ela registra um fato
> de camada que só apareceu quando uma guarda foi re-rodada e o placar dela **não bateu com o registro**.
> Registro completo em `validacao/MANIFESTO.md` **§90.1**.

**O FATO, medido por comando nos 48 artefatos:**

| Nome do token | Artefatos que o declaram | Claro | Escuro |
|---|---|---|---|
| `--seed-action-destructive` | **5** | `#C6393B` | `#FC6F6A` |
| `--seed-feedback-danger-solid` | **16** | `#C6393B` | `#FC6F6A` |
| `--seed-danger-solid` | **2** (`banco-cn`, `banco-dados`) | **`#D94545`** ⚠ | `#FC6F6A` |

**Os dois primeiros são a MESMA COR com dois nomes** (já registrado no §5-e). **O terceiro é a mesma
INTENÇÃO com um valor diferente:** `#D94545` é o vermelho-**500**, e o gêmeo diz vermelho-**600**.

**O que isso custa, medido:**

| tinta | fundo | mede | piso |
|---|---|---|---|
| branco | `#C6393B` (vermelho-600, valor do gêmeo) | **5,19** ✓ | 4,50 |
| branco | `#D94545` (vermelho-500, valor divergente) | **4,30** ❌ | 4,50 |

**Hoje não há defeito, e isso foi MEDIDO, não suposto:** a varredura `SUP=--seed-danger-solid COD=MR5`
devolveu **0 PASS · 0 FAIL · 96 `[n/a]` · ZERO textos** assentando sobre esse token. *É a mesma forma da
CD-P6: o par reprova, e nenhum consumidor está em cima dele — ainda.*

**A CONSEQUÊNCIA DE INSTRUMENTO, e ela é a lição:** o contrato **MR2** do `guarda-tinta-marca.mjs` varre
por **um nome**. Enquanto os três existirem, **o censo da MR2 nunca é o censo da superfície** — e foi
exatamente por isso que o placar dela caiu de 26 para 16 textos entre duas medições sem que nada tivesse
regredido. **Placar que mede NOME e é lido como se medisse COISA é a mesma doença do placar cortado: o
número está certo e a leitura está errada.**

**PENDÊNCIAS NOMEADAS:** **AC-P5** (unificar o valor de `--seed-danger-solid` ao do gêmeo) e **MR-P3**
(unificar os três nomes, ou ensinar a guarda a varrer o conjunto). Nenhuma das duas foi executada.

**A cobertura que faltava foi feita:** `SUP=--seed-feedback-danger-solid COD=MR4 MAO=livre` — **8 PASS ·
0 FAIL · 88 `[n/a]` · 20 textos assentando sobre o segundo nome, zero violando**. Fecha a **AC-P3**.

## 6. O que este arquivo NÃO cobre (fronteiras)

- **Tokens de componente (camada 3):** nascem componente a componente, e a especificação de cada grupo vive no `seed-componentes.md`, não aqui. **Grupos JÁ emitidos nos gêmeos, em duas levas:** `field.*` (form-field, 21 tokens da §2.5), v1.21, 2026-08-25, gate **G5**; e `button.*` (12, §1.6) · `card.*` (3, §26) · `divider.color` e `list.hover` (§26-F) · `danger.item` (§27) · `wait.delay` (§17 R3-c) — 19 tokens, v1.22, mesmo dia, gate **G6**. **O que a segunda leva mudou na fronteira:** ela deixou de ser lida e passou a ser MEDIDA. A guarda `06-validacao/guardas/guarda-spec-gemeo.py` (contrato **SG1**) varre os `01-canonicos/*.md` e reprova todo custom property que o canon nomeia e o gêmeo não define — antes dela, "quais grupos ainda faltam?" era pergunta respondida por `grep` e memória, e a resposta errou por quatro caminhos diferentes numa única tentativa (família escrita com `*`, família com posição `-N`, classe CSS em BEM com `--` duplo, e contraexemplo documentado lido como pedido). **Estado medido em 2026-08-25, depois da v1.22: 10 nomes seguem sem definição no gêmeo**, e nenhum deles é "próximo grupo a emitir" — três são contraexemplos que NÃO se emite e quatro são lacunas da própria spec. A lista, com o motivo de cada um, está na entrada **v1.22** do §9. *(Redação anterior desta linha: "nascem na Fase 3" — superada: a Fase 3 fechou e a camada começou a nascer de fato em 2026-08-25.)*
- **Regras de aplicação de marca** (logo, EEny, grafismo, fotografia): `marca-seed.md` v5.0 (Fase 2, em produção).
- **Guia de integração Tailwind/shadcn dos produtos:** Fase 3.
- **E-mail:** e-mail não consome CSS variables (clientes de e-mail não suportam); o sistema de e-mail (Fase 4) usará os MESMOS valores hex inline, com este arquivo como fonte.

## 7. Pendências explícitas

0. ~~**(v1.3) Gêmeos `seed-tokens.json`/`seed-tokens.css` a regenerar** com os tokens novos da §3c~~ — **ENCERRADA na v1.4 (2026-08-09), no prazo declarado (o gate do DT).** Os dois gêmeos foram regenerados e passam a **v1.4**, restabelecendo a unidade md+json+css do cabeçalho.

   > **SUPERSEDE FORMAL da redação anterior desta pendência.** A redação da v1.3 dizia que o débito era regenerar os gêmeos "com os tokens novos da §3c" — isto é, um atraso de uma versão. **Isso estava errado, e o erro só apareceu quando os arquivos foram abertos.** Medição de 2026-08-09 sobre as cópias reais do Drive: `seed-tokens.json` e `seed-tokens.css` declaravam **`v1.1`** no próprio cabeçalho e não continham **nenhum** token do pacote mobile **v1.2** — zero ocorrências de `breakpoint`, `safe-area`, `fs-field-touch` e `clamp` nos dois arquivos. A defasagem real era de **duas versões** (v1.2 + v1.3). A v1.4 dos gêmeos fecha as duas de uma vez.
   >
   > **Causa raiz declarada:** a regra "os três arquivos formam uma unidade" existia desde a v1.0 **sem detector**. Ler o `.md` não revela nada sobre o conteúdo dos gêmeos, e o `.md` é justamente onde a versão dos três é declarada — a fonte da afirmação e o objeto da afirmação nunca se encontravam. Mesma classe do defeito que originou a regra de leitura de volta no marco v1.4 (propagação afirmada, nunca lida).
   >
   > **Correção estrutural:** nasce a guarda permanente **`validacao/paridade-tokens.py`**, que mede 3 portões — **G1 não-regressão** (nenhum token do CSS anterior some ou muda de valor), **G2 paridade** (todo token do JSON tem contraparte no CSS, salvo isentos declarados: hoje só `breakpoint`, que media query não lê), **G3 cobertura** (o inventário nominal da §3c e do pacote v1.2 está nos dois gêmeos, em light **e** dark). Placar da regeneração: **43 PASS · 0 FAIL**.
   >
   > **Achado do próprio G1, registrado por transparência:** a primeira tentativa de regeneração reescrevia o CSS inteiro a partir do JSON e **foi reprovada** — renomeou `--seed-sp-*` para `--seed-space-*` (renomear token quebra todo consumidor), perdeu `--seed-focus-ring` (composto que só existe no CSS, sem contraparte no JSON) e serializou sombras, famílias tipográficas e curvas de bezier como estrutura DTCG em vez de valor CSS. A entrega final foi por **edição cirúrgica** sobre o arquivo anterior: zero regressão por construção, não por conferência. *Alternativa descartada:* aceitar a regeneração total e corrigir os 3 achados — descartada porque o método que produz 3 perdas detectadas produz as não detectadas também.
   >
   > **Verificação cruzada da entrega:** os 26 tokens da §3c foram conferidos linha a linha entre esta seção e os hex efetivamente gravados nos gêmeos — **26/26 batem, 0 divergências**. Contagem do CSS: `:root` 156 → 191 tokens (+35 = 26 dataviz + 4 fluidos + 1 field-touch + 4 safe-area); bloco dark 61 → 87 (+26). Chaves balanceadas, zero declarações duplicadas, `prefers-color-scheme` com os 26 espelhados.

1. **Validação visual pelo Rafael** do preview (`seed-tokens-preview.html`) — rampas e semânticos em light/dark. Qualquer ajuste de gosto (ex.: dark mais quente/frio) é feito na fonte e regenerado.
2. **CMYK "U" (superfície fosca)** das cores: o Manual 2018 previa e não preencheu. Segue "(a confirmar)" — só relevante se houver impressão em papel fosco com fidelidade crítica.
3. **Teste em tela real dos produtos:** os valores dark foram derivados por método e auditados por contraste, mas merecem uma passada de olho no ERP real antes de virarem lei.

## 8. Registro de decisões desta entrega (com alternativas descartadas)

| Decisão | Porquê | Alternativa descartada |
|---|---|---|
| OKLCH como espaço de geração | Uniformidade perceptual entre rampas; padrão 2026 | HSL (distorce luminosidade percebida entre matizes) |
| Âncora automática por luminosidade | Zero alteração dos hex canônicos; sem inversões | Forçar canônicos no stop 500 "por convenção" (gerou inversões na v1 do algoritmo) |
| Verde = turquesa-600 (rampa única com âncora dupla) | É a mesma família colorimétrica; evita rampa duplicada | Rampa "verde" separada (near-duplicata da turquesa, dobraria manutenção) |
| Vermelho funcional #D94545 | Já estava em uso; continuidade > invenção | Vermelho novo "harmonizado" (mudaria telas existentes sem ganho) |
| Success = família turquesa | Na SEED, êxito é verde da marca; ícone desambigua | Rampa verde-folha extra (cor fora da marca) |
| Dark tintado no hue do cinza | Coerência de marca; direção já esboçada no DS v1 | Cinza neutro puro (genérico) ou dark turquesa forte (cansativo) |
| Proporção 70/20/10 no lugar dos 45% de turquesa | Contenção editorial; mata o "efeito infantil" das ondas | Manter 45% (causa raiz do problema) |
| Amarelo=acento oficial, dourado=trabalho | ~25° de distância de matiz; uso intercambiável lia como inconsistência | Remover um dos dois (perderia Pantone canônico e o dourado no dataviz) |
| Azul: livre na UI (info), contido na marca; ação nunca azul | Botão azul = default genérico; verde institucional é assinatura AA | Azul como cor de ação (ERP ficaria com cara de sistema genérico) |
| ~~2 famílias tipográficas (Montserrat + JetBrains Mono)~~ **3 famílias — SUPERSEDIDA em 2026-08-20** (ver errata na §2.5): principal Montserrat · secundária JetBrains Mono · **terciária `--seed-font-expressive`, exclusiva de marketing alegórico/festivo** | Cobertura completa com mínimo de manutenção; padrão dos grandes sistemas. A terceira entra com **escopo estreito e declarado**, que é o que impede o retorno do uso onipresente da Indie Flower | ~~3ª família serifada (necessidade inexistente hoje)~~ — **a alternativa não foi descartada, foi DECIDIDA pelo Rafael.** Descartado agora: nomear o token `--seed-font-display` (nomearia tamanho, não propósito) |
| Breakpoints = escala Tailwind, fora do CSS var (v1.2) | Stack real (Lovable/shadcn) já é Tailwind; media query não lê custom property — fingir token CSS seria decorativo | Manter 640/960 do HTML v1 (fricção de configuração em todo produto); breakpoint como `--seed-*` (tecnicamente inerte) |
| Tipografia fluida com clamp rem+vw (v1.2) | 1 token por nível, sem saltos de media query; termo rem preserva o zoom 200% (WCAG 1.4.4) | Media queries por nível (saltos, 2× tokens); clamp com vw puro (reprova zoom 200%) |
| Fonte de campo 16px via `pointer: coarse` (v1.2) | Resolve o zoom automático do iOS na causa; detector pega TOQUE (tablet incluso), não largura | `maximum-scale=1` (bloquear zoom viola WCAG e pune baixa visão); gatilho por breakpoint (falha em tablet largo) |

## 9. Versionamento

| Versão | Data | Mudança |
|---|---|---|
| 1.23 | 2026-08-26 | **A CAMADA 3 FECHA (SG1 a ZERO FAIL) e a COLISÃO DE ALTURA, aberta em 2026-08-15, é RECONCILIADA.** *Para quem lê sem ter visto a conversa:* a entrada v1.22 desta mesma tabela terminava com uma lista chamada **"o que fica para a sessão principal"** — decidir o par dark do `divider-strong`, marcar `switch-off-bg`/`slider-track` como medição pendente, fixar a curva do `ease-out`, isentar o `input-affix` e abrir a pendência do estado OFF no tema claro. **Esta versão fecha a lista inteira**, e vale dizer por quê: *lista de pendência que ninguém fecha vira lista de desculpa, e a única prova de que ela servia é ela acabar.* Todas as seis decisões vieram do Rafael em 2026-08-26, no gate das nove peças da Onda 2. **① O SWITCH — e a medição achou três coisas, não uma.** Ele decidiu: *"acredito que tem que conseguir um tom que atenda o piso. analise e decida"*. (a) O tom é **cinza-500 `#788F9D` = 3,38:1**, primeiro degrau da escala acima do piso — o cinza-400 ainda reprova, com 2,53. Zero cor nova (§14.1). (b) ⭐ **Medir "3:1 sobre a página" era medir METADE do componente:** o thumb é BRANCO, e branco sobre cinza-300 dá os mesmos **1,91** — *o thumb sumia dentro do trilho*, e a posição do thumb é o único canal que separa ON de OFF (K3: nunca "ON/OFF" escrito no trilho). Cinza-500 conserta os dois pares de uma vez. (c) ⭐⭐ **No tema ESCURO quem reprovava era o estado LIGADO, não o desligado** — thumb cinza-100 sobre o trilho ligado dá **2,25** — e ninguém tinha visto porque a cláusula só mandava medir o OFF. A saída não precisou de cor nova: *"o que vai sobre a superfície de ação"* já é par medido e canonizado (`--seed-text-on-action-primary`), e o thumb de um switch ligado é exatamente isso — **7,39:1**. Nasce `--seed-switch-thumb-on`; no claro ele coincide com o thumb desligado, e **isso é a regra colapsando, não duplicação**. (d) Dois erros de NOME na mesma linha da spec, consertados junto: ela apontava para `--seed-action-primary-bg`, o **token fantasma** da FF-P2/FF-P3, e dizia "turquesa-400 sobre dark" quando `action-primary` escuro é `#66D1C2` = turquesa-**300**. ⭐ *Spec que aponta para nome morto passa em toda guarda de valor, porque não há valor nenhum para conferir.* **② O SLIDER tinha a mesma doença, e ela só apareceu porque o switch foi medido** — cinza-300, os mesmos 1,91. Passa a cinza-500. ⚠ **Mas aqui a saída é diferente, e a diferença importa:** nenhum degrau atende os dois pares, porque o vazio precisa ficar longe do branco da página *e* longe do turquesa do preenchido, e o turquesa-600 mora no meio da escala (cinza-300 dá 2,40 contra o preenchido, cinza-500 dá 1,36). **A decisão não foi escolher o menos pior; foi ver o que cada par carrega:** o valor tem canal **textual** garantido pela própria spec (*"valor corrente visível SEMPRE"*) e canal de **forma** no thumb de 24px com borda, então a divisão preenchido/vazio é o **terceiro** canal e fica **decorativa declarada, com o número escrito** (1,36 claro / 2,59 escuro) — mesmo tratamento de `card-border` e `divider-color`. *Exigir 3:1 ali seria criar cláusula que o canon nunca teve, e cláusula nova é decisão dele.* **③ E OS DOIS TINHAM O MESMO DEFEITO ESTRUTURAL, que era o que ele já havia apontado:** `--seed-switch-off-bg` e `--seed-slider-track` eram declarados **só no tema escuro e com escopo de elemento** (`[data-theme="dark"] .seed-switch{…}`) — e como não existiam no gêmeo, **no tema CLARO o `var()` não resolvia e o controle ficava sem fundo nenhum**. Com o token no gêmeo, as duas regras de escopo somem e o defeito morre pela raiz. ⭐ *Token declarado só num tema não é "tema faltando" — é um estado que não existe na metade do sistema.* **④ A CURVA: ele mandou "teste os 2 e decida", e o teste devolveu uma resposta melhor que "escolha um".** Resolvendo o bézier em 21 instantes de um movimento de 120 ms e convertendo para tempo — porque milissegundo é o que o olho pode ou não perceber, e "parecem diferentes no papel" não é medida de nada: `.2,.8,.4,1` e `.2,.7,.3,1` diferem no máximo **1,5% do percurso** e **0,3 ms**. A 60 Hz um quadro dura 16,7 ms, então **a diferença é 1/56 de quadro e não existe em nenhum monitor** — *eram dois nomes para a mesma curva*. Escolhida a de maior uso (3 artefatos contra 2), que também faz o conserto ser de 2 arquivos e não 3. ⭐⭐ **E o mesmo teste respondeu a pergunta que ninguém tinha feito:** `--seed-ease-out` deve existir, ou era apelido de `--seed-ease-productive`? Contra o productive a diferença é **36,8% e 24,9 ms — 83 vezes maior** que a diferença entre as candidatas. *São curvas diferentes de verdade, então o token merece existir.* Sem o número, isso se responderia por gosto. **⑤ O DIVISOR FORTE: a v1.22 recusou emiti-lo, com um argumento bom — e o que mudou não foi a opinião, foi a medição.** A recusa se apoiava no "1,91 light" da spec. ⚠⚠ **Esse número não existe:** medidas as **cinco** superfícies do tema claro contra o `border-default`, nenhuma dá 1,91 (page/raised/overlay = **1,49**; subtle 1,37; sunken 1,23). O número foi **transplantado** — 1,91 é o que o `border-subtle` **escuro** dá sobre a página escura. ⭐ *O número estava certo em algum lugar do arquivo; só estava grudado no token errado.* E o irmão só batia porque foi medido contra **outro fundo**: o "1,75 dark" do `divider-color` não sai da `surface-page` (1,91) — sai da `surface-subtle`. ⭐⭐ **Régua: contraste sem fundo declarado não é um número, é uma família de números** — e foi variando o fundo, uma condição por vez (§14.5), que os três valores se explicaram. Sem o 1,91, o cinza-600 do consumidor vivo se revela **dialeto local** e vale a regra simétrica do irmão: **border-default nos dois temas** (1,49 / 2,84, decorativo declarado). **⑥ O `--seed-input-w-md` NÃO foi emitido, e a saída certa não era nenhuma das duas que a SG1 oferece.** O nome aparecia uma vez, num exemplo de HTML da §2.5: `style="max-width:var(--seed-input-w-md,320px)"` — um `var()` apontando para um token que nunca existiu, que é **o mesmo defeito do switch**. ⭐ *Exemplo de código num canônico é código que alguém copia; citar nele um `var()` que não resolve não é citação, é ensinar o defeito.* O exemplo passou a escrever `320px` direto e o nome saiu do canônico. ⚠ E aí nasceu a **6ª classe de falso positivo da SG1**: o comentário que EXPLICA a remoção cita o nome, e a guarda reprovou de novo — com razão, porque para ela nome no arquivo é nome no arquivo. Reescrever o comentário sem o nome faria a guarda passar **e apagaria a lição**, trapaça que a isenção do `--seed-tq-300` já proíbe. Isentado com o motivo escrito. As seis classes hoje: curinga · placeholder maiúsculo · classe BEM · contraexemplo documentado · nome de exemplo em diagrama · **nome citado no registro da própria remoção**. Todas dizem *citar não é pedir*. **⑦ A ALTURA DE CONTROLE — ele mandou "reconcilie para todos seguirem o padrão".** De 2026-08-15 a 2026-08-26 o DS teve **três réguas com dois números**: 32/40/48 em `--seed-control-*` (v1.14, genérica, herdada do Fluent) contra 32/44/52 em `--seed-button-height-*` e `--seed-field-height-*` (fixados por escrito na §1.6 e na §2.5, com a decisão explícita *"md = 44px (não 40px)"*). O `sm` já coincidia. ⚠ **O desempate não foi por gosto: medido, NENHUM artefato do acervo consome `--seed-control-*`** — os três consumidores são a spec, a guarda de paridade e o gêmeo. *A régua genérica era a de papel; vence quem tem spec.* ⚠ E **o argumento certo para o 44 não é o SC 2.5.8**, que pede 24×24 (AA) e que 40 também cumpriria: o 44 é **fundamento próprio do DS**, mais generoso que a norma — e é por ser decisão nossa que ele precisava ser **reconciliado** em vez de deduzido de fora. O preset compacto (28/32/40) não muda: é densidade para tela de dado com mouse, e fica abaixo do alvo de toque de propósito. **PLACARES.** `SG1`: **140 PASS · 7 FAIL · 6 [isento] → 147 PASS · 0 FAIL · 7 [isento]** — a camada 3 não tem mais nenhum nome que o canon cite e o gêmeo não defina. `paridade-tokens.py`: **103 → 110 PASS · 0 FAIL**. ⚠ **E esta é a primeira leva que NÃO é adição pura** — as v1.21 e v1.22 podiam se gabar disso; esta muda dois valores, e **o G1 acusou**, exigindo supersede declarado (`SUPERSEDES_V123_ROOT`). *Declarar é o preço de mudar valor, e o preço é barato.* `:root` 323 → **330** (+7), dark 129 → **135** (+6). ⭐ E a linha `info:` do G6, que desde a v1.22 imprimia **"COLISÃO DECLARADA de altura"** a cada execução, passa a imprimir **"RÉGUA ÚNICA desde a v1.23: md=44px · lg=52px nos três grupos"** — e continua imprimindo os três pares, de modo que, se algum dia um deles derivar, a divergência aparece na mesma linha que hoje diz que não há nenhuma. *O oposto de declarar um problema não é silêncio: é declarar que ele fechou.* **CONSUMIDORES.** As duas bancadas que carregavam a curva divergente (`banco-feedback`, `banco-superficies`) foram atualizadas pelo `reinjeta-tokens.py` — ⭐ *o build de quem não tem gerador fez sozinho o trabalho, e sem chance de errar um hex* —, e o mesmo build apagou o dialeto do divisor (cinza-600 → `#4D606C`). ⚠ **O que ele NÃO faz, por regra declarada, quase me custou as duas bancadas:** ele não acrescenta token que o preview não consumia. Ao apagar as regras de escopo local do switch e do slider eu deixei `banco-formfield.html` consumindo `var()` de tokens que não estavam escritos nele — e o arquivo carrega **cópia embutida**, não lê o gêmeo. Os dez tokens foram acrescentados aos blocos `:root` e dark, e o reinjetor, rodado em seguida, confirmou **0 divergências** contra o gêmeo. ⭐ *Apagar dialeto local só é seguro depois de o canônico chegar ao arquivo — e num preview de cópia embutida, "chegar" quer dizer estar escrito nele.* |
| 1.22 | 2026-08-25 | **SEGUNDA LEVA DA CAMADA 3 — 19 tokens em seis grupos, e a classe da AD-P6 passa a ter INSTRUMENTO.** *Para quem lê sem ter visto a conversa:* a v1.21 (mesmo dia) emitiu o primeiro grupo de componente dos gêmeos, o form-field, porque o `seed-componentes.md` descrevia 21 tokens `--seed-field-*` que **nenhum artefato podia consumir** — a spec citava, o gêmeo não definia. Esta entrada fecha a **mesma classe** para os grupos seguintes. **O que mudou no método, e é o mais importante desta versão:** a pergunta "quais grupos ainda faltam?" era respondida por `grep` e memória, e errou por **quatro caminhos diferentes numa única tentativa** — família escrita com `*` (`--seed-field-*` não é um token), família com posição genérica (`-N`), classe CSS em BEM lida como token (o `--` duplo de `.seed-btn--primary`) e **contraexemplo documentado lido como pedido**. Nasce então a guarda **`06-validacao/guardas/guarda-spec-gemeo.py`** (contrato **SG1**), que varre os `01-canonicos/*.md` e reprova todo custom property que o canon **nomeia** e o gêmeo `seed-tokens.css` **não define**, imprimindo nome, quem cita, quantas vezes e a linha de contexto. **Placar SG1: 121 PASS · 29 FAIL · 3 `[isento]` antes desta edição → 140 PASS · 10 FAIL · 3 `[isento]` depois** (cobertura: 153 nomes distintos em 10 canônicos, conferidos contra 323 definidos no gêmeo). **OS 19 EMITIDOS, cada um com valor e origem.** *Botão (12), `seed-componentes.md` §1.6 l.126-148* — a spec escreve o bloco CSS inteiro, com o par dark explícito e a regra que o gerou verbatim (*"token de componente que referencia primitivo DEVE declarar o par dark — primitivo não troca de modo sozinho"*, correção v0.5): `button-radius` 8px (= radius-md) · `button-font-weight` 600 (= fw-semibold) · `button-height-sm/md/lg` 32/44/52px (fixados) · `button-gap` 8px (= sp-2) · `button-secondary-border` turquesa-600 `#098475` / turquesa-300 `#66D1C2` · `button-secondary-text` turquesa-800 `#005048` / turquesa-100 `#CDF3EC` · `button-outline-border` cinza-600 `#617683` / cinza-400 `#90A6B3` · `button-ghost-text` turquesa-700 `#006C62` / turquesa-300 `#66D1C2` · `button-toggle-on-bg` turquesa-800 `#005048` / turquesa-300 `#66D1C2` · `button-toggle-on-fg` `#FFFFFF` (único valor de cor da leva que a spec fixa em hex, não em alias) / turquesa-900 `#00352F`. *Cartão (3), §26 l.1954*: `card-bg` = surface-raised · `card-border` = border-subtle (**borda decorativa declarada**: 1,21 claro / 1,75 escuro, abaixo do piso 3,00 da SC 1.4.11 **de propósito**, porque a separação é carregada por espaço + raio + superfície + tipografia) · `card-radius` 12px (= radius-lg → radius-6). *Divisor (1), §26-F l.1976*: `divider-color` = border-subtle. *Lista (1), §26-F l.2000*: `list-hover` = surface-subtle no claro e o hex `#273137` no escuro — **a assimetria é da spec e foi preservada**, porque `#273137` é o `surface-overlay` do escuro, não o `surface-subtle` (`#141D23`), e é o que os quatro consumidores vivos renderizam. *Item destrutivo de menu (1), §27 l.2181*: `danger-item` = vermelho-700 `#A5272A` / vermelho-200 `#FFC2BD`. *Espera (1), §17 R3-c l.1687*: `wait-delay` **1000ms**, número que a própria linha fixa por escrito (*"default 1000ms"*), fundamentado no limite de 1s de Nielsen, com revisão por telemetria real do ERP na F4 declarada ali como *"pendência declarada, não decisão aberta"*. **OS 10 QUE NÃO SE EMITE, com o motivo — e eles são a lição desta versão, porque nem todo nome citado é um pedido.** ⓐ **Três contraexemplos documentados** (*documentação de um defeito CITA o defeito, e citar não é pedir*): `--seed-button-primary-bg` aparece só no **diagrama de arquitetura** do §1 deste arquivo e do `seed-email.md` ("3. COMPONENTE — exceção local"), como ilustração do conceito de camada 3 — e a §1.6, que é a spec real do botão, **deliberadamente não o cria**, porque o botão primário consome `--seed-action-primary` sem divergir (a regra do §1 daqui: *"a camada 3 só nasce quando um componente precisa divergir do semântico"*); `--seed-input-affix` está na coluna **Descartado** da tabela de decisões do §3.10 (*"duplicaria help-text sem caso de uso divergente"*), com a §3.6 dizendo em texto *"Tokens novos: nenhum de cor"*; `--seed-danger-solid` é nomeado no `mapa-cobertura-ds.md` §21 dentro da tabela da **"cegueira de nome"** — a mesma superfície vermelha sólida vive no acervo sob três nomes, e este é justamente o que carrega o **valor divergente** (`#D94545` contra `#C6393B`), já registrado como pendência **AC-P5** e **MR-P3**; emiti-lo canonizaria o defeito. ⓑ **Quatro lacunas reais da spec** (nome sem origem de valor declarada — §14.1: valor que não existe no canônico não se cria): `--seed-input-w-md` aparece **uma vez**, dentro de um exemplo HTML de `style` embutido, como `var(--seed-input-w-md,320px)`; o `320px` é *fallback* de CSS, não declaração, não existe escala de largura (`-w-sm`/`-w-lg`) e não há medição nem racional — emitir inventaria uma escala de um membro só. `--seed-divider-strong`: a §26-F fixa o alias (border-default) e mede **1,91 apenas no claro**, sem declarar o par dark, e o único consumidor vivo (`banco-superficies.html`) usa cinza-600 `#617683` no escuro, que **não** é o border-default dark (`#4D606C`) — emitir qualquer um dos dois lados criaria contradição com o consumidor ou invenção de valor. `--seed-switch-thumb`: a spec diz "branco / cinza-100", mas a bancada `banco-formfield.html` **fixa `#fff` nos dois temas** e não consome o token; divergência sem decisão registrada. `--seed-ease-out`: a spec o **usa** quatro vezes e **nunca fixa a curva**, e o acervo tem **dois valores diferentes** rodando — `cubic-bezier(.2,.8,.4,1)` em três artefatos e `cubic-bezier(.2,.7,.3,1)` em dois (medido por varredura nas bancadas); o gêmeo não tem `ease-out`, só `ease-productive`/`ease-expressive`. ⓒ **Três de dependência circular com o fantasma:** `--seed-switch-off-bg` e `--seed-slider-track` têm o alias condicionado a uma medição **que nunca foi feita** (a própria spec escreve *"3:1 sobre a página: medir na produção do preview"*) — e o valor que ela propõe **não passaria**: cinza-300 `#ACBECA` sobre a página clara mede **1,91**, medido aqui, contra o piso de 3,00 que a linha exige; o único consumidor declara **só a metade escura**, e com escopo de elemento (`[data-theme="dark"] .seed-switch{…}`), o que deixa o estado OFF do tema claro com `background` inválido — defeito real, medível, e que merece pendência própria. `--seed-switch-on-bg` tem como origem declarada o `--seed-action-primary-bg`, que é **token fantasma isento na SG1** (FF-P2/FF-P3), e o valor dark que a spec lhe dá (turquesa-400) **contradiz** o `--seed-action-primary` vivo do tema escuro (turquesa-300 `#66D1C2`), que é o que a bancada de fato renderiza — além de o componente não divergir do semântico, o que pela regra do §1 proíbe criar a camada 3. **VERIFICAÇÃO DE SUPERSEDE, feita antes de emitir cada valor** (a régua que a v1.21 pagou caro: *spec desatualizada que ninguém anota vira token errado*). Três decisões posteriores foram achadas e **nenhuma muda valor** dos 19: **CD-P7** (2026-08-17, fechada) decidiu que os 93 botões com borda abaixo de 3:1 **não são defeito** de SC 1.4.11, porque rótulo legível já identifica o controle — é veredito sobre conformidade, não sobre valor; **MR-P1/MR-P2** (2026-08-17) reescreveram a tinta sobre fundo de marca, mas na família `text-on-*`, e o registro diz explicitamente que *"o botão primário não muda de aparência"*; **CP-P4** (2026-08-15) supersedeu a **forma** de aplicar a borda do cartão (de `border` para o par anel-de-1px + sombra), sem tocar no valor do token. Os consumidores vivos foram conferidos um a um e **concordam com a spec em todos os 19** — `banco-componentes.html` (l.406-411) já declarava os seis tokens de cor do botão com os mesmos aliases, `banco-superficies.html` os três do cartão e o divisor, quatro bancadas o `list-hover` e duas o `danger-item`. **PLACARES, antes e depois.** `paridade-tokens.py`: **85 → 104 PASS · 0 FAIL**, com o **gate novo G6** (irmão do G5: presença nos dois gêmeos, fidelidade alias→valor e espelho `prefers-color-scheme` idêntico ao `[data-theme="dark"]`); o G6 imprime a cada execução uma linha de INFORMAÇÃO com a colisão de altura, para que ninguém a descubra por acidente. G1 estrito contra o CSS v1.21 real: **0 sumidos, 0 alterados, `:root` 304 → 323 (+19), dark 118 → 129 (+11)** — adição pura provada, não afirmada. `paridade-previews.py`: **505 PASS · 0 FAIL**, inalterado. `guarda-valor-gemeo.mjs` (contrato AC5, artefato × gêmeo no Chrome real): **40 PASS · 0 FAIL** nos dois lados, com a medição feita duas vezes variando UMA condição (o gêmeo) — contra o v1.21: 11 `[achado]`, 5.556 valores comparados, 76 declarações de dialeto local; contra o v1.22: **10 `[achado]`, 5.588 valores comparados (+32), 60 declarações de dialeto local (−16)**. Ou seja: 16 redeclarações que eram "dialeto local, ninguém confere" viraram valor conferido contra o gêmeo, nos dois temas, e todas passaram. **PROVA DE CONSUMO** (cobaia mínima no scratchpad, fora do repositório, ligada ao gêmeo real por `file://` e sem repetir nenhum valor literal; Chrome real pelo contrato `ambiente.mjs`, medição por `getComputedStyle`): **38 PASS · 0 FAIL** — 19 tokens × 2 temas. E a **contraprova**, que é o que dá sentido ao número: a mesma cobaia apontada para o gêmeo v1.21 devolve **0 PASS · 38 FAIL**, com as cores caindo em `rgba(0,0,0,0)` e o delay em `0s` — a camada é medida de verdade, e reprova quando não existe. **COLISÃO DECLARADA E NÃO RESOLVIDA, com os três números lado a lado, para decisão do Rafael:** `--seed-button-height-md/lg` = **44/52px** (§1.6) e `--seed-field-height-md/lg` = **44/52px** (§2.5, decisão explícita *"md = 44px (não 40px)"*, alvo de toque WCAG) contra `--seed-control-md/lg` = **40/48px** (v1.14, régua genérica de altura de controle). Dois números para o mesmo degrau da escala, agora em três grupos. Emitido como cada spec fixa; reconciliar é decisão de canônico, não dos gêmeos. **O QUE FICA PARA A SESSÃO PRINCIPAL, porque é promoção de texto canônico e não emissão de token:** anotar no `seed-componentes.md` que a §3.6/§3.10 já resolveram o `input-affix` (para a SG1 poder isentá-lo em vez de reprová-lo), decidir o par dark do `divider-strong`, marcar o `switch-off-bg`/`slider-track` como medição pendente, fixar a curva do `ease-out` num dos dois valores que já rodam, e abrir a pendência do estado OFF do switch no tema claro. |
| 1.21 | 2026-08-25 | **A CAMADA 3 (componente) COMEÇA A EXISTIR NOS GÊMEOS — form-field, fecha a AD-P6.** O defeito, medido: `seed-componentes.md` §2.5 (validada pelo Rafael em 2026-08-02, v0.6/v0.7) especifica 21 tokens `--seed-field-*` com contraste medido par a par; `seed-field-` aparecia **116 vezes** na spec e **ZERO** nos gêmeos — a camada era perfeitamente descrita e inconsumível, e o ERP (resultado nº 1 do projeto) consome exatamente ela. A emissão: **adição pura** (nenhum valor anterior muda), cada token gravado como o hex RESOLVIDO do alias que a §2.5 declara (ex.: `field-label` = cinza-900 `#242E34`), nos três blocos do CSS (`:root`, `[data-theme="dark"]` e o espelho `prefers-color-scheme`) e no grupo `semantic.field` do JSON — **com UMA exceção obrigatória, achada pela verificação de colisão com decisão posterior**: `field-border` NÃO segue a §2.5 l.400 (cinza-600), porque a **CD-P2 (2026-08-17, fechada)** a supersedeu — o alias vigente é `--seed-border-interactive` (cinza-500 `#788F9D` nos dois temas; medido 3,13 claro / 5,05 escuro, o local degradava na inversão 4,74→3,21), e a bancada `banco-formfield.html` já renderiza assim desde CD-P2; as variantes de estado (`-hover/-error/-success/-warning`) não migraram, por decisão da própria CD-P2. A colisão foi flagrada pela `guarda-valor-gemeo.mjs`, que comparou a emissão com o consumidor vivo — a primeira emissão seguia a §2.5 verbatim e reprovou. Estrutura fixada pela spec: alturas **32/44/52px** — o md=44 é decisão explícita do canônico ("md = 44px (não 40px)", alvo de toque WCAG) e **coexiste declaradamente** com a régua genérica `--seed-control-md` 40px da v1.14; reconciliar é decisão de canônico, apontada ao decisor. **Guarda nova: gate G5** na `paridade-tokens.py` — presença nos dois gêmeos, **fidelidade alias→valor** (se o token-base mudar e o field não seguir, reprova — mata a fossilização da classe "defasado e invisível" do reinjeta-tokens) e, pela primeira vez, **o espelho `prefers-color-scheme` é lido por um gate** (antes um token esquecido lá era invisível). Placar: **85 PASS · 0 FAIL** (64 anteriores + 21 do G5); G1 estrito contra o CSS v1.20 real: 0 sumidos, 0 alterados, +21 `:root` / +15 dark. Prova de consumo no Chrome real (contrato `ambiente.mjs`): 6 tokens consumidos por uma cobaia de scratchpad (altura, raio, fundo, borda, ajuda, erro) e medidos no render por `getComputedStyle` — 9 medições · 9 PASS nos dois temas. Divergências INTERNAS da §2.5 achadas na emissão (spec escrita antes da implementação, registradas para o gate, não corrigidas aqui): (a) o comentário do `readonly-bg` claro diz "sobre cinza-50" e o `surface-sunken` vigente é cinza-100 `#E3EBF0` (o alias vence, o número 12,75:1 está defasado); (b) as medições dark citam "dark-default `#141D23`", que hoje é o `surface-subtle` (a página dark é `#0B1419`) — e a bancada `banco-formfield.html` carrega `--seed-field-readonly-bg: #141D23` LITERAL no bloco dark (resolução da era da spec), divergindo do alias vigente `surface-sunken` = `#0B1419`; (c) a §2.5 l.400 (`field-border` = cinza-600) está SUPERSEDIDA pela CD-P2 e a tabela da §2.5 nunca recebeu a anotação — promover a nota no `seed-componentes.md` é da sessão principal. **Nota de lacuna desta tabela:** as linhas v1.13–v1.20 nunca foram escritas aqui (mesma classe da errata que a v1.11 registrou e restaurou para v1.7–v1.10); lacuna apontada ao decisor em 2026-08-25 — não restaurada nesta edição porque reconstrução histórica não é emissão de token. |
| 1.12 | 2026-08-14 | **`border-interactive` — FECHA A SH-P1/PN-P5** (aberta desde o bloco 6A, 2026-08-11). Fronteira de componente interativo (SC 1.4.11): promoção do empréstimo declarado do `cinza-500` `#788F9D` a semântico, mesmo hex nos dois temas por medição (seis superfícies, 3,11–5,51, todas ≥3,0), slot dark declarado de propósito (coincidência medida, não invariância). Alternativa `cinza-600` descartada com número (passa, mas mudaria cor renderizada aprovada em gate sem motivo). Gatilho: regra GI2 — a camada 2 foi editada pela CP-P3 (v1.11) e o Rafael mandou fechar na mesma janela. Gêmeos na MESMA edição; `paridade-tokens.py` **52 · 0**. O campo de busca do shell passa a consumir o semântico (preview v0.3). Racional completo na nota do §3. |
| 1.11 | 2026-08-14 | **Semânticos de COMPOSIÇÃO E CHROME (CP-P3 · SUP-6 em escopo mínimo) — nova subseção no §3.** Entram, todos INVARIANTES de tema (sem redeclaração no bloco dark, de propósito): `rail-background` (gradiente `turquesa-700 → turquesa-800` do CP20, adotado no gate G2; extremos medidos 6,32/9,37) · `chrome-overlay-hover`/`-active` (véu branco .12/.14 sobre a rampa da marca — alphas fixados **depois** de medição em COMPOSIÇÃO: rótulo branco sobre overlay composto em cada extremo = 4,88/6,82 e 4,68/6,50, todos ≥4,5) · `entity-1…6` com **tinta por posição** `entity-N-ink` (paleta fechada do CP23, gate G3; admissão CP22 medida: 5,11/5,30/5,63/9,37/6,43/6,68) · `marker-now` (`turquesa-600` fixo, CP24/G4, ≥3,0 contra as cinco superfícies canônicas). Gêmeos JSON+CSS na MESMA edição (v1.11), `paridade-tokens.py` **52 PASS · 0 FAIL** (G1 sem regressão: nenhum valor anterior muda — é ADIÇÃO). Motivação: pendência CP-P3 do `seed-composicao.md` (regeneração do shell, que também **fecha a errata E-CP-01** — o C1 deixava de consumir a categórica). **Errata desta edição, fechada pela regra GI2:** a tabela deste §9 estava parada na v1.6 — as entradas v1.7–v1.10 nunca foram escritas aqui (mesma classe da E-6C-01 do `seed-componentes.md`: quem bumpa o título escreve a entrada na mesma edição); restauradas abaixo a partir das notas inline deste arquivo e do MANIFESTO, marcadas como retroativas. |
| 1.10 | 2026-08-14 | *(entrada retroativa, escrita na v1.11)* **Normalização do `focus-ring`** — o tema claro deixa de consumir o primitivo `--seed-branco` e passa ao semântico `--seed-surface-page` (o que o escuro já fazia); cor renderizada idêntica, muda a EXPRESSÃO. Achado veio de fora: `paridade-previews.py` acusou os previews, e eles estavam mais corretos que o canônico. Racional completo na nota do §3. |
| 1.9 | 2026-08-13 | *(entrada retroativa, escrita na v1.11)* **SUPERSEDE DA TINTA DE TEXTO** — `text-primary/secondary/muted` migram da família cinza para a família turquesa da marca nos dois temas (`#0B3330`/`#2F5A54`/`#40706A` no claro), com supersede formal da restrição "nenhum hex novo" (valores entram como SEMÂNTICOS). Fecha na mesma edição a errata do `text-muted`, que REPROVAVA (2,80–3,38 no claro). Racional, tabela e alternativas descartadas na nota do §3. Fecha o PN-P1. |
| 1.8 | 2026-08-14 | *(entrada retroativa, escrita na v1.11)* **Sub-bloco DP (mapas):** adição de `chart-geo-base` (território de contexto) e `chart-geo-boundary` (fronteira de município, piso 3:1). Nenhum valor anterior muda. Nota na §3c; errata E19 relacionada (chart-grid tem o mesmo hex de no-data). |
| 1.7 | 2026-08-11 | *(entrada retroativa, escrita na v1.11)* **`chart-no-data-hatch`:** a tinta das linhas da hachura ganha token próprio (a E3 provou que papel de desenho sem token toma emprestado o de outro papel — era cat-5-stroke e virou violeta na v1.5). Medido contra o preenchimento: 3,93/3,84. |
| 1.6 | 2026-08-11 | **Promoção da categórica ESTENDIDA da §3c a `estável`**, por "aprovo" explícito do Rafael sobre o lote de formalização da Fase 5 (o gate visual havia acontecido em 2026-08-10; o lote formalizou o que estava só nos previews). **Nenhum valor de token muda nesta versão** — é mudança de estado. Os gêmeos `seed-tokens.json` e `seed-tokens.css` acompanham para v1.6 **para preservar a unidade md+json+css declarada no cabeçalho**, seguindo o precedente da v1.4 (que também foi uma promoção de estado). *Alternativa descartada:* declarar o estado sem bump de versão, deixando os três em v1.5 — economizaria uma edição, mas criaria um arquivo cujo rótulo de versão não distingue "proposto" de "aprovado", que é exatamente a informação que o gate produz. **Achado colateral registrado no `seed-dataviz.md` v0.6 §5 (errata E3):** o supersede da categórica teve uma consequência não intencional — o `cat-5`, que na v1.0 era cinza-400 e servia de referência neutra no gráfico do alerta ET5, virou **violeta** na v1.5; referência de comparação não pode carregar cor de categoria viva, e o ET5 passa a consumir tinta neutra. É a classe de risco que qualquer troca de paleta cria: quem usava uma posição categórica como "neutro" perde o neutro em silêncio. |
| 1.5 | 2026-08-11 | **Categórica ESTENDIDA (§3c) — supersede formal da categórica v1.0 e da restrição "nenhum hex novo" do DT.** Racional medido: a marca tem só **3 matizes livres para dado** (turquesa ~170°, dourado/amarelo ~36–50° — mesma família —, azul ~192–197°; vermelho e cinza são reservados), então nascem **2 matizes exclusivos de dataviz que nunca aparecem em UI** (padrão IBM Carbon/GitLab): magenta 332° (`#CD518B`/`#E8A1C2`) e violeta 268° (`#966AC8`/`#BD9CE2`), 6 hex novos no total, **sem rampa no §2.1 de propósito**. Sequência: **turquesa → dourado → magenta → azul → violeta → azul-800** — 5 famílias, nenhuma repete antes da 6ª posição; ordem 2↔3 decidida no gate (dourado separa por peso os dois tons médios saturados). `cat-1` light muda de turquesa-400 para **turquesa-500 `#00A192`** (3.22 vs branco — o DG14 removeu o contorno e o fill passou a ter de passar 3:1 sozinho). **Regra do dourado:** permitido em área grande com rótulo direto; vetado como fill solitário sem rótulo (1.85 é insolúvel sem matar a cor da marca). **O cinza sai da categórica** (conflitava com a reserva de "sem dado"). **Supersede DM3 no gauge:** bandas viram intensidades de cinza (medido: as faixas coloridas distavam 1 ponto de claridade no light e 0 no dark); a barra de valor carrega a severidade; nenhum hex muda. Emenda GI2 cumprida: registrado que a rampa categórica ESCURA colapsa em claridade (75/75/71/71/67) por construção — é o que obriga o DG13. **Achado da formalização:** os previews aprovados embutiam 5 hex com deriva do canônico; a seção ancora nos stops reais do §2.1, com remedição provando veredito idêntico. Aprovação: gate visual do Rafael em 2026-08-10 ("tudo ok" sobre os previews v1.2/v0.7); leis de consumo no `seed-dataviz.md` v0.5. Gêmeos atualizados NA MESMA edição (v1.5), `paridade-tokens.py` com allowlist de supersede declarada. |
| 1.4 | 2026-08-09 | **Promoção da §3c a `estável`** (gate visual do DT aprovado pelo Rafael sobre o preview v0.2 completo) **e fechamento do débito do §7.0: os gêmeos `seed-tokens.json` e `seed-tokens.css` foram regenerados e passam a v1.4.** Nenhum valor de token foi alterado nesta versão — é mudança de estado + restabelecimento da unidade md+json+css. **Achado da execução:** o débito era de DUAS versões, não uma — os gêmeos declaravam `v1.1` e não continham nenhum token do pacote mobile v1.2 (breakpoints, tipografia fluida `clamp()`, `--seed-fs-field-touch`, safe-area); a redação anterior da pendência 7.0 é superada com racional completo. **Guarda nova:** `validacao/paridade-tokens.py` (G1 não-regressão · G2 paridade json↔css · G3 cobertura nominal), 43 PASS · 0 FAIL — ela reprovou a primeira tentativa de regeneração (renome de `--seed-sp-*`, perda de `--seed-focus-ring`, sombras serializadas como DTCG), o que levou a entrega a ser feita por edição cirúrgica. Cruzamento §3c × gêmeos: 26/26 hex batem. `contraste-dataviz.py` reproduzido na janela: 29 PASS · 3 FAIL (os 3 documentados do fill em traço fino). |
| 1.3 | 2026-08-09 | **Escalas de dado da Fase 5 (sub-bloco DT), nova §3c** — a entrega prometida desde a v1.0. Sequencial `chart-seq-1…7` (rampa turquesa; **escala final 100→900 light / 800→100 dark, decidida no gate visual**: o Rafael reprovou a proposta original 50→800 porque os dois primeiros stops liam como cinza — ambíguos com "sem dado" — e aprovou a opção A sobre preview comparativo; nasce junto o token **`chart-no-data`**, cinza exclusivo de "sem medição", SEMPRE hachurado; isenção 1.4.11 declarada com condições de acompanhamento e gatilho de revisão) · divergente `chart-div-neg-3…pos-3` (vermelho↔cinza↔turquesa, alinhada por construção ao par positive/negative da v1.0; posições plenas passam 3:1 medido nos dois modos; regra da zona-zero declarada) · gauge `gauge-track/value/range-*` (faixas referenciam a taxonomia de feedback — nenhuma severidade paralela) · **variante `cat-N-stroke` light+dark** para traço fino, nascida de remedição que reprovou cat-1/2/5 a ≤3px (fill intocado; os pares dark vieram do achado V2 do render). **Dois achados do script corrigiram a proposta antes da spec:** warning light dourado-500→600 (2.35→3.25 vs trilha) e critical dark vermelho-400→300 (2.38→3.26). Nenhum hex novo — tudo stop existente do §2.1. **Errata §5 fechada nesta edição** (regra GI2 — aberta desde o roadmap v1.3, 2026-08-04): a linha do par info dizia "azul-700 · 5.79 · AA"; medição de 2026-08-09 provou que 5.79 é de fato o azul-700, mas o par **semântico** usado pelo sistema (feedback-info-text, consumido inclusive pelo e-mail §4.2) é o **azul-800, que mede 8.57 · AAA** — a linha passa a documentar o par real, e a errata original (que previa só troca de rótulo) é superada pela correção completa rótulo+número+veredicto. Consumidor primário desta seção: `seed-dataviz.md` (9º canônico, DF7: uma fonte, referência sem duplicação). |
| 1.2 | 2026-08-02 | **Camada mobile/app (pacote M1–M3 aprovado pelo Rafael).** Breakpoints oficiais = escala Tailwind (sm 640…2xl 1536), canônicos no JSON + theme do Tailwind, com supersede do corte 960 do HTML v1; escala tipográfica fluida com `clamp()` rem+vw nos 4 topos (regra WCAG 1.4.4 embutida); `--seed-fs-field-touch` 16px via `pointer: coarse` (anti-zoom iOS); tokens de safe-area para PWA/app. Nenhum valor de cor alterado. Contexto: diretriz de paridade mobile/app declarada pelo Rafael em 2026-08-02 — apps serão produzidos e o uso mobile supera o desktop. |
| 1.1 | 2026-07-30 | Hierarquia de uso da paleta (§3b): proporção 70/20/10 (supersede os 45% de 2018), amarelo=acento oficial vs dourado=trabalho, papel formal do azul (livre na UI/info, contido na marca, nunca ação primária). Novo grupo semântico `accent` (highlight/highlight-subtle/on-highlight). Nenhum valor de cor alterado. |
| 1.0 | 2026-07-30 | Entrega inicial da Fase 1 do rebranding do DS. Rampas tonais das 6 famílias (8 cores de marca + vermelho funcional), semânticos light/dark, elevação, motion, tipografia (Montserrat+JetBrains Mono; Indie Flower e Neo Tech aposentadas), spacing/radius, dataviz. Supersedes declarados: #0d8f82 → surface-brand-deep; #2a3942 → cinza-900; hex dark ad-hoc → superfícies dark oficiais; #c63838 → vermelho-600; regra de contraste do turquesa reformulada com medição. |
