# Impl: Escala/DRY: chrome comum dos passos finais do wizard (pós-B195)
Status: aprovado
Atualizado em: 2026-08-11
Issue: #619 (D11)
Intenção: docs/plans/escala-dry-pos-wizard-steps.md
Appetite restante: herdado (~0,5–1 dia eng) — não estoura
## Leitura da intenção
- **Outcome:** os 4 passos finais do wizard de `/campanha/acoes` param de duplicar (a) submit bar + pendência e (b) campos do cadastro de demanda, sem mudar comportamento, copy, toast/push/retorno ou a11y pinada por e2e.
- **O que NÃO negociar:** copy intocada (`Salvando…`, sr-only de cada passo, labels de CTA, `WIZARD_*`/`CAMPAIGN_DEMAND_*` continuam onde estão e com os mesmos valores); e2e de foco/a11y verdes (`contentFocus`, aria-live, label do botão); não renomear arquivos de steps (histórico de PRs); não unificar os corpos dos steps; nada de migration/schema.
- **O que reavaliar (hipóteses da intenção):**
1. `WizardStepFormChrome` como "form + pending chrome + submit bar" — o 4º step (`WizardExpectedVotesStep`) **não é form**: usa `useTransition` + `fetch` + CTA `type="button"`, sem `useActionState`. Forçá-lo a form mudaria comportamento (Enter passaria a salvar). A extração precisa de dois modos, não de um form só.
2. "Campos de demanda parametrizado por prefixo de id + `showMunicipality`" — a diferença entre os dois cadastros é maior que prefixo: município fixo (hidden input + search já vinculado) vs selecionável (gating do combobox, placeholder locked, reset de atividade, copy condicional, grid 2 colunas).
## Abordagem recomendada
```mermaid
flowchart LR
A[WizardStepFormChrome
shared/] --> B[WizardRegisterDemandStep]
A --> C[WizardUpdateBodyStep]
A --> D[WizardTrendNoteStep]
A --> E[WizardExpectedVotesStep]
F[DemandFields
demand/] --> B
F --> G[DemandForm /demandas/nova]
```
**`WizardStepFormChrome`** — dono do chrome de passo final: wrapper (`