diff --git a/docs/plans/atualizacoes-mobile-sheet-criacao-usavel-impl.md b/docs/plans/atualizacoes-mobile-sheet-criacao-usavel-impl.md
new file mode 100644
index 00000000..e90caa30
--- /dev/null
+++ b/docs/plans/atualizacoes-mobile-sheet-criacao-usavel-impl.md
@@ -0,0 +1,100 @@
+# Impl: Atualizações mobile — sheet de criação usável (altura auto até o topo, form sem labels com divisórias, placeholders, polaridade em toggle, checks à direita)
+
+Status: aprovado
+Atualizado em: 2026-08-09
+Issue: #519
+Intenção: docs/plans/atualizacoes-mobile-sheet-criacao-usavel.md
+Appetite restante: herdado (~0,5–1 dia eng)
+
+## Leitura da intenção
+
+- **Outcome:** no celular, o sheet de criação do feed abre com altura = conteúdo (teto no topo da tela; rola por dentro só quando estoura), sem título visível, form estilo lista sem labels/bordas com divisórias full-bleed, placeholders descritivos, polaridade em toggle Ruim|Neutra|Boa e checks à direita com linha inteira tocável — registrar sem lutar com o sheet.
+- **O que NÃO negociar:** dados gravados inalterados (`body`, `polarity boa|neutra|ruim` default `neutra`, `urgent`, `adversarySignal`); anti-goal "não virar overlay de tela cheia nem segunda página"; desktop do feed mantém título/labels/descrições salvo o decidido no gate sobre campos compartilhados; acessibilidade mantida (labels acessíveis, erros anunciados, obrigatórios marcados).
+- **O que reavaliar:** a hipótese apontava possível mudança na primitiva `Drawer` — verificado: a primitiva já é auto-height (`--drawer-content-height:auto` + teto `--drawer-content-max-height`), o uso atual só impõe `max-h-[90dvh]`; a mudança cabe 100% no uso, sem tocar a primitiva. C103 não tem implementação em `main` (branch local = só o plano) — este item estabelece o padrão, C103 reutilizará.
+
+## Abordagem recomendada
+
+```mermaid
+flowchart LR
+ A[MunicipalityUpdateFields] -->|prop layout: 'labeled'\|'list'| B[Campos compartilhados]
+ B --> C[feed create modal]
+ B --> D[quick-edit lista B42]
+ C --> E[mobile: sheet auto até topo + form lista]
+ C --> F[desktop: dialog com labels]
+ D --> G[sheet: herda lista]
+ D --> H[popover: labels]
+```
+
+**Opções consideradas:** A | B | C
+**Recomendação:** A — variante de apresentação dentro do componente de campos compartilhados (`layout`), controle de polaridade vira `ToggleGroup` nas duas resoluções, altura do sheet ajustada por override scoped no uso (`max-h-dvh`), primitiva `Drawer` intocada.
+**Rejeitadas:** B) primitiva do Drawer ganha modo "topo" — blast radius em `CalendarFeedDialog` e demais superfícies sem volatilidade que justifique; C) componentes duplicados (fields do feed e fields da lista) — viola "edit the owner, don't twin".
+
+### Componentes / mudanças
+
+- **`MunicipalityUpdateFields`** (`src/components/campaign/municipality/MunicipalityUpdateFields.tsx`): ganha `layout?: 'labeled' | 'list'` (default `labeled` = hoje).
+ - Ambas os layouts: `NativeSelect` → `ToggleGroup` (`ToggleGroupItem` Ruim|Neutra|Boa, ordem pedida; `variant="outline"` + `spacing={0}` com `data-[state=on]:bg-primary data-[state=on]:text-primary-foreground` = destacado; precedente `VoteIntentionControl`); valor submetido via `` (mesmo nome/valores; select não submete button). Grupo com `aria-labelledby` apontando para o `FieldLabel` (visível no labeled, `sr-only` no list) → `getByLabel('Polaridade')` continua funcionando.
+ - `layout="list"`: container `flex flex-col divide-y divide-border` (full-bleed — sem padding horizontal no container; cada linha `px-4`); rows: texto (label sr-only; `Textarea` sem borda `border-0 bg-transparent rounded-none px-0`, placeholder `"Descrever o que aconteceu..."`, `required` mantido, `FieldError` mantido), polaridade (toggle w-full), Urgente e Sinalizar adversário (linhas `