# 07 — CMS: acesso e shell

| Campo | Valor |
|---|---|
| **Objetivo** | Provar o acesso ao painel (ADR-037) e o shell como dado (ADR-036) em navegador real. |
| **Referências** | ADR-021, ADR-025, ADR-036, ADR-037; `wiki/plan/12-admin-cms-editor.md` |

## Pré-condições

- `php artisan db:seed` (usuário do painel: `admin@concordia.inf.br` / `Concordia` — semente de demonstração).
- Domínio próprio do CMS: `cms.localhost` (o host isola cookie/sessão do portal).

## Jornada

1. **Visitante** acessa `/` → é conduzido a `/login`, sem qualquer navegação do painel exposta
   (regiões já vêm desligadas na tela de acesso) e sem violações axe.
2. **Credencial inválida** → permanece no login, com erro **anunciado** (`role="alert"`, mensagem
   genérica — não revela se o e-mail existe).
3. **Credencial válida** → painel com as regiões do shell: atributos `data-cms`/`data-cms-sidebar`,
   sidebar visível **antes** do conteúdo no DOM (ordem de foco = ordem visual), alvos ≥ 24px e axe sem
   violações WCAG 2.2 A/AA.
4. **Sair** → sessão encerrada (`POST /logout` com CSRF) e `/` volta a exigir login.
5. **Sem JavaScript** → o login (formulário nativo) e o painel continuam funcionando (ADR-010).

## Invariantes verificados

- Locale/idioma: `lang="pt-BR"` no documento.
- Shell: `header`/`sidebar`/conteúdo presentes; posição declarada em atributo (o CSS decide a coluna).
- Acessibilidade: axe (árbitro de contraste) + alvos mínimos + erro anunciado.
- Navegação rápida: abre **sem JS** (Popover nativo) e a lista continua clicável; o filtro é
  enhancement e **ignora acento** (`noticias` acha *Notícias* e `notícias` também) — o índice vem
  normalizado do servidor e o termo digitado passa pela mesma regra no cliente.

## Fora de escopo

- Auditoria (`core.login`/`core.logout`/`core.login_failed`) e freio de força bruta (429) são provados
  por `CmsAuthTest` (PHPUnit) — determinístico e sem depender de relógio.
