# A11y Verification Report — Same Brain

Este relatório compila as evidências de conformidade do site **Same Brain**, garantindo
que seu desenvolvimento atingiu — ou não — a definição de "Certification Ready".

Protocolo aplicado: [A11Y.md](https://github.com/fecarrico/A11Y.md) v1.1.0 ·
Formato: [`templates/REPORT.md`](https://github.com/fecarrico/A11Y.md/blob/main/docs/pt-BR/templates/REPORT.md)

> Este relatório é um **registro versionado do projeto** — nunca adicione ao `.gitignore`.
> Evidência escondida do controle de versão não é evidência.

> **Convenção deste relatório.** `[x]` significa verificado com evidência reproduzível,
> descrita ao lado. `[ ]` significa **não verificado**, e o motivo está escrito. Nenhum
> item foi marcado por analogia, por leitura de código ou por confiança no autor. Os itens
> 3.1 e 4.2-simulador exigem uma pessoa operando tecnologia assistiva e permanecem
> abertos — o protocolo chama isso de **validação humana obrigatória** (§0, introdução).

---

## 📌 Contexto da Validação
- **Funcionalidade/Épico:** site completo — 16 rotas, 38 páginas de conceito, 13 de método,
- **Independência da Verificação:** cross-agent — *quem verificou:* Claude Opus 5 em sessão própria (subagente sem acesso à conversa que produziu o código), em 07/09/2026, reproduzindo no DOM do `dist/` os checkpoints automatizados das rotas `#/casos`, `#/manifesto`, `#/limites`, `#/leis` e `#/etica`, em pt e en; relatório em `avaliacao/verificacao-2026-09-07.md`. Vale para a revisão de 07/09 abaixo; as medições de agosto continuam com a atribuição que já tinham.
  4 capítulos de fundamentos, glossário, mapa em canvas, busca, playbook e referências
- **Perfil de Conformidade:** ⚖️ **Standard (AA)** — padrão do protocolo (§0.1), com duas
  Regras da Casa endurecidas: piso de fonte **14px** (protocolo pede 12px†) e alvos de
  **44×44px** (normativo AA é 24×24px, SC 2.5.8)
- **Data do Teste:** 2026-08-05
- **Ambiente de teste:** DOM real via jsdom 29 sobre o `dist/index.html` publicado, com
  as 16 rotas visitadas e o CSS aplicado; cálculo de contraste WCAG a partir dos tokens
  de `estilo.css`; validação estrutural de CSS por `css-tree`
- **Status de Conformidade:** ⚠️ **CONDICIONAL (Passa com Exceções)** — nenhuma violação
  CRITICAL ou HIGH encontrada nos itens verificáveis por ferramenta; **uma exceção ativa**
  (`EXCEPTIONS.md` EXC-2026-001) e **dois checkpoints pendentes de validação humana**

---

## 1. Verificação Técnica (Automated & Semantics)

- [x] **Axe-Core / Lighthouse:** Zero violações "Critical" ou "Serious"?
  → **Não foi possível rodar axe-core ou Lighthouse** (exigem navegador real; o ambiente
  desta verificação é headless sem Chromium). No lugar, foi escrita e executada uma
  varredura estática equivalente sobre as 16 rotas renderizadas, cobrindo as regras que o
  axe classifica como Critical/Serious e que se aplicam a este site:

  | Regra | Equivalente axe | Resultado |
  |---|---|---|
  | `div`/`span` com clique ou `role="button"` | `aria-required-children`, teclado | **0** |
  | Controle sem nome acessível | `button-name`, `link-name` | **0** |
  | `<img>` sem `alt` | `image-alt` | **0** |
  | `<input>` sem label | `label` | **0** |
  | `role` redundante sobre elemento nativo | `aria-allowed-role` | **0** |
  | `tabindex` positivo | `tabindex` | **0** |
  | Salto de nível de título | `heading-order` | **0** (2 corrigidos nesta rodada) |

  O item fica marcado porque a evidência existe e é reproduzível
  (`scratchpad/auditoria.mjs`), **com a ressalva de que não é axe-core.** Rodar axe é a
  primeira coisa a fazer numa máquina com navegador.

- [x] **Semântica HTML:** Substituição apropriada de `div`s genéricas por endpoints
  interativos? → **Sim, verificado.** Zero `div`/`span` com handler de clique em 16 rotas.
  Todo controle é `<button>`, `<a href>`, `<input>` ou `<fieldset>`/`<label>` nativo. Casos
  notáveis: a chave do mapa é `<ul>`, o alternador de modo é um `radiogroup` nativo, os
  microtextos foram removidos, e o popover do glossário usa a API nativa `popover` com
  `popovertarget` — sem ARIA escrito à mão. Guarda automática em `verificar.py` impede
  regressão de rota para função inexistente.

- [x] **Hierarquia de Títulos (H1-H6):** Respeitada e sem saltos de nível?
  → **Sim, após correção nesta rodada.** A varredura encontrou dois saltos `h1 → h3`
  (`#/fundamentos` e `#/playbook`), onde os cartões e as cinco perguntas viviam sob o `h1`
  sem seção intermediária. Ambos passaram a `h2`. Cada rota tem exatamente um `<h1>`, e a
  troca de rota move o foco para ele.

## 2. Tab Order e Focus Management

- [x] **Indicador de Foco:** O anel de foco nunca foi suprimido e atende ao contraste de
  3:1? → **Sim.** Não há `outline: none` sem substituto no `estilo.css`. O padrão é
  `outline: 2px solid hsl(var(--accent))` com `outline-offset`, e o acento mede **8,67:1**
  no tema escuro e **6,02:1** no claro contra o fundo — acima do piso de 3:1 por larga
  margem. Verificado por varredura do CSS e pelo cálculo em §4.

- [x] **Navegação Lógica:** A tecla `Tab` segue a ordem visual? → **Sim, por construção
  verificável.** Zero `tabindex` positivo em todas as rotas — a ordem é a do DOM, e o DOM
  segue a ordem visual em cada página. O único `tabindex="-1"` é o `<h1>` de destino do
  foco na troca de rota, que é alvo programático e não entra na tabulação. O `inert` é
  usado no modo de foco da busca para retirar o resto da página da ordem, e é removido ao
  fechar.

- [x] **Profundidade da navegação principal:** os destinos do menu são alcançáveis sem
  descoberta manual? → **Sim, desde 2026-08-05.** Antes, em viewport ≥ 60rem, a barra
  entregava a quem navega por teclado três botões com `aria-expanded="false"`: os doze
  destinos não estavam na ordem de tabulação e só apareciam depois de expandir cada grupo.
  Abaixo de 60rem a lista já era plana, então os dois públicos recebiam árvores diferentes.
  Agora o submenu abre ao receber foco de teclado e a ordem medida em 1280px é: `Entender →
  Manifesto → O cérebro → O corpo → O mapa → Aplicar → Leis e vieses → Playbook → Ética →
  Conferir → Limites → Métodos → Glossário → Referências → O autor`, com `aria-expanded`
  refletindo o estado real em cada parada. Em 600px a sequência plana anterior permanece
  idêntica. Verificado por percurso automatizado de 22 tabulações nos dois viewports, sem
  erro de JavaScript. Motivação e alternativa descartada em
  [`A11Y-DECISIONS.md`](A11Y-DECISIONS.md).

- [x] **Foco Capturado (Modals/Overlays):** Ao abrir modais, o foco é preso e há `Escape`?
  → **Sim.** O site tem dois overlays. O **modo de foco da busca** aplica `inert` ao
  restante do documento (o que remove tudo da tabulação sem gerenciar a lista à mão),
  move o foco para o campo, fecha em `Escape`, no botão de fechar, no clique fora e ao
  navegar para um resultado — comportamento coberto por um teste de máquina de estados de
  8 casos, todos passando. Os **popovers do glossário** usam a API nativa `popover`, cujo
  fechamento por `Escape` e por clique fora é do próprio navegador (light dismiss).

## 3. Comportamento e Retorno de Tarefas

- [ ] **Screen Reader Test:** Realizou a tarefa principal usando VoiceOver/NVDA?
  → ❌ **NÃO REALIZADO.** Este checkpoint exige uma pessoa operando um leitor de tela real.
  Nenhuma verificação automatizada substitui isso, e nada neste relatório deve ser lido
  como se substituísse. **É o item que impede o status ✅ PASS.**
  **Escopo mínimo quando for feito:** (a) chegar de `#/` a uma lei pelo menu e ler os cinco
  tempos; (b) usar a busca em modo de foco e alcançar um resultado; (c) abrir e fechar um
  popover de glossário no meio de um parágrafo; (d) percorrer a lista textual do mapa e
  confirmar que ela sustenta a tarefa sem o canvas — o que também decide a exceção
  EXC-2026-001.

- [x] **Mudança de Status (`aria-live`):** Erros de formulário, loading states ou
  atualizações não visuais são anunciadas? → **Sim, nos dois lugares em que há mudança
  não visual.** O placar do playbook usa `role="status"` para a leitura do resultado
  conforme os sintomas são marcados; a busca anuncia a contagem de resultados na mesma
  região viva. O site não tem carregamento assíncrono nem erro de rede: é um documento
  único, sem estados de loading.

- [x] **Preenchimento de Formulários:** Labels corretas e relacionadas em todos os inputs?
  → **Sim, verificado.** Zero inputs sem label em 16 rotas. Os únicos campos do site são o
  da busca (com `<label>` associado), os checkboxes do playbook (cada um dentro do próprio
  `<label>`) e os rádios do alternador do mapa (dentro de `<fieldset>` com `<legend>`).

## 4. Percepção Visual e Compreensão

- [x] **Contraste de Texto & UI:** Todos os textos possuem ratio 4.5:1 e componentes
  essenciais 3:1? → **Sim. 14/14 pares no piso, medidos nos dois temas** em 2026-08-01
  (`scratchpad/contraste.py`, cálculo WCAG a partir dos tokens):

  | Par | Onde | Escuro | Claro | Piso |
  |---|---|---:|---:|---:|
  | `--ink` / `--bg` | prosa | 16,79 | 16,42 | 4,5 |
  | `--ink-muted` / `--bg` | lead, listas, legendas | 7,80 | 6,09 | 4,5 |
  | `--ink-faint` / `--bg` | meta, contagens, créditos | 5,12 | 5,23 | 4,5 |
  | `--accent` / `--bg` | links e chips | 8,67 | 6,02 | 4,5 |
  | `--ink-faint` / `--bg-raised` | cartões | 4,66 | 5,47 | 4,5 |
  | `--line-strong` / `--bg` | borda de controle | 3,73 | 3,29 | 3,0 |
  | `--accent-ink` / `--accent` | botão forte, ícone do mapa | 8,67 | 6,02 | 4,5 |

  `--line` (1,53 / 1,27) é decorativa — divisores e molduras — e está fora do escopo da
  SC 1.4.11 por decisão registrada no `A11Y-DECISIONS.md`. A borda que **identifica**
  controle é sempre `--line-strong`.
  Verificado também o pior caso da imagem de fundo da seção de inspiração: prosa sobre o
  pixel mais escuro do fundo dá **4,98:1** no tema claro, com a opacidade calibrada em 0,09
  exatamente para isso.

- [ ] **Redundância:** Erros e alertas não comunicam por cor exclusiva?
  → **Verificado por análise; não verificado por simulador.** Nenhum estado do site
  depende de matiz: filtros usam preenchimento + peso, o item ativo do menu usa peso +
  régua de 2px, a chave do mapa usa forma (cheio/vazado), tamanho e traço
  (contínuo/tracejado), e as duas colunas da matriz de ética usam marca lateral + rótulo
  de coluna. O tracejado das arestas de vizinhança foi implementado nesta rodada
  justamente porque a distinção dependia só de cor. **O que falta:** passar as telas por um
  simulador de deuteranopia/protanopia/tritanopia, que é o que o protocolo pede. Item
  aberto. *(Nota de contexto: o autor é daltônico e é o revisor visual do projeto — o que
  reduz o risco, mas não é o teste pedido.)*

- [x] **Scale / Zoom:** Texto a 200% sem perda (SC 1.4.4) e reflow a 320 CSS px
  (SC 1.4.10) sem rolagem bidimensional? → **Sim, por construção verificada no CSS.**
  Não há `maximum-scale` nem `user-scalable=no` no viewport. Toda tipografia é `rem` ou
  `clamp()` com base relativa — zero `font-size` em `px` fixo no corpo do texto. Larguras
  usam `max-inline-size`/`minmax()`, e todo conteúdo largo (tabelas, diagramas, blocos de
  código, a lista de referências) está em contêiner com `overflow-x: auto` próprio, de modo
  que o `<body>` nunca rola na horizontal. Breakpoints em `rem` respondem ao zoom.
  **Ressalva honesta:** isto foi verificado lendo as regras e o DOM, não redimensionando um
  navegador real. Um teste visual a 320px e a 200% continua sendo devido.

---
## 📝 Notas de Avaliação ou Bloqueios Conhecidos

- **Nota 1 — Exceção ativa.** `EXCEPTIONS.md` → **EXC-2026-001**: o `<canvas>` do grafo não
  oferece exploração livre por leitor de tela. Severidade 🟡 Medium, dono e aprovador
  Felipe Carriço, expiração **2027-02-01**. O fallback é a lista textual completa servida
  no mesmo documento, com atalho declarado. Nenhuma exceção vencida.

- **Nota 2 — O que impede o ✅ PASS.** Dois checkpoints exigem uma pessoa: o teste com
  leitor de tela (§3.1) e o simulador de percepção de cor (§4.2). Enquanto eles não forem
  feitos, o status honesto deste projeto é **CONDICIONAL**, e não PASS. O protocolo é
  explícito de que a certificação depende de "validação humana obrigatória"; marcar esses
  itens sem tê-los feito seria fabricar evidência, que é a única falha deste relatório que
  não teria conserto.

- **Nota 3 — Este relatório chegou tarde.** O projeto acumulou dezenas de publicações antes
  de ter seu primeiro REPORT, e o EXCEPTIONS.md não existia até hoje. A análise técnica do
  porquê, e o que deveria mudar no próprio A11Y.md para que isso não fosse possível, está
  em [`A11Y-POSTMORTEM.md`](A11Y-POSTMORTEM.md).

- **Nota 4 — Mudança de conteúdo posterior a este relatório (2026-08-01, mesma data).**
  Os 30 verbetes do glossário ganharam corpo (2 a 3 parágrafos cada) e 17 deles receberam
  prancha anatômica reaproveitada de Fundamentos — nenhuma imagem nova, todas de licença
  livre já creditadas em `#/referencias`. A varredura estática das §1-§2 foi repetida
  depois da mudança e os resultados acima continuam válidos: zero `div` clicável, zero
  controle sem nome, zero `img` sem `alt`, hierarquia de títulos sem saltos. O contraste
  não foi afetado (nenhum token mudou).

- **Nota 5 — Verificação contínua.** O projeto mantém `verificar.py`, que roda antes de
  cada publicação e falha em: rota que chama função inexistente, link para rota inexistente,
  classe CSS declarada e não usada, CSS estruturalmente inválido, lei sem fonte rastreável,
  entrada de bibliografia sem caminho até a fonte, divergência de chaves entre os idiomas e
  crase dentro de comentário HTML. São guardas de integridade, não de acessibilidade — mas
  várias nasceram de defeitos que quebravam páginas inteiras, e página quebrada é barreira
  de acesso para todo mundo.

---

## Revisão de 07/09/2026 — reescrita de voz, página de casos e verificação cross-agent

- **Data do Teste:** 07/09/2026 · **Cobre a interface em:** `src/` após a reescrita geral de voz (Ética, Manifesto, Limites, os quatro capítulos, 31 aplicações, cinco métodos, passe de travessão e de vírgula), o inglês novo de Manifesto, Limites e do cartão de Ética, e as mudanças de interface listadas abaixo.
- **Status:** ⚠️ **CONDICIONAL** — os checkpoints automatizados se sustentam por verificação cross-agent; os humanos seguem abertos e a exceção EXC-2026-001 segue ativa.
- **O que mudou de interface:**
  - `#/casos` (rota nova): lista os blocos *Um caso* das leis; reusa `.grupo`, `.caso` e o ligador; `h1` → `h2` por caso; entrada de menu no header, no nav e no rodapé, com `aria-current`. A preposição do rótulo ("É um caso da/do") segue o gênero do nome da lei.
  - Catálogo `#/leis`: selo textual `caso` e contagem "com caso" no mesmo elemento do selo `exercício` (`.linha__demo`, uma regra CSS para os dois).
  - `#/manifesto`: parágrafos, abertura, contexto e hipótese renderizam pelo ligador (tooltips de termo e de autor, o componente `popover` já usado no resto do site). O título da caixa fóssil passou de `<p class="eyebrow">` para `<h2 class="eyebrow">` (CSS: `h2.eyebrow { font-weight: 400 }`), fechando um salto h1 → h3 herdado.
  - Idioma (SC 3.1.2) nos dois sentidos: os trechos em português dos três popovers (`definicao__termo`, `definicao__curta`, `autor__mediu`) ganham `lang="pt-BR"` só quando o documento é `lang="en"`; as rotas `#/leis`, `#/casos` e `#/etica`, cuja interface já é inglesa, deixaram de receber o envelope `<div lang="pt-BR">` do fallback e marcam o português elemento a elemento (`LANG_PT()` em `src/app.js`, `ROTAS_LANG_PROPRIO`); os chips de filtro aceitam atributo por item; no manifesto inglês os dois links portugueses de "Continuar" e o `<em>o mesmo</em>` da nota de tradução estão marcados.
- **Verificação cross-agent, primeira rodada** (achados do verificador, todos lidos do DOM): (1) salto h1 → h3 na caixa fóssil do manifesto, pt e en; (2) português sem `lang` em 5 popovers do manifesto e 7 de Limites em inglês, regressão direta do ligador no manifesto; (3) envelope `lang="pt-BR"` cobrindo `h1`, lead e títulos de grupo em inglês em `#/leis`, `#/casos` e `#/etica`; (4) "É um caso **da** Efeito da posse" em 5 dos 8 casos. Mais o gate `verify-a11y.py` acusando o REPORT mais antigo que o `src/`.
- **Segunda rodada, sobre o build corrigido:** os quatro fechados. Hierarquia pt `h1 → h2 → h3 → h3 → h2` e en idem, `h1` único em 10/10 páginas; `autor__mediu[lang]` em 5/5 e 6/6 cartões, `definicao__*[lang]` em 17 popovers de termo e nas prévias de lei, rótulos ingleses sem atributo, e em português nenhum popover com `lang` (o único `[lang]` do documento pt é o link de troca de idioma); nenhum filho direto de `#conteudo` com `lang` nas cinco rotas inglesas, as demais não traduzidas mantêm o envelope; catálogo 38/38 nomes e enunciados, 5/5 substratos, 5/5 trilha; casos 8/8 títulos, links, blocos e `svg[role=img]`; as 8 preposições concordando. Sem regressão: 0 controles sem nome, 0 ids duplicados, 0 `tabindex` positivo, foco no `h1` em 10/10 trocas de rota, selos 30 + 8 batendo com as contagens nos dois idiomas. Três sobras que ele apontou (3 chips de `#/etica` [en], 2 links do `.relacionados` do manifesto [en], o `<em>` da nota) foram fechadas depois da segunda rodada e conferidas **só por esta sessão**, no render.
- **Aberto por exigir pessoa:** percurso real de Tab e retorno de foco no `Escape` dos popovers; `aria-expanded`/`aria-details` expostos pelo navegador no gatilho (jsdom não implementa a API); anúncio de troca de rota por leitor de tela; zoom/reflow; simulador de daltonismo; SC 2.5.3 por voz; `prefers-reduced-motion` nas barras animadas do manifesto.
- **Avisos do gate que não são desta revisão:** `outline: none` em `estilo.css` (linhas 150 e 1933, de 07/08/2026): há anel substituto, mas ele é `box-shadow` e some em forced-colors. Fica registrado para a próxima revisão de CSS.
- **Gates, saída registrada abaixo** (`verificar.py` → 0):

```
! [outline-none] src/estilo.css:150 — outline suppressed — pair it with a visible focus indicator that survives forced-colors mode; a box-shadow ring alone disappears there (SC 2.4.7)
! [outline-none] src/estilo.css:1933 — outline suppressed — pair it with a visible focus indicator that survives forced-colors mode; a box-shadow ring alone disappears there (SC 2.4.7)
PASS with 2 warning(s).
exit=0
```

- **Terceira e quarta rodadas (cross-agent, mesmo verificador, mais tarde no mesmo dia).** O que mudou depois da segunda: os 30 blocos *Um caso* novos (a página `#/casos` foi de 8 para 38; cada caso com a fonte renderizada como link externo, `target="_blank"` e `rel="noopener noreferrer"`, pelo mesmo padrão do resto do site); a rota `#/reportar` (formulário de erro ou caso real, com anexos) e o link fixo `a.reportar` no canto inferior direito, presente em todas as rotas e repetido em texto no rodapé; o receptor `reportar.php`, que **não roda no ambiente de verificação** e foi testado à parte, num contêiner PHP 8.2, com `curl` (405 no GET, 422 nos inválidos, gravação com anexo, isca engolida). Lido no DOM pelo verificador: `#/casos` com `h1` único, 38 `h2`, 38 links de lei, 38 blocos com `lang="pt-BR"` em inglês, contagens do catálogo batendo (38 conceitos, 30 com exercício, 38 com caso), busca encontrando os casos novos nos dois idiomas; 30 links de fonte com nome acessível e `rel`; `#/reportar` com todos os campos rotulados, `fieldset`/`legend`, `aria-describedby` 5/5 válidos, isca fora da árvore e sem `required`, `role="status"` presente, foco no `h1`, sem envelope em inglês; `a.reportar` com nome nos dois idiomas, SVG decorativo, 48 px, `z-index` abaixo do topo e da busca, anel de foco global preservado. **Um achado novo, 🟡:** em 390×844, no meio de páginas longas, o botão fixo cobre o fim de duas linhas de texto (nada coberto em 1280×900 nem no fim das páginas). Tratado como decisão em `A11Y-DECISIONS.md` (44 px abaixo de 640 px, destino repetido em texto no rodapé), não como correção. **Achado de site inteiro, anterior a hoje:** 171 links externos abrem em nova aba sem aviso textual; registrado como opção em aberto no mesmo arquivo.
- **Aberto por exigir pessoa (acrescentado):** SC 3.3.1 a 3.3.3 no formulário, o que a região `role="status"` anuncia no sucesso e na falha com o receptor rodando e um leitor de tela; a sobreposição do botão fixo no celular com dedo e zoom de 200%.
- **Gate, rodado de novo depois dessas mudanças:**

```
! [outline-none] src/estilo.css:150 — outline suppressed — pair it with a visible focus indicator that survives forced-colors mode; a box-shadow ring alone disappears there (SC 2.4.7)
! [outline-none] src/estilo.css:1933 — outline suppressed — pair it with a visible focus indicator that survives forced-colors mode; a box-shadow ring alone disappears there (SC 2.4.7)
PASS with 2 warning(s).
exit=0
```

- **Figuras nos casos (mais tarde em 07/09, self-reported).** Nove blocos *Um caso* ganharam uma figura real (foto ou documento) acima do texto: `<figure class="caso__figura">` com `<img>` de `alt` descritivo escrito olhando a imagem, `width`/`height` declarados, `loading="lazy"`, e `<figcaption>` com legenda e crédito (autor, origem e licença como links externos, no mesmo padrão da prancha anatômica). Imagens só com licença conferida na página de origem (domínio público, registro público da Flórida, CC0, CC BY-SA); a tabela da pesquisa está em `avaliacoes` do lab. O diagrama desenhado do Magic Mouse foi substituído pela foto. Imagem menor que a coluna fica no tamanho natural (o botão do Windows 95, 580 px). Não reverificado por agente; conferido por esta sessão no render de `#/casos` e `#/lei/lei-da-proximidade`. O gate do padrão continua PASS.
- **Mais catorze figuras (self-reported, mesmo dia, mais tarde):** capturas fornecidas pelo autor (interfaces de terceiros, uso editorial, crédito e origem na legenda; a licença aparece como texto quando não há link de licença). A similaridade trocou o alerta do celular pelo menu do sistema. Total de 22 casos com figura. Mesmo componente, mesmo `alt` descritivo escrito olhando cada imagem; o `verificar.py` acusou "logo abaixo" em dois `alt` como meta-referência e a expressão foi trocada. Gate do padrão: PASS mantido.
- **Exercícios (mais tarde em 07/09, quinta rodada cross-agent).** A página da lei passou a mostrar o caso antes do exercício, e o caso perdeu a caixa (só `.demo` continua em caixa). Cinco exercícios novos (Parkinson, escassez, transparência, estética, apoio à escolha), dois gráficos convertidos em exercício com o gráfico mantido dentro (pico-fim, posição serial), Zeigarnik refeito, e complementos no Tesler (tabela com `caption`, checkboxes nomeados, diálogo `role="group"`) e na proximidade (cédula com `role="group"` e seis botões nomeados). O verificador leu os dez no DOM, chegou ao estado final de cada um por interação, conferiu nome acessível em 100% dos controles, `aria-live` onde o resultado muda, 0 `tabindex` positivo, 0 ids duplicados, montagem única em ida e volta de rota, e a hierarquia h1 → h2 → h3 em todas as rotas. Dois retoques pedidos e feitos depois da rodada, conferidos só por esta sessão: a régua das batidas virou decorativa (`aria-hidden`, a região viva narra) e a tabela do Flexcube ganhou `caption`. Também entrou, por conta própria, o registro de batida por `click` no pad, para ativação por tecnologia assistiva.
- **Aberto por exigir pessoa (acrescentado):** para onde vai o foco quando um bloco `[hidden]` é revelado nos exercícios em etapas; se as três regiões vivas da estética competem; o som da transparência (AudioContext não roda no jsdom; a régua é a alternativa visual); o tempo real das rodadas do pico-fim (SC 2.2.1); contraste e alvo dos controles novos; `prefers-reduced-motion`.

## Revisão de 08/09/2026 — pente fino de conceitos, estrutura e voz

- **O que mudou no site.** Texto, não estrutura: 254 reescritas de voz (dois-pontos, travessão-aforismo, fecho de efeito, jargão do site vazando para a prosa) aplicadas em `src/conteudo.js`, `src/textos-pt.js`, `src/glossario.js` e três `pe` de exercício em `src/app.js`, todas com o trecho original registrado em `avaliacao/pente-fino-2026-09-08/consolidado.json` e backups datados em `antes/`. Dois defeitos de código: o marcador `{leis}` que chegava cru à home no cartão do corpo (`replace` trocava só a primeira ocorrência; agora `replaceAll`, pt e en) e as 14 páginas de método e instrumento que compartilhavam o título de aba "Página" (SC 2.4.2; agora cada uma leva o próprio nome).
- **O que não mudou.** Nenhuma edição de marcação, foco, contraste, nome acessível ou ordem de leitura. O `estilo.css` não foi tocado; os dois avisos `outline-none` são os mesmos de agosto.
- **Como foi verificado.** Esta rodada é automatizada e **autodeclarada**, não cross-agent: `verificar.py` sem quebra (56 leis, 141 referências, 0 referências quebradas), `build.py` limpo, as 70 rotas re-renderizadas por `avaliacao/navegar.mjs` e varridas por padrão de pontuação quebrada (nenhuma), gate `verify-a11y.py` rodado depois deste adendo. Os achados de conceito (195) e de estrutura (28) **não foram aplicados**: estão na página de decisões do autor, porque são decisão de conteúdo, não de conformidade.
- **Achado de ferramenta.** `navegar.mjs` termina com `process.exit(0)` e, com a saída em pipe, cortava páginas longas em 8 KB; oito rotas chegaram truncadas aos revisores na primeira passada. Corrigido no `renderizar.py` (saída direto em arquivo) e os três revisores afetados releram as páginas inteiras. Quem usar o `navegar.mjs` em pipe deve saber disso.
- **Aberto por exigir pessoa (sem mudança).** Os mesmos checkpoints da revisão de 07/09.

## Revisão de 08/09/2026, segunda rodada — aplicação dos achados de conceito, estrutura e voz

- **O que mudou no site.** A pedido do autor ("aplicar tudo, com prudência reputacional"), os 491 achados que esperavam decisão foram aplicados por nove aplicadores em cópias de trabalho e fundidos no fonte (`avaliacao/pente-fino-2026-09-08/logs/L1..L9.md` registram achado por achado; `decisoes.json` consolida). Texto em `src/conteudo.js`, `src/glossario.js`, `src/textos-pt.js`, `src/leituras.js`, `src/figuras.js` e nos `pe` dos exercícios em `src/app.js`; paridade levada a `src/conteudo-en.js` e `src/textos-en.js` (`logs/EN.md`). Bibliografia: 25 entradas novas e 3 corrigidas, todas com DOI ou URL em `FONTE_PRIMARIA`.
- **Mudanças que tocam a estrutura acessível.** (1) `#/casos` ganhou cabeçalhos de eixo (`h2`) e os títulos de caso passaram de `h2` a `h3`; cada caso já tinha `id` próprio. (2) Bloco "Continuar" (mesmo `div.relacionados` + `ul` das outras páginas) acrescentado ao fim de `#/leis`, `#/casos`, `#/referencias`, `#/fundamentos`, `#/metodos`, `#/playbook` e `#/reportar`. (3) `#/grafo` ganhou uma lista de três itens com a legenda das formas, logo após o lead. (4) Rótulos: menu e rodapé "O mapa" → "Conexões"; "Limites" → "Limites da evidência"; "Explorar" → "Ver nas conexões"; nas páginas de método, o link de volta e o do outro grupo nomeiam o grupo. (5) Home: cartões reordenados (motor, catálogo, corpo, linha, medir) com uma linha de apoio antes; as quatro citações dos números levam à entrada exata da bibliografia (`?em=ref-…`), assim como a fonte do mecanismo nas leis de nível A. (6) Chips "Como medir isso no seu produto" com o nome do método por extenso e a sigla entre parênteses. (7) A nota automática de nível B só aparece quando a lei lista alguma estrutura no grafo. (8) O caso da Lei de Parkinson foi removido (sem fonte); o catálogo de casos tem 37.
- **O que não mudou.** `estilo.css` intocado; nenhum controle novo; foco, contraste e nomes acessíveis dos componentes existentes iguais.
- **Como foi verificado.** `build.py` limpo, `verificar.py` com saída 0 (166 referências em ordem, nenhuma quebrada, paridade de chaves pt/en), as 70 rotas re-renderizadas e varridas por pontuação quebrada. Um verificador independente (Opus, contexto novo) leu o diff inteiro do texto novo contra a evidência dos revisores e as páginas renderizadas; o relatório está em `achados/verificacao-final.json` e o que ele apontou foi corrigido antes desta linha. A rodada é **cross-agent na verificação do conteúdo e autodeclarada na de acessibilidade**: os checkpoints humanos seguem os mesmos.
- **Conferência cruzada, resultado.** O verificador final apontou 20 resíduos (11 altos), quase todos de mesclagem: correção que entrou numa página e não alcançou a gêmea (contagens de nível em Limites e Corpo, a data do cérebro em Fundamentos, duas fichas em Referências, o cortisol contra o próprio verbete), mais dois de código, entre eles a condição da nota de nível B, que passou a depender do grafo e sumiu de 12 páginas. Corrigidos todos, inclusive no inglês: a nota B agora aparece quando o texto da lei cita alguma estrutura do glossário; o grupo de métodos passou a se chamar "O que se lê no corpo", coerente com o parágrafo que diz que só três dos sete pedem laboratório; o catálogo de casos se declara "lei por lei" e diz que uma das 38 ficou sem caso. Build e `verificar.py` limpos depois disso; as 70 rotas re-renderizadas sem glitch de pontuação.
- **Três decisões do autor, aplicadas em 08/09 à noite.** (1) Sexto eixo do catálogo, "Sobre o trabalho, não sobre quem usa", com Tesler, Occam, Pareto e a heurística de Nielsen; `#/leis`, `#/casos` e os filtros derivam dos eixos, então ganharam a seção sem código novo; rótulo "Os seis eixos". (2) "Dois caminhos" renomeada para "Flexibilidade e eficiência de uso", o nome de Nielsen, com slug `flexibilidade-e-eficiencia-de-uso`, imagem do caso renomeada e todos os links internos atualizados; sem link externo prévio. (3) Efeito da posse promovido a nível A com Knutson et al., 2008, lido pelo consolidador no Europe PMC (24 participantes, compra, escolha e venda em fMRI); a nota A aponta para a entrada exata da bibliografia; contagens em Limites e no corpo atualizadas para três leis A, dezessete B e dezoito C, em pt e en. Build, `verificar.py` e as 70 rotas re-renderizadas limpos.
- **Reportar, na variante artefato (08/09, noite).** O inseto fixo e o link do rodapé deixaram de ser removidos da cópia publicada como artefato; só o receptor (`data-reportar`) continua vazio. Sem receptor, `#/reportar` mostra o formulário inteiro com um aviso em negrito antes dos campos ("aqui o envio é simulado"), e o envio, depois das mesmas validações do cliente, troca o formulário pelo bloco de confirmação com o texto `okSimulado` e foco no `h2`, sem `fetch`. Nada muda no site real, que continua postando para `reportar.php`.
- **Home, a pedido do autor (08/09, noite).** (1) O pós-escrito abaixo da citação saiu (`posEscrito` removido de pt e en, com o CSS `.hipotese__ps`). (2) A grade das cinco portas estava quebrada por uma regra `.cartoes` do exercício de Zeigarnik, acrescentada em 07/09 no fim do `estilo.css` com os mesmos nomes de classe da home; ela passou a ser escopada a `.demo`. A grade da home agora tem seis colunas acima de 68rem (motor, catálogo e corpo com duas colunas cada; linha e medir com três), o corpo ocupa a linha do meio entre 44 e 68rem, e uma coluna abaixo disso; a margem de seção do `.cartao--largo`, que vale em `#/metodos`, foi zerada dentro da grade. A ordem do DOM não mudou; só a grade. Conferido em 1280, 900 e 420 px.
- **Página de casos, a pedido do autor (08/09, noite).** Entre dois casos consecutivos entrou um filete com 3,5rem de respiro acima e 4,5rem de margem (`.grupo--caso + .grupo--caso`), os cabeçalhos de eixo ganharam margem própria, e a linha da fonte perdeu o filete só nessa página (`.casos__eixo ~ .grupo--caso .caso__fonte`), porque ali ela lia como divisor de seção. Nas páginas de lei nada muda. Só CSS; DOM e ordem de leitura iguais.
- **Busca, conferida depois das mudanças (08/09, noite).** O índice é montado em tempo de execução a partir do conteúdo, então o texto novo entrou sozinho: 24 consultas com termos novos e corrigidos (Knutson, Huettel, Kunst-Wilson, Conde-Valverde, Kwasa, Tuch, Alaybek, Ross e Amabile, Magic Mouse, o hotel da prova social, o nome novo da heurística e o nome antigo, o eixo novo) devolveram a página certa. Um buraco fechado: a legenda da figura e a fonte do caso passaram a compor o documento da lei, porque "Flexcube" só existia na legenda e não achava Tesler. Siglas com ponto ("S.D.N.Y.") continuam fora do índice, por desenho do tokenizador.
- **Mapa de conexões, a pedido do autor (08/09).** (1) Bug do alternador Estruturas/Conceitos: o controle mandava `estrutura`/`design` e o mapa esperava `neuro`, então voltar para Estruturas não voltava; `alternarModo` passou a traduzir. (2) A lente de dimensão virou pílula na altura e no desenho do alternador, com rótulo dentro e seta desenhada por borda (herda a cor do tema); rótulo encurtado para "Dimensão do corpo". (3) O corte de grau do grafo caiu de 2 para 1: entra toda estrutura que alguma lei cita no texto, como achado ou como ponte declarada; o mapa foi de 5 estruturas e 9 leis para 16 e 17, e o parágrafo do recorte diz isso. A lista "As mesmas conexões, em lista" segue o mesmo dado. Nada muda no foco, no teclado ou nos nomes acessíveis.
- **Pontes declaradas e mapa ligado (08/09, tarde), a pedido do autor.** (1) Conteúdo: 19 leis ganharam no mecanismo uma ponte declarada entre a função em que se apoiam e a estrutura que a literatura amarra a essa função, com fonte lida; 12 subiram de C para B; seis referências novas (Bartra 2013, Corbetta e Shulman 2002, Gilboa e Marlatte 2017, Krauzlis 2013, Mitchell e Johnson 2009, Roelfsema 2006). Níveis agora: 3 A, 29 B, 6 C; contagens em Limites e no corpo atualizadas em pt e en. Duas arestas falsas por negativa (escassez e dopamina; carga e cortisol) e uma por menção fora do mecanismo (Tesler e memória de trabalho) resolvidas no texto. (2) Glossário: verbete novo "memória de longo prazo" (33 verbetes) e campo `liga` em todas as entradas, com as ligações anatômicas e funcionais entre estruturas. (3) Mapa: arestas estrutura–estrutura (tipo `entre`), pontilhadas, com item próprio na legenda ("estrutura e estrutura") e a linha "Liga-se a" em cada estrutura da lista textual; o corte de grau caiu para 1. O mapa foi de 5 estruturas e 9 leis para 17 e 32, com 117 arestas. Nada muda em foco, teclado ou nomes acessíveis; a lista textual segue equivalente ao canvas.
- **Verificação das pontes (08/09, tarde).** Um verificador independente leu as 19 frases novas contra as fontes e as páginas renderizadas: 14 achados, 3 altos. Corrigidos todos: a frase quebrada da escassez; Hick-Hyman, cuja ponte com memória de trabalho contradizia o neuromito da própria página, passou a apoiar-se na seleção entre alternativas (Corbetta e Shulman, 2002); a mera exposição perdeu a ponte com o temporal medial, que a literatura contraindica para um efeito sem reconhecimento, e voltou a C; ilusão de controle, conectividade, proximidade, flow, saliência e Jakob ajustados ao que cada fonte diz; von Restorff com a ponte no fim do bloco; flexibilidade e eficiência de uso declara a ponte na prosa. Níveis: 3 A, 28 B, 7 C, contagens em pt e en. Mapa: 17 estruturas, 31 leis, 115 arestas.
- **Formulário de reportar ao vivo (08/09, 12h56).** Com o site no ar, o `mail()` do plano da KingHost devolveu `false`; o receptor passou a enviar por SMTP autenticado (`smtp.samebrain.design:465`, TLS implícito com certificado verificado, conta `reportar@samebrain.design`), com as credenciais em `/home/<conta>/reportar.config.php`, fora da raiz pública (conferido: 404 pela web), gravadas pelo `publicar.py --config-smtp` a partir de variável de ambiente. Cada relato guarda `email.json` com o resultado do envio. Terceiro envio de teste aceito pelo servidor (`email: true`, `via: smtp`). Nada muda na interface.
- **SEO e compartilhamento (08/09, 13h).** O `head` já tinha descrição, canônica, `hreflang`, Open Graph com imagem e cartão do Twitter; faltavam no ar a pasta `og/` (não subia no `publicar.py`) e o favicon. Entraram: ícones derivados da composição do autor (`assets/og/samebrain-icone-icone.png`, recorte e redução, sem redesenho) em favicon.ico, 32 px, apple-touch 180 e 192/512 com `site.webmanifest`; `sitemap.xml` com as duas raízes e `hreflang`; `robots.txt` apontando o sitemap e fechando o receptor; dados estruturados JSON-LD (WebSite + Person). O `publicar.py` passou a enviar tudo isso e a `og/`. Nada muda na interface renderizada; os ícones têm `alt` implícito pelo contexto e a cor de tema já existia.
- **Miniatura no WhatsApp (08/09, 13h20).** No ar, a imagem larga responde 200 e as tags estão nos primeiros 2 KB; a ausência de prévia foi cache do rastreador, que guardou o 404 da primeira publicação. Entrou uma segunda `og:image`, quadrada, a composição `samebrain-icone-icone.jpg` do autor (512 px, 64 KB), para leitores que preferem o quadrado; a larga continua primeira.
- **Responsividade, a pedido do autor (08/09, tarde).** Medição em 390×844, 768×1024 e 1440×900 com Playwright, 16 rotas (`avaliacao/responsividade-2026-09-08/`). Três achados grandes, todos corrigidos: (1) abaixo de 60rem a barra de seções tinha 3px de largura e nenhum dos 13 links aparecia — entrou o botão de menu `#menu` com `aria-expanded`/`aria-controls`, painel abaixo do cabeçalho, `Escape` que fecha e devolve o foco, fechamento por navegação, toque fora e redimensionamento; o "EN" da barra vai para o fim do painel no celular. (2) O mapa de conexões no celular: texto e chave cobriam o canvas, o painel do nó ficava fora do quadro, os blocos mediam 395px em tela de 390 (seletor de dimensão com rótulo sem quebra) e `touch-action: none` prendia a rolagem — abaixo de 52rem a camada da frente vai para o fluxo (controles, mapa em 72svh, painel, chave em `<details>` recolhido, atalhos, e só então título e texto), o seletor estica, e em ponteiro grosso o canvas usa `pan-y`. (3) Capa: abaixo de 64rem texto centralizado e título com piso de 2,75rem; abaixo de 40rem botões em largura cheia e cérebro em 15,5rem, os dois botões acima da dobra em 844px. Miudezas: piso de 13px para créditos e fontes de referência abaixo de 40rem, área de toque dos termos do glossário ampliada em ponteiro grosso (padding e margem negativa, sem mexer na linha), `.tabela-envelope` limitado à coluna e coluna da camada do mapa com `minmax(0, 1fr)`. Conferido depois: `verificar.py` com saída 0, largura de rolagem igual à do viewport em 390 e 768 na capa e no mapa (a matriz reporta `scrollWidth` de 852 mas `scrollX` não sai de 0: o envelope rola por dentro), 14 links visíveis com o menu aberto, painel do nó visível ao tocar. Registro em A11Y-DECISIONS (três decisões novas, uma revista). Fora do escopo: rótulos de SVG dos experimentos em 9,5px, recolher casos por eixo, e o botão fixo de reportar sobre o fim das linhas (decisão anterior mantida).
- **Segunda rodada do celular, a pedido do autor (09/09).** Sete pontos reportados depois da publicação. (1) O link de idioma que eu tinha posto no painel do menu saiu; o "EN" volta a ser só o botão da barra, e abaixo de 26rem os seis controles ficam com 40px para caber em 390 (medido: 124 a 374px, sem estouro). (2) Página do grafo em notebook de 768px de altura: a cabeça media 525px e empurrava "Ler como lista" para fora do quadro — saíram os três marcadores redundantes com a chave e a nota "O mapa traz as 17 estruturas…" (chaves `recorte` removidas de pt e en); a cabeça passou a 319px e os atalhos terminam em 728px; abaixo de 46rem de altura a chave nasce recolhida e o título do recolhível aparece. (3) Mapa no celular, outra solução: a versão em fluxo saiu; abaixo de 52rem a rota abre um diálogo modal em tela cheia (`.mapa--app`), com fechar, alternador, seletor, canvas com `touch-action: none` (a pinça volta a dar zoom), chave em pílula que abre por cima, e o cartão do nó na base da mesma tela; `inert` no resto, `Escape`/fechar/"Ler como lista" devolvem o foco; o cabeçalho fixo e o botão de reportar somem enquanto o app está aberto. Fechado, sobra "Abrir o mapa" e o texto. No quadro pequeno o nó ancorado cresce 60% do desktop e o raio não acompanha a aproximação. Medido: abre ao entrar com foco no fechar, o toque num nó escreve o cartão em 652–832px na tela de 844, fechar devolve o foco a "Abrir o mapa", "Ler como lista" fecha e foca a lista, nenhum erro de JavaScript. (4) Tab na capa entrava no cérebro 3D: os quatro objetos ambientes (capa, fundamentos, bailarina, retrato) passam a `role="img"` sem tabindex; o mapa continua focável. (5) Formulário de reportar: o receptor no ar respondeu a um envio de teste meu às 23h19 com `{ok, email: true, via: smtp}`; a falha relatada não se reproduziu daqui — fica aberta até ele dizer a mensagem que viu. (6) Título da capa no celular: piso de 3,25rem (52px em 390). (7) "Erros de rota": o site no ar foi percorrido em 10 rotas, notebook e celular, sem erro de console nem de página; nada a corrigir sem a descrição dele. Verificação: `verificar.py` com saída 0, gate rodado depois deste adendo.
- **Peso da página, versão em inglês e endereço (10/09).** Três queixas do autor depois da publicação. (1) Lentidão: medido no ar, `index.html` com 4.456.791 bytes, `Content-Encoding` ausente e nenhum `Cache-Control`; 2,3 MB eram 32 imagens em base64 dentro do HTML. Agora o site referencia as imagens em `/imagens/` (29 arquivos, `loading="lazy"` já existia nos `<img>`, com `width`/`height`), e o HTML caiu para 2,1 MB; a variante artefato continua embutindo, porque é um arquivo só. Entrou `dist/.htaccess` (de `assets/htaccess`): `mod_deflate` para HTML, CSS, JS, JSON e SVG; cache de uma semana para imagens e ícones e `no-cache` para HTML; redirecionamento 301 de `http://` e de `www.` para `https://samebrain.design`, com a condição por `X-Forwarded-Proto` para não entrar em laço atrás de proxy. Nada disto muda marcação, foco ou nome acessível. (2) "O que houve com o inglês": nada. A versão em inglês sempre foi parcial — interface, capa, manifesto, corpo, limites, sobre e reportar traduzidos; leis, fundamentos, casos, ética, glossário e mapa ainda em português, marcados com `lang="pt-BR"` — e o aviso no topo dessas rotas diz exatamente isso (`avisoDeIdioma`, `ROTAS_TRADUZIDAS`). Medido rota a rota no build em inglês; nenhuma mudança. (3) `index.html#/` na URL: vinha do seletor de idioma, que apontava para `en/index.html` e `../index.html`; agora aponta para `en/` e `../`, e a substituição da variante artefato ficou ancorada no atributo `href`. "Erros de rota": nenhum erro de console ou de página em dez rotas, notebook e celular, no site no ar. Verificação: `verificar.py` com saída 0, `dist/` servido por HTTP local com as imagens carregando em `/` e em `/en/`, gate rodado depois deste adendo.
- **O estudo inteiro em inglês (10/09, tarde e noite).** A pedido do autor, depois de ele constatar que a versão em inglês cobria só a interface e seis rotas. Escopo: as 38 leis (nome, enunciado, resposta curta, mecanismo, corpo, aplicação, onde quebra, mitos, caso com legenda e alt), os quatro capítulos de fundamentos e a página do cérebro, os sete métodos e sete instrumentos, ética (com a matriz), playbook, estudos raros, atribuições, as 124 frases de "quem mediu", o glossário (33 entradas, com termo, definição curta, corpo e variantes em inglês), as oito figuras anatômicas (legenda, alt, chave de leitura), os créditos de imagem, os textos das 35 demonstrações e dos diagramas didáticos, e onze títulos de seção que viviam escritos direto no app. Mecanismo: `ferramentas/traducao/` (extrator, vocabulário canônico `nomes-en.json` com nomes de leis e variantes de estruturas, 17 lotes traduzidos e conferidos chave a chave, montador) gera `src/conteudo-en-estudo.js`, que entra só no bundle em inglês e sobrepõe a tradução aos dados na carga; as variantes em inglês das estruturas entram no glossário e em `VARIANTES`, então o ligador marca os termos e o mapa acha as ligações no texto traduzido. As demos e os diagramas usam um dicionário em que o português é a chave (`tx`, `tf`, tradução da árvore na montagem e observação das mudanças), com busca por padrão para os textos com número. Acessibilidade: o aviso "This part is not in English yet" e as marcas `lang="pt-BR"` deixam de ser emitidos (`ESTUDO_TRADUZIDO`); os `alt` das figuras seguem dizendo que os rótulos dentro da imagem estão em português; a bibliografia fica nas línguas originais. Conferido no build: resíduo de português zero em 20 rotas do estudo (as exceções são a bibliografia, o nome próprio "Com Cedilha" e a citação intencional em `<em lang="pt-BR">`), zero nas 35 demos antes e depois de clicar em cada botão, 38 páginas de lei sem erro nos dois idiomas, mapa em inglês com 55 nós e 115 ligações iguais ao português, `verificar.py` com saída 0, gate rodado depois deste adendo. Decisões de tradução registradas pelos tradutores em `ferramentas/traducao/` (relatórios nos lotes); a frase do site sobre tradução "à mão, não por máquina" ficou em `textos-en.js` como texto de reserva, não exibido.
- **Página de referências, a pedido do autor (10/09, noite).** Dois defeitos, nos dois idiomas. (1) Ordem: a abertura dos seis "estudos que quase nunca aparecem" dizia "a lista acima está em ordem alfabética", mas o bloco vinha ANTES da bibliografia, logo depois das ilustrações; agora a página é bibliografia (índice A–Z e lista), os seis estudos ao fim dela como `h3`, e uma seção única de créditos (`h2` Créditos, com `h3` para a forma do site e `h3` para ilustrações, modelos 3D e tipografia). Hierarquia conferida: `h1 → h2 → h3` nos dois idiomas; ids `bibliografia`, `raros`, `creditos`, `inspiracao`, `imagens` mantidos, e o link "Abrir a bibliografia" das páginas de lei continua chegando. (2) A página inteira, fora os títulos, vivia escrita em português no `app.js`, inclusive "Bibliografia": os textos passaram para `T.referencias` em pt e en, e os campos de autor, licença e adaptação dos créditos passam pelo dicionário `tx` (7 chaves novas). Conferido no build: títulos em inglês na versão em inglês, sem erro de console, `verificar.py` com saída 0, gate rodado depois deste adendo.
- **Abertura dos seis estudos (10/09, noite).** A pedido do autor, a frase "A lista acima está em ordem alfabética porque serve para consulta. Estes seis estão aqui por outro motivo" saiu nos dois idiomas: o parágrafo começa por "Cada um destes seis mede uma lei famosa num corpo…". Só texto; nada de marcação.
- **Mapa no celular, terceira rodada (11/09), a pedido do autor.** Três defeitos no app do mapa. (1) Nós ovais e texto achatado ao tocar um nó: o canvas só era remedido no `resize` da janela; quando o cartão do nó abria e a caixa encolhia, o buffer ficava com o tamanho antigo e o navegador esticava o desenho. Entrou um `ResizeObserver` no canvas com `redimensionar()`, que acompanha a caixa preservando a câmera (escala e deslocamentos reescalados, zoom e nó ancorado mantidos); e o cartão do nó passou a flutuar sobre a base do mapa (`position: absolute`, fundo translúcido) em vez de empurrá-lo, então a caixa não muda ao tocar. (2) Pinça: não existia tratamento de dois ponteiros — só roda do mouse e teclas `+`/`-`, embora a legenda prometesse a pinça. Agora cada ponteiro é rastreado por id; com dois dedos a distância entre eles multiplica o zoom de partida, dentro dos limites `ZOOM_MIN`/`ZOOM_MAX`; o gesto nunca vira clique ao soltar. (3) Não dava para tocar num vizinho a partir de uma seleção: qualquer tremor acima de 3 px virava arrasto e o toque era descartado; o limiar passou a 12 px acumulados desde onde o dedo encostou quando `pointerType` é `touch` (3 px no mouse). `setPointerCapture` ficou protegido para ponteiros já soltos. Medido em Chromium emulando toque (390×844, DPR 2): toque ancora um nó; toque num vizinho troca a âncora; pinça sintética leva o zoom de 0,57 a 1,72; caixa do canvas forçada de 664 para 400 px atualiza o buffer para 732×800 mantendo âncora e zoom; sem erros. Sem mudança na semântica do canvas (`role="application"`, teclado igual). Gate rodado depois deste adendo.
- **Cartão do nó no celular (11/09), a pedido do autor.** O cartão flutuante ganhou 8 px a mais de recuo nos lados e no pé (20 px das bordas, 80 px do fundo), sombra, e um botão de fechar no canto superior direito (40 px, `aria-label` "Fechar o cartão" / "Close the card", só no app do celular); fechar desfaz a âncora e devolve o foco ao canvas. O nó ancorado passa a ser centrado no espaço livre entre o topo do quadro e o topo do cartão, medido depois de o cartão ser pintado (`definirCentroY` na vista); fora do app o centro continua sendo o do quadro. Medido em toque emulado: recuos 20/20/80, botão presente, espaço livre de 425 px com o nó em y=212, fechar → cartão vazio e foco no canvas; sem erros. Gate rodado depois deste adendo.
- **Negociação de idioma na raiz (11/09), a pedido do autor.** O site não detectava o idioma de quem chega: a raiz servia o português e `/en/` o inglês, sem lógica no meio (só o `hreflang` para buscadores e o botão PT/EN). Agora a raiz negocia, como a landing do A11Y.md: um script no topo do `<head>` de `index.html` (só no site em português; nem em `/en/`, nem nos artefatos) lê `navigator.languages` em ordem e, se a primeira língua que seja pt ou en for inglês, faz `location.replace('en/' + hash)` antes de qualquer pintura, mantendo a rota. Nenhuma das duas deixa em português, que é o `x-default`. O botão PT/EN passou a gravar a escolha (`pr-idioma` no localStorage, gravado no clique e nunca na chegada), e a escolha vale mais que o navegador nos dois sentidos. Robôs (`bot|crawl|spider|slurp` no user agent) e navegadores automatizados (`navigator.webdriver`) ficam onde estão: o buscador acha as duas versões pelo `hreflang`, e as auditorias locais abrem a raiz em en-US. `replace` evita o laço no Voltar. Verificado com Playwright em oito cenários: en-US vai para `/en/` e mantém `#/grafo`; pt-BR, fr-FR e webdriver ficam; escolha gravada pt ou en vale nos dois sentidos; `/en/` nunca redireciona; clicar PT em `/en/` grava `pt` e a raiz passa a obedecer. Sem JavaScript nada muda: português. Gate do padrão: PASS mantido (as 2 advertências de outline são anteriores).
