# 30 — CMS: widgets reais por slot na coluna da página

**Fase:** P5.S5.2 · **Área:** CMS (domínio do painel) + portal · **Spec:** `tests/30-cms-widgets-slots.spec.ts`

## História

O operador abre **Layout por grupo de URL** no painel e vê o **catálogo real** de widgets que o
Core conhece, por espaço do shell (id, título, ícone, dono e se é embutível). Ele cria um perfil
para o grupo de URL das páginas e coloca ali widgets de **outros módulos** — últimas notícias, mais
lidas e últimos conjuntos de dados — referenciando apenas o `id`. O portal renderiza a coluna da
página com esses fragmentos, sem import entre módulos.

## Critérios de aceite

1. `/layout` lista o catálogo derivado de `WidgetRegistry::forSlot()` (nenhuma segunda lista), com
   os ids reais e o dono resolvido pelo manifesto (`dadosabertos` → `DadosAbertos`), sem violações
   A/AA (axe).
2. O perfil `paginas.portal.show` aceita `noticias.ultimas`, `noticias.mais-lidas` e
   `dadosabertos.ultimos` nos slots que cada fonte declara; salvar confirma e o formulário continua
   acessível.
3. A página publicada mostra os três widgets: cada um tem heading próprio (`<h2>`), lista semântica
   com itens, links com nome acessível e **exatamente um** `<h1>` na página.
4. Sem violações A/AA no portal: axe no viewport de desktop e, no **mesmo** spec, um contexto
   `Pixel 7` reabre a página pública (sem repetir login/escrita no painel) e repete o axe.
5. Ao final o perfil é **desativado** (a coluna lateral não vaza para as páginas de outras specs) e
   a página é arquivada.

## Dados próprios

Cada execução cria a própria página (slug com projeto + timestamp) e publica. O perfil usa um
escopo fixo e exclusivo (`paginas.portal.show`), criado ou atualizado pelo próprio spec; a página é
arquivada no fim (arquivar é terminal) e o perfil fica inativo.

## Fora de escopo (S6.x)

Publicar perfis reais com widgets na home, cache de payload por slot e o e2e de perfil por
`/cms/layout` com vários escopos simultâneos.
