# ADR-025 — Acessibilidade/UX como gate de CI

| Campo | Valor |
|---|---|
| **Status** | Aceito (2026-10-20) |
| **Data** | 2026-10-14 |
| **Plano de origem** | `wiki/plan/01-analise-e-decisoes.md` |
| **Relacionadas** | ADR-010, ADR-009 |

## Contexto

O portal é governamental e precisa cumprir **eMAG 3.1 + WCAG 2.2 AA**. O `prefeituras_v5` já
produziu guidelines de eMAG; o `sucesu-cms` integrou **sniffCSS** (CSS computado + WCAG) ao
Playwright. Acessibilidade tratada como "polimento final" não sobrevive à pressão de prazo.

## Decisão

- **Playwright + `@axe-core/playwright`** (WCAG 2.2 AA + eMAG) e **sniffCSS** (CSS computado,
  contraste, foco, oclusão, alvos) são **gates** para templates-chave — não relatórios opcionais.
- **Todo componente novo tem teste de a11y** (isolado em fixture Blade + e2e de história).
- Histórias-chave rodam em modo **estrito** (`SNIFF_A11Y_STRICT=1`) e **bloqueiam o merge**.
- Locators por papel acessível (`getByRole`) — o teste reforça a semântica.

## Justificativa (alternativas descartadas)

- **Auditoria manual pontual** — descartada: não bloqueia regressão.
- **Relatório sem gate** — descartada: vira ruído ignorado.
- **Só automação** — descartada: automação cobre ~40%; teste manual com AT real complementa.

## Consequências

**Positivas**
- Acessibilidade vira critério de aceite por construção; regressões param no CI.

**Custos / negativas**
- Gate pode ter falsos positivos (ex.: carrossel "ocluído") → calibração por seletor + exceção
  documentada (nunca silenciar em massa).
- Custo de execução → rodar histórias-chave em paralelo/cache.

## Exemplo mínimo (comparativo)

```ts
// ❌ Sem verificação de acessibilidade
await expect(page.getByText("Publicar")).toBeVisible();

// ✅ Gate axe + sniffCSS na história
const results = await new AxeBuilder({ page }).withTags(["wcag2aa", "wcag22aa"]).analyze();
expect(results.violations).toEqual([]);
// + sniffCSS: contraste/foco/alvos
```

## Verificação

- `make check E2E=1` verde com `SNIFF_A11Y_STRICT=1`; axe sem violações `serious`/`critical`.
- Teclado-only percorre home → detalhe → formulário sem armadilha.

## Referências

- `prefeituras_v5/.agents/guidelines/accessibility/`; `sucesu-cms/tests-e2e/`; `wiki/plan/11-acessibilidade-ux-gate.md`.
