# 31 — Composição da home: reordenar, ocultar e publicar

**Fase:** P5.S2.1/S2.2/S6.1 · **Área:** CMS (domínio do painel) + portal · **Spec:** `tests/31-cms-home-composicao.spec.ts`

## História

A pessoa responsável pela comunicação monta a home no **Editor da home**: adiciona o `hero` e
seções de texto, **reordena por teclado**, **oculta** uma seção (que continua na lista, na mesma
posição), publica e confere o portal. No celular, o mesmo fluxo é feito **com o dedo** — o
formulário longo e o `<dialog>` nativo não podem sobrepor nem interceptar os controles.

## Critérios de aceite

1. A lista do editor é o documento: depois de adicionar `hero`, “Alfa”, “Beta” e “Gama”, a ordem
   exibida é exatamente a ordem publicada.
2. **Teclado:** focar “Subir” na última seção e pressionar `Enter` reordena o documento
   (`[Alfa, Gama, Beta]`) — o mesmo submit dos botões, sem arrastar (WCAG 2.2 SC 2.5.7).
3. **Ocultar** remove a seção do portal **sem** apagar a posição: a lista continua
   `[Alfa, Gama, Beta]`, a seção mostra o selo “Oculta” e a home publicada mostra só
   `[Alfa, Beta]`.
4. **Mostrar** devolve a seção na **mesma** posição; publicar de novo faz o portal exibir
   `[Alfa, Gama, Beta]`.
5. O documento publicado tem **exatamente um** `<h1>` (o `hero`) e headings em ordem; o portal e o
   editor passam no axe A/AA em desktop.
6. No viewport `Pixel 7` (390×844), editar a seção (abrir/fechar o diálogo), salvar, mover e ocultar
   funcionam por **clique real** (`.click()` só conclui quando o alvo está estável e não
   interceptado) — a suspeita de sobreposição registrada na S3.1; a tela passa no axe.
7. O estado final da home é válido e publicado (o teste seguinte do lote global não herda um
   documento vazio).

## Dados e isolamento

- O spec cria os próprios dados com marcador único (timestamp) e limpa o rascunho antes de compor.
- Publicar a home muda **estado global**: roda no projeto `cms-serial` (um worker, antes dos
  demais via `dependencies`), como as histórias 18/23/26. O viewport móvel é emulado no mesmo
  arquivo (`test.use({ ...devices['Pixel 7'] })`), sem um segundo projeto concorrente mutando o
  mesmo rascunho (`lock_version`).

## Fora de escopo

- Documento com tipo desconhecido, `props` inválida ou `version` errada **não tem caminho de
  escrita pela UI** (schema fechado): a degradação para o default é provada no teste integrado
  `HomeModuleTest::an_invalid_stored_document_falls_back_to_the_default_home` (HTTP real, banco com
  documento inválido), não no navegador.
- Editor rico (TipTap) das seções e seletor de mídia: fatias próprias (ADR-028/026).
