# Validação e evidências

Última execução: 21/09/2026. Esta página distingue o que foi executado, o que foi verificado estaticamente e o que permanece impedido. Não declara conformidade certificada, publicação nem aprovação da marca.

## Build: o impedimento foi resolvido

Nas rodadas anteriores o build não pôde ser executado neste host. A causa era conhecida: `@tailwindcss/postcss` carrega `@tailwindcss/oxide`, um binário por plataforma, e o store pnpm deste projeto só contém `win32-x64-msvc`; a rede está fechada por política de egress, então instalar a variante Linux é impossível.

A saída não foi contornar a verificação, e sim remover a dependência do binário: o pacote `tailwindcss` puro expõe `compile()`, que faz o trabalho em JavaScript desde que receba a lista de candidatos — exatamente o que o oxide descobriria varrendo os arquivos. `scripts/compile-tailwind.mjs` faz essa varredura (469 arquivos, 49.199 candidatos) e produz o CSS; o Webpack então roda normalmente, com o PostCSS sem plugins, e monta HTML, bundle e assets.

**`webpack` terminou com código 0.** `build/` tem 93 páginas, `style.css` de 463 KB e `bundle.js` de 7,3 MB.

`scripts/verify-build.mjs` confere o resultado e está ligado como `postbuild`: **14/14 itens aprovados** — tokens `--tp-` no CSS compilado, os cinco `@font-face`, as classes `.tp-*`, os utilitários do Tailwind, o preloader, as páginas obrigatórias, as fontes emitidas, os vetores, o favicon, o bundle e o `<link>` do CSS em toda página.

Esse verificador nasceu de uma falha real: numa rodada anterior o Webpack terminou sem alarde emitindo um `style.css` que continha apenas o CSS das bibliotecas, porque o módulo `src/css/style.css` falhara. As páginas abriam sem estilo nenhum e nada no resultado denunciava isso.

No Windows, `npm run build` funciona pelo caminho oficial, com os binários nativos — `compile-tailwind.mjs` é necessário apenas onde eles não existem.

## Navegador real

Build servido em HTTP local e percorrido com Chromium (Playwright), em `design-system.html`, `sistema-atendimento.html` e `index.html`, nas larguras 390 e 1440 px, temas claro e escuro.

- **12 capturas. 0 erro de console, 0 `pageerror`, 0 requisição falha.**
- Passo confirmada renderizando no portal e no atendimento (`document.fonts.check('700 16px Passo')`).

### Defeito encontrado e corrigido

Medição do item da fila de atendimento em 1440 px: o item ocupava **545 px dentro de um painel de 335 px**, com o título espremido em **98 px** e o badge de prioridade cortado.

Causa: `.tp-inbox-item` era um grid de três colunas (`auto minmax(0,1fr) auto`) e a terceira coluna passou a conter status, prioridade e SLA, todos `white-space: nowrap` — 355 px de largura mínima numa fila de 335 px. A lista tem `overflow-x: auto`, então o estouro não vazava na página; virava scroll horizontal e corte visual.

Correção: o item passou a empilhar — avatar à esquerda ocupando duas linhas, nome e preview na primeira, e os sinais na segunda, com `flex-wrap`. É o padrão de qualquer inbox de alta densidade e resolve em qualquer largura.

Depois da correção, em 1440, 768 e 390 px: item cabe exatamente na lista, título com **255 px sem truncar**, sem scroll horizontal e sem overflow de página.

## Verificações automatizadas

- `node scripts/generate-design-system.mjs`: **450 tokens**, CSS portátil, catálogo JSON, `fonts.css`, assets de marca e fontes, 7 e-mails e 7 peças.
- `node scripts/check-design-system.mjs`: **792/792 aprovadas**, 18 pares de contraste em claro e escuro. Eram 736 no início do dia, 757 depois da integração da marca, 774 com o dashboard e 792 com as seções novas do portal. Toda verificação nova cobre algo que passou a existir.
- `node scripts/test-adapter.mjs`: **9 grupos aprovados**.
- `node scripts/verify-build.mjs`: **14/14**.

## O que foi construído nesta rodada

Três agentes especializados trabalharam em paralelo, com escopo de arquivos exclusivo.

**CSS e fundações** — 111 classes novas (234 → 345) e 63 tokens novos (391 → 454), sem remover nenhuma classe. Toast completo (não existia), os 4 tons de alerta e badge, skeleton em 4 variantes com shimmer, loading overlay, error state, progresso indeterminado, paginação, cabeçalho fixo de tabela, célula de ações e de usuário, as 13 classes da escala tipográfica (65 tokens que não tinham um único consumidor), SLA com 4 níveis, os 5 estados de atendimento com aparência distinta, canal, atribuição, chips de filtro, anexos, áudio, templates. Correções: `.tp-button:disabled` deixou de pintar todas as variantes de roxo; `:hover` e `:disabled` passaram a existir em campos; as 6 classes que o markup usava e não existiam (`.tp-priority`, `.tp-message-*`, `.tp-tabs`, `.tp-label`, `.tp-list`, `.tp-nav-home`) foram escritas; `.tp-contact-header` voltou a ter efeito; o degrau duplicado de radius foi desfeito; elevação, z-index e radius passaram a vir de token em vez de literal.

**Sistema de Atendimento** — paginação com tamanho ajustável sobre 42 conversas fictícias; loading, skeleton e erro nos três painéis; SLA com prazo real, relógio de 30 s e pausa quando aguarda o contato; os 5 estados com ícone e máquina de transição (Fechado não volta a Aberto sem reabertura explícita); atribuição e transferência com registro como mensagem de sistema; filtros por canal, responsável, prioridade, status e tag, combináveis, com chips e contagem; composer com múltiplos anexos, progresso, templates com variáveis, agendamento e estado de erro; conversa com separador de data, agrupamento, preview de imagem, player de áudio e status de envio incluindo "lido"; painel de contato com histórico, campos personalizados e observações; toast em todas as ações.

**Portal** — de 21 para 29 seções, com 18 partials novos. Passaram a ser apresentados: espaçamento, grade, forma, bordas, elevação, motion, camadas de z-index e breakpoints — nenhum deles aparecia antes. A seção de tokens deixou de ser três cartões conceituais e virou catálogo navegável dos 450 tokens, agrupado em 10 famílias, com valor no claro, valor no escuro e os seletores que consomem cada um, extraídos do próprio CSS. A escala tipográfica passou a ser exibida nos 13 degraus. Entraram Toast, Pagination, Breadcrumb, Divider, Skeleton, Loading, Error state e a matriz de estados por componente. Três defeitos do portal foram corrigidos de passagem, entre eles um `<include>` dentro do atributo `x-init` que tornava a expressão Alpine inválida.

## Não executado

- Leitor de tela e teste manual integral das 94 páginas.
- ApexCharts, FullCalendar, Dropzone e mapas exercitados em navegador: o QA cobriu portal, atendimento e dashboard; as demais páginas carregam o mesmo bundle mas não foram percorridas uma a uma.
- Testes em clientes de e-mail reais.
- WOFF2 (Brotli indisponível) e hospedagem própria de Inter (sem acesso a `fonts.gstatic.com`).
- Contraste calculado cobre os pares de token documentados, não todas as combinações legadas. O agente do CSS calculou 26 pares adicionais das classes novas; o pior caso foi 4,31:1 para borda (mínimo 3:1) e 5,23:1 para texto.
- Homologação institucional da marca e revisão de licença web da Passo.
- O build foi gerado neste host pelo caminho alternativo descrito acima. Vale rodar `npm run build` no Windows antes de publicar, para confirmar equivalência pelo caminho oficial.

## Procedimento reproduzível

No Windows, na pasta do projeto, com Node ≥ 22.18:

```
npm ci
npm run check:design-system
npm run build          # já roda verify-build no postbuild
npm run serve:build
```

Onde não houver o binário nativo do Tailwind:

```
node scripts/compile-tailwind.mjs . src/css/style.css tmp-compiled/style.css
```

e aponte o Webpack para o CSS compilado, com o PostCSS sem plugins.

## Rodada de 18/09, noite — menu, grafismos, marca, identidade e localização

Cinco frentes, cada uma com agente próprio e escopo de arquivos exclusivo. Medições feitas no build compilado com Chromium, não por leitura de código.

### O menu recolhido que apagava as seções

O defeito relatado com foto: abaixo de 1280 px, acionar o botão do menu abria uma gaveta de 290 px com ícones centralizados, sem rótulo e sem título de seção.

A causa não estava no markup. Um override do `style.css` casava por substring — `.sidebar[class*="w-22.5"]` — e a lista de classes do `<aside>` contém `xl:w-22.5`. O seletor pegava **em qualquer largura**, inclusive onde `xl:` não estreita coisa alguma. Havia ainda dois blocos `@media (max-width: 767px)` que forçavam o sidebar a 4,5 rem e anulavam, com `!important`, a expansão por hover do próprio TailAdmin.

Correção: o estado recolhido passou a existir só dentro de `@media (min-width: 1280px)`, com `[class~="xl:w-22.5"]` (casamento exato de token, não substring) e `:not(:hover)` — o que devolveu a expansão por hover que o `!important` vinha vencendo. Os dois blocos de 767 px foram removidos: abaixo de 1280 o sidebar é uma gaveta sobreposta, não um trilho. No markup, `sidebarToggle ? 'justify-center'` e `? 'xl:block'` ganharam o qualificador de breakpoint que faltava, em `sidebar.html`, `sidebar-layout-1.html` e `sidebar-layout-2.html`.

Medido depois, em 1440, 1280, 1200, 1024, 768 e 390 px:

| largura | ao acionar o botão |
| --- | --- |
| 1440 e 1280 | trilho de 90 px, 0 rótulos, 0 títulos, 3 reticências de grupo, marca compacta |
| 1200, 1024, 768 e 390 | gaveta de 290 px, 18 rótulos, 3 títulos |

Zero overflow horizontal em todas. A marca no topo da gaveta foi testada e revertida: o cabeçalho da página já exibe a marca abaixo de 1280 e as duas colidiam.

### Grafismos

Os quatro do guia de estilos — arco de grande raio, linha de acento, pontos modulares e gradiente institucional — passaram a existir como classes tokenizadas, com variantes de posição e escala, tema escuro, unidades lógicas para RTL e `aria-hidden` obrigatório. Seção nova no portal, com pares fazer/evitar, e `docs/design-system/grafismos.md`.

A primeira versão exibia um defeito que contrariava a própria regra que documentava: medido, o desenho cruzava o texto em 5 dos 8 contêineres, até 10.546 px² de interseção. A correção saiu da recomendação e virou cálculo — o contêiner deriva a faixa que o desenho alcança e a devolve como recuo do conteúdo, com `:has()` levando a escala do filho para o contêiner. O contraexemplo "Evitar" tem uma classe própria, `.tp-graphic-overlap`, para seguir demonstrando o erro. Medido de novo em 1440, 1280, 768 e 390 px, nos dois temas: **0 px² de interseção em todos os contêineres não marcados**.

### Manual de marca

Auditoria em `docs/design-system/auditoria-marca.md`, com 10 alarmes falsos descartados com prova. O que faltava e foi corrigido: a regra normativa das cores secundárias (pp.27–32), que não existia em lugar nenhum e agora acompanha o token; duas frases do portal que afirmavam o contrário do que o pacote entrega; o ícone de aplicativo e o webmanifest (pp.13–14), rasterizados do vetor oficial; os 2 gradientes ausentes dos 5 da p.34; e as 8 cores que faltavam em `brand-tokens.js`. Co-branding (p.7) e papelaria ficaram registrados como pendência — dependem de decisão de marca.

### Identidade e localização

E-mails no padrão `nome.sobrenome@trocapontos.com.br` — 100 ocorrências normalizadas, 53 endereços distintos, 28 pessoas renomeadas, 0 divergências entre nome exibido e e-mail. Contatos externos do atendimento ficaram em domínios fictícios de empresa cliente. A administradora principal é **Mariana Sydow** em cabeçalho, perfil, conta, assinaturas e autoria, com iniciais `MS`.

Números em formato norte-americano herdados do TailAdmin: 125 ocorrências em 46 arquivos, milhar para ponto e decimal para vírgula, decididas caso a caso pelo contexto da tela. Três `toLocaleString()` sem locale — que reintroduziriam `3,782` num navegador em inglês — passaram a `pt-BR` explícito.

### O verificador de build ficou mais rígido

Durante esta rodada o `verify-build.mjs` aprovou, com 14/14, um build cujo CSS tinha perdido **todos** os utilitários do Tailwind: a checagem antiga procurava `.flex|.grid|.hidden` e passou porque `.hidden` existe no CSS autoral. Agora são quatro utilitários independentes conferidos com a declaração esperada, mais a prova de que as variantes responsivas saíram como media query e de que a escala de largura do template está presente. São 16 itens.

### Números da rodada

| | antes | depois |
| --- | ---: | ---: |
| verificações do design system | 788 | **875** |
| itens do verificador de build | 14 | **16** |
| classes `.tp-*` | 341 | 368 |
| tokens exportados | 450 | 452 |
| erros de console (12 combinações página × tema) | — | **0** |
| overflow horizontal | — | **0** |

## Revisão de 18/09, noite — três defeitos que passaram

Reportados com captura de tela. Os três eram reais e nenhum tinha sido pego pela verificação.

**O `<body>` das três páginas de referência estava quebrado.** Em `padroes-erp.html`, `institucional.html` e `comunicacao.html`, o bloco `<include src="./partials/preloader.html">` havia sido inserido **dentro** do atributo `x-init` da tag `<body>`, entre `$watch('darkMode', value =>` e ` localStorage.setItem(...)`. O parser fechava a tag no meio, o resto do atributo era renderizado como texto na página — `ocalStorage.setItem('darkMode', …)` — e, sem `:class="{'dark': darkMode}"` válido, **o tema escuro não existia nessas páginas**. O bloco foi movido para depois da tag. Medido: as quatro páginas do portal alternam de `#FAF8FB` para `#19151C`, sem texto vazando e sem erro de console.

**O preloader exibia a logomarca do TailAdmin.** `src/partials/preloader.html` apontava para `./images/logo/logo.svg` e `logo-dark.svg` — os arquivos originais do template, em azul `#465FFF` — enquanto o comentário logo acima descrevia "logomarca oficial (positiva no tema claro, negativa no escuro)". Agora aponta para `./images/brand/logo-positive.svg` e `logo-negative.svg`. Isso aparecia em todas as 93 páginas, no primeiro instante de cada carregamento. Passou despercebido porque o QA anterior **ocultava o preloader** antes de medir, justamente para não atrapalhar as medições — um ponto cego criado pelo próprio método.

**Os contraexemplos dos grafismos eram lidos como defeito.** Os cartões marcados "Evitar" mostram o grafismo por cima do texto de propósito, mas o rótulo ficava solto acima do cartão e a legenda abaixo; em qualquer recorte da tela o cartão aparecia sozinho e parecia quebrado. Cada exemplo passou a ter moldura própria com faixa de rótulo — `.tp-example`, `.tp-example-do`, `.tp-example-dont` — em verde ou vermelho, dizendo "Uso correto" ou "Uso incorreto, mostrado de propósito" antes de qualquer leitura.

### O catálogo de tokens saiu do fluxo de leitura

452 linhas no meio da página não são referência, são obstáculo. A seção 07 passa a explicar a distribuição — 218 primitivos, 213 semânticos, 21 de componente; 240 em cor e 93 em tipografia respondendo por três quartos do total — e o catálogo completo, com busca e filtros, ficou atrás de uma divulgação progressiva (`.tp-disclosure`), fechada por padrão. Quem escreve interface consome a camada semântica; quem precisa da tabela abre.

## Refinamento final de 21/09

Rodada de revisão com baseline aprovado e regra "se está 100%, não mexa". Três auditorias somente leitura (tokens e foundations; componentes e estados; conteúdo e consistência), quatro lotes de execução com arquivos exclusivos, e não-regressão medida em 90 combinações de página × largura × tema. Relatório completo, no formato preservado / refinado / corrigido / consolidado / removido / validação / pendências: **`refinamento-final.md`**. Evidências e scripts em `evidencias/refinamento-final/`.

Números: verificação estática 875 → **931/931**; build 16/16; overflow horizontal 2 → 0; texto abaixo de AA no tema escuro 1.954 → 12 (todos em exemplos desabilitados); erros de console 0; páginas com `<h1>` 15 → 92; botões de ícone sem nome 468 → 144; campos sem rótulo 12 → 0. Baseline em `_backup/baseline-refinamento-final-2026-09-21_1459.tar.gz`.

## Ajustes de 21/09, tarde

Reportados com captura: e-mail cortando no perfil e menu "Soluções" diferente dos demais.

- **E-mail que invadia a coluna vizinha** em `profile.html` e `single-transaction.html`: ponto de quebra antes de `@` e de `.com.br`, com `wrap-anywhere` como rede. Medido em 1440, 1024 e 390 px: texto dentro da própria caixa. Na mesma tela, três resíduos do template: CEP "ERT 2489", CNPJ "AS4568384" e a descrição de "Alterar senha" falando de avisos de pontos.
- **"Soluções"** passou a usar o mesmo `.tp-reference-menu` de "Referências": chevron em SVG que gira, mesmo painel e mesmo teclado. O painel próprio (`.tp-mega`, `.tp-mega-panel`) ficou sem consumidor e saiu do CSS e da documentação. Um modificador `.tp-reference-menu-start` alinha o painel ao início do botão quando o menu é o primeiro da barra.
- **Sobrancelha do diagrama do institucional** ("Uma experiência com propósito") em roxo sobre o gradiente roxo, a 1:1: passa ao mesmo tom que o hero usa. Medido em todas as superfícies de marca das páginas do portal: era o único caso.
- **Varredura completa das 94 páginas** nos dois temas, depois da rodada: restam só os rótulos do exemplo de campo desabilitado (isentos). Ela revelou uma regressão da rodada anterior — iniciais de avatar em `table-04.html` e `recent-orders.html` com o texto clareado no escuro sobre o círculo que continuava claro (1,16:1) — e três resíduos antigos: status em cartão de crédito escuro no tema claro, etiqueta laranja do kanban e contador de aba a 4,48:1. Todos corrigidos.
- **Título de `maintenance.html`** saía 19 px da própria caixa (já saía antes): um degrau de tipografia abaixo.

## Plataformas e dispositivos

Seção nova no portal (16) e página de referência `padroes-aplicativo.html`: aplicativo do colaborador em telefone, tablet e desktop, com a camada `TP:APP` que se adapta ao próprio contêiner em 620 e 1120 px. Detalhes, premissas e decisões pendentes em `plataformas-e-dispositivos.md`. A revisão encontrou e corrigiu um defeito da própria entrega: em telefones de 360 px o título da linha de lista invadia o valor, porque a trilha `auto` assumia a largura de uma palavra longa.

As perguntas que dependem de decisão estão reunidas em `decisoes-pendentes.md`.

Verificação estática 931 → **985/985**; build 16/16 com 94 páginas; zero erro de console e zero rolagem horizontal nas páginas medidas.

## Respostas de 22/09/2026

Guilherme Sydow respondeu as 26 perguntas de `decisoes-pendentes.md`. Vinte e quatro foram executadas nesta rodada; V1 (peso dos botões) e V2 (paleta dos gráficos) ficaram sem resposta e continuam abertas.

- **Co-branding (M3), implementado.** A Troca Pontos à esquerda. A distância entre as marcas não virou pixel fixo. **Este parágrafo estava desatualizado e foi corrigido em 22/09/2026:** a primeira medição usou a *tinta* da letra "o" em `logo-mono.svg` — 58,546875 de 564,734375 unidades, ou `0,103672` —, e horas depois a p.7 chegou em vetor e mostrou que a unidade que a arte **desenha** é a **largura de avanço** do "o", `27,14` de `226,77` = **`0,119681`**. É esse o valor de `--tp-cobrand-o-ratio` no CSS desde então, e é ele que os vãos reais da prancha confirmam (27,33 e 27,74); a 170 px dá **20,35 px**, não 17,62. A tinta fica declarada ao lado, em `--tp-cobrand-o-ink-ratio`, só para a troca ser rastreável. O divisor **deixou de ser premissa**: a p.7 dá espessura (1 unidade), altura (`0,250000` da largura) e cor (`#C6C6C6`, igual nas duas versões). Bloco `TP:COBRAND`, componente `.tp-cobrand` nas duas versões da p.7, partial `cobranding.html`, seção no portal e regra escrita, com a versão colorida proibida e a marca do cliente como espaço reservado rotulado.
- **Aplicativo do gestor (A2), implementado.** Três telas na mesma casca `.tp-app` — Início, Aprovações e Campanhas —, com abas próprias e a folha inferior do mesmo contrato de diálogo modal. O painel web continua sendo a gestão completa no desktop.
- **Reconhecer movimenta pontos (A4).** Mudança de fluxo, não de tela: escolha de valor, saldo à vista, saldo insuficiente como erro de campo, saldo depois do envio na confirmação, débito no extrato e no Início. As contas foram somadas, não estimadas, e fecham nos três períodos: 30 dias 11.530 + 5.600 − 4.650 = 12.480; a campanha "3 de 5" conta os mesmos três reconhecimentos que o extrato mostra; a cota do gestor fecha em 60.000 = 36.000 creditados + 24.000 a distribuir.
- **Tema no app (A9).** "Aparência" no Perfil, com Sistema, Claro e Escuro, padrão em seguir o aparelho.
- **Decisões visuais (V3 a V7).** Os dois sistemas de grafismo vão no pacote; um fundo de página só para todo o site; véu roxo lido do token `--tp-overlay`; sem par escuro de sombras; Real como moeda padrão.
- **Conteúdo (C1 a C3).** Números e integrações ficam como exemplos e saíram das pendências; os clientes-alvo dos modelos de e-mail passaram a ser Gmail, Outlook e Apple Mail, com o teste ainda por fazer.

Um defeito real foi encontrado na revisão, e não pela entrega nova: a escada de camadas de `#z-index` tingia cada degrau em 6% da cor de ação, e no tema escuro o degrau mais alto (`--tp-z-preloader`) ficava em **4,25:1** com o texto. O passo caiu para 5% — 5,19:1 no escuro e 7,86:1 no claro —, sem perder o degradê. Ele estava escondido porque o medidor de contraste não lia a forma `color(srgb …)` que o `color-mix` produz e caía no fundo da página; o medidor foi corrigido antes da varredura.

Verificação estática 985 → **1040/1040**; build 16/16 com 94 páginas; 114 combinações de página × largura × tema com zero erro de console, zero rolagem horizontal e zero foco sem indicador. Varredura de contraste das 94 páginas nos dois temas: **2 nós no claro e 2 no escuro**, todos rótulos do exemplo de campo desabilitado do template, isentos. Os 27 alvos abaixo de 24 px que apareceram no portal são as miniaturas `inert` da seção de plataformas, que não são operáveis.

## Guia de marca em vetor — 22/09/2026, fim do dia

Chegou o guia de estilos como **34 pranchas em SVG**, exportadas do Illustrator. Pela primeira vez o sistema pôde ser conferido contra a geometria e as cores exatas, em vez de contra o PDF e PNGs. A rodada fechou a pendência mais antiga do projeto e corrigiu oito coisas que estavam erradas por inferência.

- **O símbolo existe (M2, D01 — abertas desde o início).** A prancha 14 traz o arco em vetor, dentro de cinco recipientes de 80,16 com raios 0, 2,83, 8,5, 22,68 e círculo. O `d` foi copiado byte a byte, sem redesenho, e só recortado por `viewBox`. O símbolo entrou na **sidebar recolhida** — que era a razão original da pendência —, no favicon e numa seção nova do portal, com a exceção de área livre que a própria prancha declara. Medido depois: 32 × 32 centrado no trilho de 90 px, nos dois temas.
- **Favicon e ícones de aplicativo.** Comparados pixel a pixel antes de trocar. Só o `favicon.ico` mudou (o recorte a 900 dpi borrava os terminais do arco a 16 e 32 px); `apple-touch-icon` e os dois PNG ficaram como estavam, porque a diferença era de 0,1 a 0,17 em 255 — trocar seria trocar por trocar.
- **Co-branding, medido em vez de suposto.** A unidade que a p.7 desenha não é a tinta do "o" (23,51 de 226,77 = 0,103672), é a **largura de avanço** (27,14 = 0,119681) — e é ela que a arte aplica, nos vãos reais de 27,33 e 27,74. O divisor deixou de ser premissa: 1 unidade de espessura, `#c6c6c6`, altura de 56,69 = **exatamente um quarto da largura do wordmark**, igual nas duas versões.
- **A ordem das marcas: divergência consciente.** A p.7 mostra cliente à esquerda e Troca Pontos à direita. A divergência foi levada a Guilherme Sydow com a prancha à vista, e ele **manteve a Troca Pontos à esquerda**. Neste ponto o sistema não reproduz a ilustração do manual por decisão de quem homologa, e isso está escrito em D32 e no portal para que ninguém "corrija" por engano.
- **Oito divergências achadas pela auditoria das outras 32 pranchas**, todas com número: a área de proteção pedia 0,16325 da largura e o sistema reservava 0,1412 (13,5% a menos); os 170 px mínimos medem coisas diferentes na versão principal e na preferencial, e o sistema fundia as duas; o arco tinha fração e tinta erradas; três dos cinco gradientes estavam documentados **na direção inversa**, e o CSS seguia a documentação; e a espessura de traço dos ícones da marca virou token.
- **A divergência "fundos azuis" (D02) nunca existiu.** A prancha em vetor escreve "fundos **roxos**", com todas as letras. Foi erro de leitura nosso do PDF, propagado por `auditoria-marca.md` — e a pergunta M4, que gastou uma rodada da marca, era evitável. Fica registrado assim.
- **Achado extra.** Conferir a área de proteção na tela de entrada revelou que ela exibia `auth-logo.svg`, **a marca do TailAdmin em `#465FFF`** — logomarca de terceiro na porta de entrada do produto, enquanto o comentário do arquivo dizia aplicar a preferencial negativa. Trocada pelo wordmark oficial.

Verificação estática 1040 → **1103/1103**; build 16/16 com 94 páginas; 114 combinações de página × largura × tema sem nenhuma regressão em relação à rodada anterior (mesmos números, zero erro de console, zero rolagem horizontal, zero foco sem indicador). Varredura de contraste das 94 páginas: **2 nós no claro e 2 no escuro**, todos rótulos de campo desabilitado do template, isentos.

## Distribuição estática oficial — 23/09/2026

O Design System deixou de ser uma customização do TailAdmin e passou a ser uma **distribuição independente**. O detalhe está em `distribuicao-estatica.md`; aqui fica o que foi feito e o que foi medido.

- **O portal virou consumidor do próprio sistema.** Antes: portal → TailAdmin → customizações. Agora: portal → `troca-pontos.css` + `troca-pontos.js` + tokens + assets. É essa inversão que prova que o sistema existe sozinho.
- **O Alpine.js saiu do runtime.** Os 27 componentes Alpine inline e os 3 nomeados foram substituídos por **`troca-pontos.js`**: 45,5 KB (10,4 KB com gzip), script clássico, sem dependência, sem `fetch`, sem módulo ES. Dirigido por atributos `data-tp-*` — classe é estilo, atributo é comportamento —, com modal, dropdown, accordion, tabs, dismiss, toast, menu, sidebar, tema e foco. O teclado e o ARIA que o Alpine fazia foram medidos um a um, não presumidos.
- **O CSS já estava pronto e ninguém sabia.** A arquitetura de três camadas de token tinha deixado o CSS livre de Tailwind: o exportado não tem uma diretiva sequer (`@apply`, `@utility`, `@custom-variant`, `--tw-`). O que faltava era a estratificação: núcleo, camada **opcional** de aplicativo, e folha exclusiva da documentação.
- **52 páginas de documentação**, uma por componente, organizadas como documentação de Design System e não como catálogo de telas de template.

### O que a mudança revelou

Tirar o Alpine expôs seis defeitos que ele escondia, todos corrigidos no núcleo, com medida antes e depois:

| Defeito | Antes | Depois |
| --- | --- | --- |
| Sidebar recolhida: o JS escrevia `data-collapsed` e **nada respondia** no pacote distribuído | 1408 px, rótulos visíveis | 68 px recolhida, expande por ponteiro **e por foco de teclado** |
| Tooltip: o núcleo estilizava, mas nunca dizia **quando** aparecer (era o `x-show`) | sempre visível, sem teto, causando rolagem a 320 px | escondida em repouso, ponte de hover (WCAG 1.4.13), teto pela janela |
| Botão em carga herdava o tratamento de indisponível | **1,90:1** claro / **2,06:1** escuro | **10,84:1** / **8,96:1** |
| Aviso temporário ficava preso em pausa ao ser fechado com o ponteiro dentro | o seguinte não fechava sozinho | fecha em 7 s, provado na página publicada |
| Fechar de aviso com alvo de 28 px | 28×28 | 44×44 de acionamento, caixa visual intacta |
| Menu responsivo escondia o painel na inicialização sem olhar o breakpoint | **o portal ficava sem navegação a 1440 px** | painel visível acima do limite, recolhido abaixo |

O último foi meu, introduzido ao ligar a casca ao JS oficial, e encontrado pela varredura — não pela leitura.

### Medições

Verificação estática 1103 → **1144/1144**. Verificação da distribuição: **20/20** — sem `node_modules`, sem TailAdmin, sem Alpine, sem Webpack, sem Tailwind em runtime, sem CDN, sem caminho absoluto, sem referência quebrada, sem âncora morta, sem divergência de token.

**Teste de independência aprovado:** a `dist/` foi copiada sozinha para uma pasta temporária fora do repositório, sem nenhum vizinho, e as 52 páginas abriram por `file://` com zero erro de console e zero requisição falha. A fonte Passo resolveu do próprio pacote. Uma página vazia criada na hora, com as duas linhas de `<link>` e `<script>` e o HTML de um botão colado da documentação, renderizou o botão em `rgb(107, 0, 128)`, 44 px de altura, com `window.TP` disponível.

**Varredura das 52 páginas × 2 temas × 2 larguras (208 combinações):** zero erro de console, zero rolagem horizontal, **zero texto abaixo de 4,5:1**, zero imagem sem `alt`. Dos 194 alvos abaixo de 24 px, 193 são links dentro de frase, isentos pela WCAG 2.5.8; o último é um link de texto numa demonstração de ordem de foco. Os dois campos sem rótulo estão dentro de `tp-example-dont` — são a demonstração deliberada do que **não** fazer.

O build do projeto foi recompilado e não regrediu: 16/16, 94 páginas, e a varredura de contraste das duas temas continua nos mesmos quatro rótulos de campo desabilitado do template, isentos.
