diff --git a/docs/plans/espacamento-strip-acoes-inicio-v2.md b/docs/plans/espacamento-strip-acoes-inicio-v2.md
new file mode 100644
index 00000000..4c04787f
--- /dev/null
+++ b/docs/plans/espacamento-strip-acoes-inicio-v2.md
@@ -0,0 +1,86 @@
+# Apertar mais o espaçamento da strip de ações do Início
+
+Status: rascunho
+Atualizado em: 2026-07-30
+Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B — **B74**; chassis UX-1 / pós-B72)
+Impeccable: B — uma linha de layout em `CampaignHomeActionStrip`
+Appetite: ~0,25d eng; token Tailwind; sem migration
+Responsável: —
+
+## Design (Impeccable)
+
+Âncoras: `PRODUCT.md` / `DESIGN.md` · tema `campaign`.
+
+Na implementação: craft compacto → critique → polish (6 ícones staff no iPhone estreito + pan B67 ✓; labels de duas linhas em `w-[4.75rem]`).
+
+Brief compacto:
+
+- **Persona:** assessor/CG na faixa horizontal do Início.
+- **Job principal:** caber mais ações por viewport sem colisão de rótulo.
+- **Estratégia de cor:** inalterada.
+- **Edit where you see:** não.
+- **Anti-goals:** encolher o círculo abaixo de 44 px; mexer no pan (B67); reabrir labels do B58.
+
+## Dados → decisão → apresentação
+
+Dados: N/A — atalhos, sem métricas.
+
+## Contexto
+
+**B72 ✓** baixou `gap-6` → `gap-4` em `CampaignHomeActionStrip` (`
`). Feedback de produto (2026-07-30): ainda **grande demais** — a strip continua esparça no mobile.
+
+B72 havia listado `gap-3` como opção A e escolhido `gap-4` por cautela com labels de duas linhas; o campo agora pede o próximo degrau.
+
+## Objetivos
+
+- Reduzir o `gap` horizontal da lista (recomendação: `gap-4` → **`gap-3`**; critique pode ir a `gap-2` se ainda parecer largo e os rótulos não colidirem).
+- Manter: `snap-x`, pan touch + drag fine (B67), scrollbar oculta, `w-[4.75rem]` / círculo 48 px (B58).
+- Sem migration, collection, server action ou mudança de catálogo.
+
+## Decisões travadas
+
+- **Só `gap`, não largura do botão.** **Rejeitado:** `w` menor ou círculo <44 px (SC 2.5.5 / B72).
+- **Um valor único em coarse e fine.** **Rejeitado:** `gap-2 md:gap-4` (inconsistência sem evidência).
+- **Item novo (B74), não reabrir B72 entregue.** O as-built de B72 fica histórico; este é o ajuste fino pedido após uso. **Rejeitado:** editar só o plano B72 sem ID (some do grafo UX-1).
+
+## Questões em aberto
+
+- **`gap-3` ou `gap-2`?** **Opções:** A `gap-3` (12 px) | B `gap-2` (8 px). **Recomendação:** **A** no craft; critique sobe para B se o viewport de 6 ações staff ainda exigir pan excessivo e o truncamento de label continuar legível. _(assumido — validar no craft)_
+
+## Abordagem proposta
+
+```mermaid
+flowchart LR
+ Strip["CampaignHomeActionStrip
ul gap-3"]
+ Btn["CampaignHomeActionButton × N"]
+ Strip --> Btn
+```
+
+Componentes:
+
+- **`src/components/campaign/dashboard/CampaignHomeActionStrip.tsx`**: `gap-4` → `gap-3` (ou `gap-2` pós-critique).
+- **Migration:** Sem migration.
+
+## Dependências
+
+- Dura: **B72 ✓** (ponto de partida). Soft: B67 ✓ (pan continua após o aperto).
+
+## Não escopo
+
+- Chrome do wizard mobile → **B75**. Remoção da bottom nav → **B73**. Rótulos/animação → B58 ✓.
+
+## Rabbit holes
+
+- **Comprimir o botão “porque o gap sozinho não basta”.** Mitigação: só gap neste item; se ainda faltar viewport, novo pedido de produto (não misturar).
+
+## Adiado com gatilho
+
+Nenhum neste item.
+
+## Referências
+
+- `src/components/campaign/dashboard/CampaignHomeActionStrip.tsx`
+- [espacamento-strip-acoes-inicio.md](espacamento-strip-acoes-inicio.md) (B72 ✓)
+- [restaurar-pan-strip-acoes-inicio.md](restaurar-pan-strip-acoes-inicio.md) (B67 ✓)
+
+Qualidade de decisão: 5/5
diff --git a/docs/plans/header-mobile-wizard-campanha.md b/docs/plans/header-mobile-wizard-campanha.md
new file mode 100644
index 00000000..d5b4eff7
--- /dev/null
+++ b/docs/plans/header-mobile-wizard-campanha.md
@@ -0,0 +1,135 @@
+# Header mobile do wizard (chrome no Mandate Red)
+
+Status: rascunho
+Atualizado em: 2026-07-30
+Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B — **B75**; chassis UX-1 / emenda a B59)
+Impeccable: C — chrome novo no shell `(app)` durante `/campanha/acoes/*`; brief abaixo
+Appetite: ~1–1,25d eng; provider + header condicional + shell sem chrome duplicado no mobile; sem migration
+Responsável: —
+
+## Design (Impeccable)
+
+Âncoras: `PRODUCT.md` (Clarity under pressure; Feel the action) / `DESIGN.md` (Mandate Red mobile top bar) · tema `data-theme='campaign'`.
+
+Na implementação (`implement-roadmap-item`): shape → craft → critique → polish.
+
+Brief compacto:
+
+- **Persona / contexto:** CG/assessor no celular entre Zaps; entrou numa ação do Início; o header vermelho do app (sidebar + “Jorge Solla”) **compete** com Voltar + título do passo que hoje moram no conteúdo (`CampaignWizardShell`).
+- **Job principal:** durante o wizard, o header Mandate Red vira **navegação do fluxo** (sair / voltar / pular encadeado + título da ação + município), sem segundo sticky no scroll.
+- **Estratégia de cor:** Restrained — **mesmo** `bg-primary` / `text-primary-foreground` do header mobile atual; ícones/links herdam contraste do header (não inventar barra branca no topo).
+- **Edit where you see:** não — chrome de fluxo.
+- **Anti-goals:** dois headers sticky (app + shell); sidebar acessível no meio do ritual; X e “Pular” ambíguos; desktop ganhando chrome vermelho; Sheet full-screen no lugar de rota (B59).
+
+## Dados → decisão → apresentação
+
+Dados: N/A — chrome; conteúdo numérico nas etapas B60–B64 / B70.
+
+## Contexto
+
+**B59 ✓** entregou `CampaignWizardShell` com:
+
+- sticky **branco** no topo do conteúdo: Voltar (`md:hidden`) | caption município | `trailingAction`;
+- `h1` = pergunta do passo no ``.
+
+O layout `(app)` **sempre** renderiza acima disso o header vermelho mobile (`SidebarTrigger` + “Jorge Solla” / “Campanha · Bahia”) em [`layout.tsx`](../../src/app/(campaign)/campanha/(app)/layout.tsx). Em `/campanha/acoes/` o usuário vê **dois** chrome empilhados — o vermelho é irrelevante ao ritual e come viewport.
+
+Pedido de produto (2026-07-30):
+
+| Estado | Esquerda | Centro (título / subtítulo) | Direita |
+| ------ | -------- | --------------------------- | ------- |
+| 1ª etapa do fluxo | — | **fluxo** (ex. “Ajustar votos”); subtítulo município **só depois** de escolhido | **X** (sair do wizard → Início / origem) |
+| 2ª+ etapa | **Voltar** | fluxo + município (se houver) | **X** |
+| Fluxo **encadeado** (ex. sinal depois de votos no A1) | Voltar (se não for 1ª do subfluxo) | título do **subfluxo** atual | **“Pular <fluxo>”** no lugar do X |
+
+A pergunta do passo (“Em qual município?”, grid de tipos…) permanece no **conteúdo** (`h1`), não no header.
+
+Skip de B63/B64/B70 (“Pular registro de sinal…”) **migra** para este slot direito no mobile quando a origem for encadeada; no entry standalone o direito é X.
+
+## Objetivos
+
+- Em viewport **< `md`**, rotas `/campanha/acoes/*`: substituir o header app (sidebar + marca) por **header de wizard** Mandate Red com a tabela acima.
+- Em **`md+`**: header slim atual (só `SidebarTrigger`) **inalterado**; shell pode manter caption de município discreta **ou** só no conteúdo — sem Voltar duplicado (browser). Recomendação: no desktop, sem barra vermelha de wizard; `h1` + caption opcional no conteúdo como hoje.
+- Remover do `CampaignWizardShell` o sticky branco de Voltar/município/`trailingAction` **no mobile** (evita chrome duplo); no desktop, `trailingAction` de skip pode ficar no conteúdo até o wiring A1 — ou sumir se só mobile importa (recomendação: skip só no header mobile; desktop = link textual no conteúdo se B63+ precisar).
+- Provider/contrato tipado para o shell **publicar** chrome (`flowTitle`, `municipalityLabel?`, `stepKind: 'entry' | 'continue'`, `previousHref?`, `dismissHref`, `skip?: { label, href }`).
+- a11y: X com nome “Fechar” / “Sair da ação”; Voltar com verbo visível; “Pular …” contém o nome do fluxo; foco no `h1` do passo preservado (B59).
+- Guardrails: sem migration / Consent / action de escrita; print:hidden; staff gate de `acoes/layout` intacto.
+
+## Decisões travadas
+
+- **Arquitetura: chrome condicional no layout `(app)` + context publicado pelo shell (não um segundo header solto, não portal ad-hoc).** Extrair o header mobile atual para um componente client (`CampaignMobileTopBar`) que, se houver chrome de wizard ativo, renderiza o modo wizard; senão o modo app. `CampaignWizardChromeProvider` envolve só `acoes/layout.tsx` (ou o `(app)` inteiro com default `null`). O shell **registra** o chrome via `useCampaignWizardChromeSet` / efeito; cleanup no unmount. **Rejeitado:** A) layout route group paralelo `(wizard)` fora de `(app)` (duplica auth/sidebar/Toaster/PWA; caro de manter); B) portal `createPortal` no `document` sem contrato (frágil com RSC/scroll); C) só CSS `hidden` no header app sem substituir (some a affordance de sair); D) Sheet full-screen (B59 já rejeitou).
+- **Título do header = nome da ação/fluxo (catálogo B45), não a pergunta do passo.** Fonte: produto 2026-07-30. **Rejeitado:** repetir `stepTitle` no header (some hierarquia; B59 já separou pergunta × contexto).
+- **Subtítulo = município só após escolha (B60).** Ausente na 1ª etapa de busca. **Rejeitado:** slug cru; “Município” genérico.
+- **1ª etapa: só X à direita (sem Voltar).** X → `dismissHref` (default Início). **Rejeitado:** Voltar na 1ª (= mesmo que X, confunde); hamburger + X.
+- **2ª+: Voltar à esquerda + X à direita.** Voltar = `previousHref` (passo anterior). **Rejeitado:** só gesture edge; esconder X após a 1ª (usuário precisa abortar no meio).
+- **Encadeado: X vira “Pular <fluxo>”.** Quando `skip` está definido, o slot direito é o skip (não X+Pular). Fonte: produto 2026-07-30 + planos B63/B64/B70. **Rejeitado:** X e Pular juntos (dois escapes); Pular no conteúdo e X no header (split mental).
+- **Sidebar inacessível durante o wizard mobile** (trigger some com o chrome app). Sair = X ou concluir. **Rejeitado:** manter SidebarTrigger no canto (reabre domínio-primeiro no meio do ritual — alinhado a B73).
+- **i18n:** ids `CampaignWizardChrome`, `flowTitle`, `dismissHref`, `skipLabel`; copy pt-BR (“Pular registro de sinal”, nomes do catálogo).
+
+## Questões em aberto
+
+- **Desktop: caption município no conteúdo ou só no header inexistente?** **Opções:** A caption muted acima do `h1` no `md+` | B só contexto na URL/query. **Recomendação:** **A** — paridade com B59 desktop; header vermelho wizard é mobile-only. _(assumido)_
+- **`stepKind` derivado de `previousHref` vs prop explícito?** **Opções:** A prop `isEntryStep` | B `previousHref == null` ⇒ entry. **Recomendação:** **A** — Voltar e dismiss não são o mesmo href na 1ª (dismiss=Início; não há previous); entry ≠ “sem previous”. _(assumido)_
+
+## Abordagem proposta
+
+```mermaid
+flowchart TB
+ AppLayout["(app)/layout.tsx"] --> TopBar["CampaignMobileTopBar"]
+ TopBar -->|chrome null| AppMode["SidebarTrigger + marca"]
+ TopBar -->|chrome set| WizMode["Voltar? + títulos + X|Pular"]
+ AcoesLayout["acoes/layout Provider"] --> Shell["CampaignWizardShell"]
+ Shell -->|setChrome| Ctx["CampaignWizardChromeContext"]
+ Ctx --> TopBar
+ Shell --> Main["h1 stepTitle + children"]
+```
+
+Componentes:
+
+- **`CampaignWizardChromeContext`** (`src/components/campaign/shell/` ou `shared/`): tipo `CampaignWizardChromeState | null`; provider; `useSetCampaignWizardChrome(state)` com sync em `useEffect` + clear on unmount (evitar chrome órfão na navegação Início←ações).
+- **`CampaignMobileTopBar`**: client; lê context; modo app vs wizard; tokens `bg-primary` / foreground; `min-h-14`; safe-area top; `print:hidden`; `md:hidden` no modo app **e** no modo wizard (desktop inalterado).
+- **`(app)/layout.tsx`**: trocar o `` inline por `` (provider precisa ancestrar o top bar — **subir** o provider para `(app)/layout` com default `null`, ou nestar top bar dentro de um client shell que também envolve `children`). Preferência: **client island `CampaignAppChrome`** wrapping header+children slot pattern só o necessário; evitar marcar o layout RSC inteiro como client.
+ - Padrão prático: `SidebarInset` recebe `` no `(app)/layout` (provider leve) + `CampaignMobileTopBar` + `{children}` — provider no layout RSC via componente client que só passa children.
+- **`acoes/layout.tsx`**: sem mudança de gate; opcional `data-wizard-route` se útil a testes.
+- **`CampaignWizardShell`**: props novas `flowTitle`, `isEntryStep`, `dismissHref`, `skip?: { label, href }`; no mobile **não** renderiza sticky branco; chama setChrome; `h1` + children permanecem; `md+` pode mostrar caption município se `municipalityLabel`.
+- **Copy de fluxo:** reusar labels de `campaignHomeActions.ts` (ex. “Ajustar votos”) via mapa `slug → flowTitle` em `campaignWizardCopy.ts` ou `campaignActionRoutes.ts` — uma fonte, não string solta por página.
+- **Testes:** unit do top bar (entry / continue / skip); atualizar `campaignWizardShell.unit.spec.tsx` (back some do shell no mobile — testar via context ou `data-slot` no top bar); e2e smoke: abrir ação → header sem sidebar → X volta Início; 2ª etapa → Voltar.
+- **Migration:** Sem migration, sem collection, sem server action.
+
+## Dependências
+
+- Dura: **B59 ✓** (shell + rotas `/campanha/acoes`). Soft: **B60 ✓** (município no subtítulo); **B45 ✓** (labels de fluxo); planos B63/B64/B70 (passam a alimentar `skip` no header em vez de `trailingAction` no sticky branco). Soft **B73** (remove bottom nav — não bloqueia).
+- Desbloqueia polish mobile dos wizards B61/B63/B64/B70 (sem este item, cada um herda chrome quebrado).
+
+## Não escopo
+
+- Orquestração completa A1 “Quer também…?” (wiring de cadeia) — este item só **hospeda** o chrome quando a cadeia existir; a máquina de passos continua nos planos A1/B63+.
+- Remoção da bottom nav → **B73**. Gap da strip → **B74**.
+- Redesign do header desktop slim.
+- Persistência de rascunho (Adiado B59).
+
+## Rabbit holes
+
+- **Route group `(wizard)` fora de `(app)`.** Explode auth/PWA/sidebar. **Mitigação:** context no inset.
+- **State machine global de wizard.** **Mitigação:** chrome burro; hrefs por etapa.
+- **Animar troca app↔wizard header.** **Mitigação:** swap imediato; motion só se critique pedir e com `prefers-reduced-motion`.
+
+## Adiado com gatilho
+
+- **Skip no desktop no mesmo visual do header.** Revisitar se B63+ shippar e a mesa reclamar que “Pular” sumiu no notebook (hoje browser + conteúdo bastam).
+- **Deep-link “voltar ao Zap” com dismiss ≠ Início.** Revisitar se entry points fora do Início (E11 → wizard) pedirem `dismissHref` dinâmico — o prop já existe; falta produto.
+
+## Referências
+
+- `src/app/(campaign)/campanha/(app)/layout.tsx` — header vermelho mobile
+- `src/components/campaign/shared/CampaignWizardShell.tsx` — sticky atual a retirar no mobile
+- `src/app/(campaign)/campanha/(app)/acoes/layout.tsx` — gate staff
+- `src/lib/campaignHomeActions.ts` — labels de fluxo
+- `src/lib/campaignWizardCopy.ts` / `campaignActionRoutes.ts`
+- [chassis-wizard-campanha.md](chassis-wizard-campanha.md) (B59 ✓) — emenda chrome mobile
+- [wizard-registro-sinal.md](wizard-registro-sinal.md) / [wizard-mudar-tendencia.md](wizard-mudar-tendencia.md) / [wizard-atualizar-lideranca.md](wizard-atualizar-lideranca.md) — skip encadeado
+- [fluxos-acao-primeiro-inicio.md](fluxos-acao-primeiro-inicio.md)
+- `PRODUCT.md` / `DESIGN.md` — Mandate Red / Field Desk
+- AGENTS.md — naming; sem Consent novo
+
+Qualidade de decisão: 4/5
diff --git a/docs/plans/remover-bottom-nav-mobile.md b/docs/plans/remover-bottom-nav-mobile.md
new file mode 100644
index 00000000..82d47c48
--- /dev/null
+++ b/docs/plans/remover-bottom-nav-mobile.md
@@ -0,0 +1,119 @@
+# Remover bottom navigation bar no mobile
+
+Status: rascunho
+Atualizado em: 2026-07-29
+Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B — **B73**; chassis UX-1)
+Impeccable: B — encaixe no shell `(app)`; remove chrome, não cria rota nova
+Appetite: ~0,25–0,5d eng; remover componente + ajustar padding do scroll + atualizar testes; sem migration
+Responsável: —
+
+## Design (Impeccable)
+
+Âncoras: `PRODUCT.md` (register `product` — clareza sob pressão; UX-1 ação-primeiro) / `DESIGN.md` (hybrid mobile top bar Mandate Red + sidebar Sheet) · tema `data-theme='campaign'`.
+
+Na implementação (`implement-roadmap-item`): craft compacto → critique → polish (só chrome do shell).
+
+Brief compacto:
+
+- **Persona / contexto:** CG/assessor no celular — o ritual diário passa pelo Início (ações + busca); listas densas são visita ocasional, não navegação por domínio.
+- **Job principal:** recuperar altura útil do viewport e deixar um único caminho de navegação secundária (sidebar via `SidebarTrigger` no header vermelho).
+- **Estratégia de cor:** Restrained — remove barra fixa; header mobile existente permanece.
+- **Edit where you see:** não — só chrome.
+- **Anti-goals:** segunda barra de atalhos; reinventar drawer fora do `Sidebar`; mover destinos para tabs no Início; exigir sidebar aberta por padrão no mobile.
+
+## Dados → decisão → apresentação
+
+Dados: N/A — remoção de chrome de navegação; nenhuma métrica/série/mapa.
+
+## Contexto
+
+O shell de `/campanha` monta hoje **duas** superfícies de navegação no mobile (<`md`):
+
+1. **Header vermelho** com `SidebarTrigger` → `CampaignSidebar` em Sheet (`collapsible="offcanvas"` no `CampaignSidebar`, B38 ✓).
+2. **`CampaignBottomNav`** fixa (`src/components/campaign/shell/CampaignBottomNav.tsx`) com até 5 destinos derivados de `getCampaignBottomNav` em `nav.ts` — subconjunto de `staffNav`/`leaderNav` (exclui Quadro, Territórios, Apoiadores, Assessores).
+
+O scroll global reserva espaço com `pb-24` em `src/app/(campaign)/campanha/(app)/layout.tsx` para não cobrir conteúdo com a bottom bar. O chassis UX-1 (**B43–B47 ✓**, **B65 ✓**) ancorou busca + strip de ações **acima** dessa barra.
+
+**Decisão de produto (2026-07-29):** o paradigma deixou de ser “navegar por domínio” (Início / Municípios / Lideranças / … na barra inferior) e passou a ser **intenção** (ações do Início, busca, wizards). A bottom bar só consome ~48–56 px + safe-area sem servir ao ritual diário. A navegação ocasional para listas de alto volume permanece no **sidebar** (fechado por padrão no mobile via `CampaignSidebarViewportDefault` quando não há cookie `sidebar_state`).
+
+Evidência alinhada: [fluxos-acao-primeiro-inicio.md](fluxos-acao-primeiro-inicio.md) — anti-goal “depender de sidebar para o ritual diário”; a barra inferior era o espelho mobile do modelo domínio-primeiro.
+
+## Objetivos
+
+- Em viewport **< `md`**: **não renderizar** `CampaignBottomNav`; navegação secundária só via `SidebarTrigger` + Sheet.
+- Remover o padding inferior artificial (`pb-24`) do `campaign-content-scroll` no mobile — substituir por padding normal (`p-4` / `pb-4` ou equivalente) com safe-area só onde necessário (toasts/PWA, não nav fantasma).
+- Revalidar o dock do Início (**B65 ✓**): com a barra sumida, o grupo strip+busca pode usar o limite inferior real do scrollport; medir se o spacer `flex-1` ainda precisa de ajuste.
+- Sidebar mobile continua **fechada por padrão** (`CampaignSidebarViewportDefault` + cookie) — sem mudar o default tablet/desktop (B38 ✓).
+- Apagar código morto: `CampaignBottomNav.tsx`, `getCampaignBottomNav`, exports órfãos; `pnpm exec knip` limpo.
+- Guardrails: sem migration, sem collection, sem Consent, sem server action; `print:hidden` preservado; leader/staff `getCampaignNav` intactos.
+
+## Decisões travadas
+
+- **Remover a bottom bar por completo — não esvaziar nem reduzir ícones.** O produto não quer atalhos de domínio no mobile; busca + ações cobrem o caminho frequente. **Rejeitado:** manter 2–3 ícones (ainda compete com thumb zone); mover Municípios/Lideranças para tabs no Início (segundo sistema de nav); PWA shortcut bar nativa (fora de escopo).
+- **Sidebar como única navegação estrutural no mobile.** O `SidebarTrigger` no header vermelho já existe; não adicionar segundo gatilho flutuante. **Rejeitado:** FAB “Menu”; gesto edge-only sem affordance; abrir sidebar por padrão no mobile (contradiz B38 + campo com uma mão).
+- **Apagar `getCampaignBottomNav` com o componente.** Não deixar helper “para o dia em que redesenharmos a barra” — git history é o arquivo. Testes que citavam a barra passam a assertar só `getCampaignNav` + `getCampaignSecondaryNav`. **Rejeitado:** deprecar com `@deprecated` (knip/CI bloqueia export morto).
+- **Ajustar `pb-24` no mesmo PR.** O padding existia só pela altura da barra; mantê-lo após remoção devolve gap morto e contradiz B65. **Rejeitado:** `pb-24` “por segurança” sem medir (o dock do Início pode precisar de `pb` menor local, não global).
+- **i18n e naming** seguem o AGENTS.md: identificadores em inglês (`CampaignBottomNav` deletado; layout classes em inglês); copy visível em pt-BR no sidebar (`aria-label` do trigger já existe).
+
+## Questões em aberto
+
+- **Reduzir `pb` global ou só revalidar o Início?** **Opções:** A) trocar `pb-24` → `pb-4` no scroll global | B) manter `pb-24` nas outras rotas e só no Início usar dock | C) `pb` proporcional a safe-area apenas. **Recomendação:** **A** no layout global — a barra era a única razão do 24; listas longas ganham área útil; se alguma rota com FAB/toast colidir, corrigir pontualmente. _(assumido — validar no craft com device real)_
+
+## Abordagem proposta
+
+```mermaid
+flowchart TD
+ layout["(app)/layout.tsx"] --> scroll["campaign-content-scroll"]
+ layout --> header["header mobile + SidebarTrigger"]
+ layout --> sidebar["CampaignSidebar Sheet"]
+ layout -.remove.-> bottom["CampaignBottomNav DELETED"]
+ scroll --> pages["rotas /campanha/*"]
+ home["Início B65 dock"] --> scroll
+```
+
+Componentes:
+
+- **`src/app/(campaign)/campanha/(app)/layout.tsx`**: remover import/render de `CampaignBottomNav`; ajustar `className` do scroll (`pb-24` → `pb-4` ou `p-4` simétrico no mobile); confirmar que `SidebarTrigger` no header mobile permanece.
+- **Deletar `src/components/campaign/shell/CampaignBottomNav.tsx`**.
+- **`src/components/campaign/shell/nav.ts`**: remover `getCampaignBottomNav` e o comentário do cap de 5 itens; manter `getCampaignNav` / `getCampaignSecondaryNav` / `MUNICIPALITY_NAV_HREF`.
+- **`src/components/campaign/shell/CampaignSidebarViewportDefault.tsx`**: sem mudança de comportamento (já fecha sidebar <1024 sem cookie) — só verificar que mobile continua com default fechado.
+- **Início (`CampaignHomeLayout` / `CampaignHomeStaffChrome`)**: smoke visual após remoção da barra — o dock pode colar mais baixo; ajustar spacer se sobrar gap >~8 px (herança do B65).
+- **`tests/unit/campaignIntelligenceConcepts.unit.spec.ts`**: teste “stays out of … mobile bottom bar” → assertar que `CAMPAIGN_CONCEPTS_PATH` não está em `getCampaignNav` (bottom bar deixa de existir).
+- **E2E smoke**: navegar via sidebar no mobile viewport — abrir Sheet, ir a Municípios, voltar (nenhum `nav[aria-label="Navegação principal"]` no DOM).
+- **Sem migration, sem collection, sem server action.**
+
+## Dependências
+
+- **B43 ✓** (Início ação-primeiro) — decisão de paradigma; sem ela a barra ainda faria sentido como atalho de domínio.
+- **B65 ✓** (soft) — o dock foi desenhado acima da bottom nav; este item **revisita** o padding/âncora, não bloqueia o merge.
+- **B38 ✓** (soft) — sidebar Sheet + default fechado no mobile/tablet sem cookie.
+- Nenhuma dependência dura de item pendente.
+
+## Não escopo
+
+- Redesenhar itens do `staffNav` / reordenar sidebar — só remover a projeção mobile de 5 ícones.
+- Atalhos de domínio no Início (busca B48+ e ações B45 ✓ já cobrem).
+- Mudar bottom nav em design-refs HTML legados (`docs/design-refs/latest/*.html` com `pb-24` estático) — artefatos UX Pilot, não runtime.
+- PWA install banner / `InstallPwaToast` — inalterados.
+
+## Rabbit holes
+
+- **Reintroduzir navegação por gestos sem affordance.** Se alguém “só documentar” que o usuário deve arrastar: sem `SidebarTrigger` visível, a descoberta cai. **Mitigação:** manter trigger no header; e2e cobre o caminho.
+- **Padding inferior em cascata.** Copiar `pb-24` para o dock do Início “por precaução” recria o bug que este item remove. **Mitigação:** um único `pb` no scroll global; ajuste local só com medição.
+
+## Adiado com gatilho
+
+- **Atalho “recentes” na sidebar** (visitados) para compensar menos um toque na bottom bar. Revisitar quando: métrica de sessão mostrar >3 aberturas de sidebar só para repetir os mesmos 2 destinos — hoje busca + ações cobrem.
+
+## Referências
+
+- `docs/roadmap.md` (UX-1, B73)
+- `src/app/(campaign)/campanha/(app)/layout.tsx` — montagem do shell e `pb-24`
+- `src/components/campaign/shell/CampaignBottomNav.tsx` — alvo de remoção
+- `src/components/campaign/shell/nav.ts` — `getCampaignBottomNav`
+- `src/components/campaign/shell/CampaignSidebarViewportDefault.tsx` — default fechado mobile
+- `docs/plans/ancorar-busca-acoes-inicio-mobile.md` — decisões que citavam a bottom nav (contexto histórico B65)
+- `docs/plans/fluxos-acao-primeiro-inicio.md` — anti-goal sidebar no ritual diário
+- `docs/plans/sidebar-recolhido-tablet.md` — B38, mobile Sheet inalterado
+- `PRODUCT.md` — princípios 2 e 3 (clareza sob pressão; edit where you see)
+- AGENTS.md — Campaign auth shell; knip mata órfãos no mesmo PR
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 6497e0ce..607c084e 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -1,6 +1,6 @@
# Roadmap — Teqo
-Atualizado em: 2026-07-30 — ~~**B66**~~ ✓ busca no focus; ~~**B51**~~ ✓; ~~**B52**~~ ✓; ~~**B72**~~ ✓ gap strip ações; **B71** polish busca (bullets/título/hover full-bleed); **B69**–**B70** A4 liderança; ~~**B62**~~ ✓ simplificar sinal (E11 triage 1 por presença); ~~**B56**~~ ✓; ~~**B67**~~ ✓; ~~**B68**~~ ✓; ~~**B59**~~ ✓; ~~**B65**~~ ✓; ~~**B60**~~ ✓; ~~**B61**~~ ✓; ~~**B48**~~ ✓; ~~**B49**~~ ✓; ~~**B50**~~ ✓; B53–B55; wizards ~~B60~~ ✓/~~**B61**~~ ✓/B63–B64.
+Atualizado em: 2026-07-30 — **B74** gap strip v2; **B75** header mobile do wizard; **B73** remover bottom nav; ~~**B66**~~ ✓ busca no focus; ~~**B61**~~ ✓; ~~**B51**~~ ✓; ~~**B52**~~ ✓; ~~**B72**~~ ✓; **B71**; **B69**–**B70**; ~~**B62**~~ ✓; ~~**B56**~~ ✓; ~~**B67**~~ ✓; ~~**B68**~~ ✓; ~~**B59**~~ ✓; ~~**B65**~~ ✓; ~~**B60**~~ ✓; ~~**B48**~~ ✓; ~~**B49**~~ ✓; ~~**B50**~~ ✓; B53–B55; wizards ~~B60~~ ✓/~~**B61**~~ ✓/B63–B64.
Registro canônico dos **próximos** planos e débitos. Histórico de entregas: resumo abaixo + planos em [`docs/plans/`](plans/) + notebook [`.cursor/rules/projects/nucleos-eleitorais.mdc`](../.cursor/rules/projects/nucleos-eleitorais.mdc).
## Âncoras do calendário eleitoral 2026 (Res. TSE 23.760/2026)
@@ -83,7 +83,7 @@ O discovery literatura→persona→entrevista ([relatório aprovado](research/re
### Demais itens abertos
-- **UX-1 fluxos ação-primeiro (prioridade pós-sessão 29/07)** — evidência: [snapshot](plans/sessao-observada-coordenador-2026-07-29-snapshot.md) · O9–O11 em CUSTOMER.md · **rascunho:** [fluxos-acao-primeiro-inicio.md](plans/fluxos-acao-primeiro-inicio.md). Soft deadline: **03/08**. **Chassis Início:** ~~**B43**~~ ✓ → ~~**B44**~~ ✓ → ~~**B45**~~ ✓ → ~~**B46**~~ ✓ → ~~**B47**~~ ✓ → ~~**B58**~~ ✓ → ~~**B67**~~ ✓ (pan strip) → ~~**B65**~~ ✓ (âncora inferior mobile) → ~~**B66**~~ ✓ (focus limpa tela + animação) → ~~**B48**~~ ✓ → ~~**B49**~~ ✓ → ~~**B68**~~ ✓ → **B71** (polish resultados busca) · ~~**B72**~~ ✓ (gap strip) → ~~**B50**~~ ✓ → ~~**B51**~~ ✓ → ~~**B52**~~ ✓ → **B53–B55** · ~~**B56**~~ ✓ · **B57** futuro. **Wizards:** ~~**B59**~~ ✓ → ~~**B60**~~ ✓/**B61**/**B64** · ~~**B62**~~ ✓ → **B63** · **B69** → **B70** (A4 liderança).
+- **UX-1 fluxos ação-primeiro (prioridade pós-sessão 29/07)** — evidência: [snapshot](plans/sessao-observada-coordenador-2026-07-29-snapshot.md) · O9–O11 em CUSTOMER.md · **rascunho:** [fluxos-acao-primeiro-inicio.md](plans/fluxos-acao-primeiro-inicio.md). Soft deadline: **03/08**. **Chassis Início:** ~~**B43**~~ ✓ → ~~**B44**~~ ✓ → ~~**B45**~~ ✓ → ~~**B46**~~ ✓ → ~~**B47**~~ ✓ → ~~**B58**~~ ✓ → ~~**B67**~~ ✓ (pan strip) → ~~**B65**~~ ✓ (âncora inferior mobile) → ~~**B66**~~ ✓ (focus limpa tela + animação) → ~~**B48**~~ ✓ → ~~**B49**~~ ✓ → ~~**B68**~~ ✓ → **B71** (polish resultados busca) · ~~**B72**~~ ✓ (gap strip) → **B74** (gap strip v2) → **B73** (remover bottom nav mobile) → ~~**B50**~~ ✓ → ~~**B51**~~ ✓ → ~~**B52**~~ ✓ → **B53–B55** · ~~**B56**~~ ✓ · **B57** futuro. **Wizards:** ~~**B59**~~ ✓ → **B75** (header mobile wizard) → ~~**B60**~~ ✓/~~**B61**~~ ✓/**B64** · ~~**B62**~~ ✓ → **B63** · **B69** → **B70** (A4 liderança).
- ~~**B43** Início em branco + Quadro~~ — **entregue 2026-07-29** (`/campanha` blank; staff dashboard em `/campanha/quadro`; liderança em `/campanha/contatos`; nav Início+Quadro / Início+Meus contatos; `requireCampaignPageActor` manda leader bloqueado → `/campanha/contatos`; sem migration) · [plano](plans/inicio-em-branco-quadro.md)
- ~~**B44** Botão de ação do Início + lista horizontal~~ — **entregue 2026-07-29** (`CampaignHomeActionButton` + `CampaignHomeActionStrip`; Tooltip fine / long-press Drawer coarse; montado no Início por B45 ✓) · ~1d · Janela 1 · Impeccable C · [plano](plans/botao-acao-inicio-strip.md)
- ~~**B45** Catálogo de ações por persona~~ — **entregue 2026-07-29** (`src/lib/campaignHomeActions.ts` + `CampaignHomeActions`; staff 6 ações com `uncovered-municipalities` → `?coverage=sem_assessor&sort=votos`; leader 2 com `my-contacts` → `/campanha/contatos`; demais inertes; ilha client por limite RSC↔ícones Lucide) · [plano](plans/catalogo-acoes-inicio-por-persona.md)
@@ -105,6 +105,9 @@ O discovery literatura→persona→entrevista ([relatório aprovado](research/re
- ~~**B68** Sugestões na busca aberta (empty state por papel)~~ — **entregue 2026-07-29** (`POST /campanha/home-search` com `mode: 'suggest'`; `loadHomeSearchSuggestions` + `rankHomeSearchSuggestMunicipalities`; assessor = carteira fria; CG/candidato = `priority === 'alta'` por déficit central + frescor; `homeSearchUiFocused` + seção **Sugestões**; `resultKind`; sem migration) · [plano](plans/sugestoes-busca-vazia-inicio.md)
- **B71** Polimento visual dos resultados de busca (sem bullets no ``; título “Municípios” discreto sentence-case; hover full-bleed borda a borda) · Depende de B48 ✓ · ~0,25–0,5d · Janela 1 · Paralelizável com B51 · Impeccable B · [plano](plans/polimento-resultados-busca-inicio.md)
- **B72** ~~Reduzir espaçamento horizontal da strip de ações (`gap-6` → `gap-4`)~~ — **entregue 2026-07-29** (`CampaignHomeActionStrip` `` `gap-4`; botões `w-[4.75rem]` e pan B67 ✓ inalterados) · Depende de B58 ✓ / B67 ✓ (soft) · ~0,25d · Janela 1 · Impeccable B · [plano](plans/espacamento-strip-acoes-inicio.md)
+- **B73** Remover bottom navigation bar no mobile — paradigma UX-1 intenção-primeiro: apagar `CampaignBottomNav` + `getCampaignBottomNav`; sidebar Sheet (fechada por padrão, B38 ✓) como única nav estrutural; ajustar `pb-24` do scroll global; revalidar dock do Início (B65 ✓) · Depende de B43 ✓ · soft B65 ✓ / B38 ✓ · ~0,25–0,5d · Janela 1 · Paralelizável com B66 / B71 / B74 · Impeccable B · [plano](plans/remover-bottom-nav-mobile.md)
+- **B74** Apertar mais o espaçamento da strip de ações (`gap-4` → `gap-3`, critique pode `gap-2`) — pós-B72 ainda largo no mobile · Depende de B72 ✓ · soft B67 ✓ · ~0,25d · Janela 1 · Paralelizável com B73 / B66 / B71 · Impeccable B · [plano](plans/espacamento-strip-acoes-inicio-v2.md)
+- **B75** Header mobile do wizard — durante `/campanha/acoes/*`, o Mandate Red substitui sidebar+marca: título = fluxo (“Ajustar votos”), subtítulo = município; 1ª etapa só X; 2ª+ Voltar+X; encadeado X→“Pular <fluxo>”; context no `(app)` + shell sem sticky branco no mobile · Depende de B59 ✓ · soft B60 ✓ / B45 ✓ · ~1–1,25d · Janela 1 · Paralelizável com B61/B63/B64 (eles consomem o chrome) · Impeccable C · [plano](plans/header-mobile-wizard-campanha.md)
- ~~**B49** Busca — resultados Lideranças~~ — **entregue 2026-07-29** (`searchHomeLeaderships`, `HomeSearchLeadershipGroup`, `leaderships` no POST `/campanha/home-search`; word-start; assessor scoped; municípios no secundário; cap 25; sem WA — **B55**) · Depende de B47 ✓ · [plano](plans/busca-global-resultados-liderancas.md)
- ~~**B50** Busca — resultados Assessores (access B19)~~ — **entregue 2026-07-29** (`searchHomeAdvisors` + `HomeSearchAdvisorGroup`; unrestricted only; word-start no nome; contagem de municípios na linha; `POST /campanha/home-search` agrega `advisors`) · Depende de B47 ✓ · [plano](plans/busca-global-resultados-assessores.md)
- ~~**B51** Busca — resultados Atividades~~ — **entregue 2026-07-29** (`searchHomeActivities` + `HomeSearchActivityGroup`; word-start no título; access `activity`; rascunhos no escopo; secundário município + data; cap 25; `POST /campanha/home-search` agrega `activities`; sem WA — **B55**) · Depende de B47 ✓ · [plano](plans/busca-global-resultados-atividades.md)
@@ -222,12 +225,15 @@ flowchart TD
B67n["B67 ✓ Restaurar pan
strip ações"]
B46n["B46 ✓ Thumb zone
ações Início"]
B47n["B47 ✓ Busca global
input + modo focado"]
- B66n["B66 Focus limpa tela
+ animação busca"]
+ B66n["B66 ✓ Focus limpa tela
+ animação busca"]
B65n["B65 ✓ Âncora inferior
busca+ações mobile"]
B48n["B48 ✓ Busca
Municípios + TIs"]
B68n["B68 ✓ Sugestões busca
vazia por papel"]
B71n["B71 Polish resultados
busca Início"]
B72n["B72 ✓ Gap strip
ações Início"]
+ B73n["B73 Remover bottom
nav mobile"]
+ B74n["B74 Gap strip v2
ações Início"]
+ B75n["B75 Header mobile
wizard Mandate Red"]
B49n["B49 Busca Lideranças"]
B50n["B50 ✓ Busca Assessores"]
B51n["B51 Busca Atividades"]
@@ -239,7 +245,7 @@ flowchart TD
B57n["B57 Delta 7d estimativa
(futuro / baixa prio)"]
B59n["B59 Chassis wizard ✓
shell + município sticky"]
B60n["B60 Busca município
nos wizards"]
- B61n["B61 Ajuste votos
cenários + atalhos"]
+ B61n["B61 ✓ Ajuste votos
cenários + atalhos"]
B62n["B62 ✓ Simplificar
modelo de sinal"]
B63n["B63 Wizard sinal
tipo + texto"]
B64n["B64 Wizard tendência
escolha + justificativa"]
@@ -324,6 +330,19 @@ flowchart TD
B68n -.mesmo grupo/linha.-> B71n
B58n -.gap visual.-> B72n
B67n -.strip estável.-> B72n
+ B72n --> B74n
+ B67n -.pan após aperto.-> B74n
+ B43n -.intenção-primeiro.-> B73n
+ B65n -.pb-24 / dock.-> B73n
+ B38n -.sidebar Sheet.-> B73n
+ B72n -.chrome mobile.-> B73n
+ B59n --> B75n
+ B60n -.subtítulo município.-> B75n
+ B45n -.labels de fluxo.-> B75n
+ B75n -.chrome mobile.-> B61n
+ B75n -.chrome + skip.-> B63n
+ B75n -.chrome + skip.-> B64n
+ B75n -.chrome + skip.-> B70n
B47n --> B49n
B47n --> B50n
B47n --> B51n
@@ -454,11 +473,11 @@ flowchart TD
B8F2 -.rank por ZE = débito aberto.-> B14n
```
-Paralelizáveis agora: **B66** (focus limpa busca — após ~~B65~~ ✓); **B71** (polish resultados busca — após B48 ✓); **B59** (chassis wizard — desbloqueia B60/B61/B63/B64/B70); **B69** (simplificar liderança — paralelo a B59/B62; desbloqueia B70); **B49–B53** após B47 ✓ / B48 ✓ (depois B54/B55). Após **B59**: **B60** ∥ **B61** ∥ **B64**. **B63** espera B59+B62 ✓ (só B59). **B70** espera B59+B69. Prefills ricos de B64 com B61/B63 são soft. **B57** futuro (depende B56 ✓). Fill-ins / débitos `*+` e itens já ✓ permanecem fora do caminho crítico UX-1. **D3** só após smoke + folga se UX-1 não absorver o Zap.
+Paralelizáveis agora: **B71** (polish resultados busca — após B48 ✓); **B73** (remover bottom nav — paralelo a B71/B74); **B74** (gap strip v2 — após ~~B72~~ ✓; paralelo a B73); **B75** (header mobile wizard — após ~~B59~~ ✓; soft nos wizards restantes B63/B64/B70); **B69** (simplificar liderança — paralelo a B59/B62; desbloqueia B70); **B49–B53** após B47 ✓ / B48 ✓ (depois B54/B55). Após **B59**: ~~**B60**~~ ✓ ∥ ~~**B61**~~ ✓ ∥ **B64** (B75 soft). **B63** espera B59+B62 ✓. **B70** espera B59+B69 (+ soft B75). Prefills ricos de B64 com B61/B63 são soft. **B57** futuro (depende B56 ✓). Fill-ins / débitos `*+` e itens já ✓ permanecem fora do caminho crítico UX-1. **D3** só após smoke + folga se UX-1 não absorver o Zap.
### Sequência por janela (só pendentes)
-**Janela 1 — agora → 05/08 (convenções):** **prioridade pós-29/07 — ~~B43–B48~~ ✓ → ~~B67~~ ✓ (pan strip) **→ ~~B65~~ ✓** (âncora inferior) **→ B66** (focus limpa busca) **→ ~~B68~~ ✓\*\* **→ B71** (polish resultados) **· ~~B72~~ ✓** (gap strip) **→** **wizards B59** → B60∥B61∥B64 · ~~B62~~ ✓ → B63 · B69 → B70 (soft 03/08) · **B49–B55** · [fluxos](plans/fluxos-acao-primeiro-inicio.md); smoke + onboarding Onda 0; **E4R ✓** aplicar seed em produção após smoke; demais entregues/pendentes da janela inalterados no detalhe abaixo — foco operacional = polish Início B66/B71 + busca B49+ + wizards B59–B64 + A4 B69/B70.
+**Janela 1 — agora → 05/08 (convenções):** **prioridade pós-29/07 — ~~B43–B48~~ ✓ → ~~B67~~ ✓ (pan strip) **→ ~~B65~~ ✓** (âncora inferior) **→ ~~B66~~ ✓** (focus limpa busca) **→ ~~B68~~ ✓\*\* **→ B71** (polish resultados) **· ~~B72~~ ✓** / **B74** (gap strip) **→ B73** (remover bottom nav) **→** **wizards ~~B59~~ ✓ → B75** (header mobile) → ~~B60~~ ✓/~~B61~~ ✓∥B64 · ~~B62~~ ✓ → B63 · B69 → B70 (soft 03/08) · **B49–B55** · [fluxos](plans/fluxos-acao-primeiro-inicio.md); smoke + onboarding Onda 0; **E4R ✓** aplicar seed em produção após smoke; demais entregues/pendentes da janela inalterados no detalhe abaixo — foco operacional = polish Início B71/B74 + chrome B73/B75 + busca B49+ + wizards B63–B64 + A4 B69/B70.
**Janela 2 — 05/08 → 16/08 (pré-propaganda):** C2 dados reais assim que o jurídico liberar; ~~**E9** fila de alocação~~ (entregue 2026-07-24, antecipada da janela 2); ~~**E16** dossiê do município~~ (entregue 2026-07-25, antecipado da janela 2); D2 se sobrar folga.
@@ -468,9 +487,9 @@ Paralelizáveis agora: **B66** (focus limpa busca — após ~~B65~~ ✓); **B71*
### Cortes seguros / não cortáveis
-**Não cortáveis:** Onda 0 (jurídico/Consent); ~~**B43–B48** chassis UX-1 + busca Municípios~~ ✓; ~~**B67** pan na strip de ações~~ ✓ (entregue 2026-07-29 — B58 escondia a barra; drag fine restaurado); ~~**B65** âncora inferior mobile~~ ✓ (entregue 2026-07-29); **B66** focus limpa busca (cortar = strip compete com o gesto de buscar até digitar — emenda explícita de produto); **B59–B61** etapas mínimas do wizard de votos (chassis + município sticky + busca município + ajuste — cortar = ações do Início continuam inertes no ritual A1 **e** o CG perde o contexto de município no meio do passo); ~~**B62** simplificar sinal~~ ✓ (entregue 2026-07-29); **B69** simplificar liderança (schema `exclusive` + limpeza — cortar = A4/B70 sem modelo e ficha continua inchada); ~~**E4R** seed da planilha~~ (entregue 2026-07-24 — ainda aplicar em produção após smoke); ~~**E8** conta da cadeira~~ (entregue 2026-07-24); ~~**C12** registro-fundação~~ (entregue 2026-07-24); C2 dados reais; assimetria declarado×estimado (relação de campo); ~~**E9** fila de alocação~~ (entregue 2026-07-24 — era o mínimo de "inteligência, não planilha"); ~~**B19** gerenciar assessores~~ (entregue 2026-07-24 — CG/candidato não entram em `/admin`); **B39** lembrar de mim / sessão longa (default de 2 h derruba sessão no onboarding/campo — atrito diário de adoção).
+**Não cortáveis:** Onda 0 (jurídico/Consent); ~~**B43–B48** chassis UX-1 + busca Municípios~~ ✓; ~~**B67** pan na strip de ações~~ ✓ (entregue 2026-07-29 — B58 escondia a barra; drag fine restaurado); ~~**B65** âncora inferior mobile~~ ✓ (entregue 2026-07-29); **B66** focus limpa busca (cortar = strip compete com o gesto de buscar até digitar — emenda explícita de produto); **B59–B61** etapas mínimas do wizard de votos (chassis + município sticky + busca município + ajuste — cortar = ações do Início continuam inertes no ritual A1 **e** o CG perde o contexto de município no meio do passo); **B75** header mobile do wizard (cortar = Voltar+título no conteúdo competem com Mandate Red+sidebar no meio do ritual — emenda explícita a B59); ~~**B62** simplificar sinal~~ ✓ (entregue 2026-07-29); **B69** simplificar liderança (schema `exclusive` + limpeza — cortar = A4/B70 sem modelo e ficha continua inchada); ~~**E4R** seed da planilha~~ (entregue 2026-07-24 — ainda aplicar em produção após smoke); ~~**E8** conta da cadeira~~ (entregue 2026-07-24); ~~**C12** registro-fundação~~ (entregue 2026-07-24); C2 dados reais; assimetria declarado×estimado (relação de campo); ~~**E9** fila de alocação~~ (entregue 2026-07-24 — era o mínimo de "inteligência, não planilha"); ~~**B19** gerenciar assessores~~ (entregue 2026-07-24 — CG/candidato não entram em `/admin`); **B39** lembrar de mim / sessão longa (default de 2 h derruba sessão no onboarding/campo — atrito diário de adoção).
-**Cortes seguros** (se o prazo apertar, nesta ordem): **B71** polish dos resultados de busca (hits continuam clicáveis; cortar = bullets/título/hover feios até folga); **B68** sugestões na busca aberta (digitação B48 continua; cortar = empty mudo no focus até folga); **B64** wizard tendência standalone (A1 ainda pode embutir tendência via B24 ✓ / passo curto; cortar = sem grid colorido + prefill até folga); **B63** wizard sinal standalone (A1 ainda pode embutir select pós-B62; cortar = sem grid/Drawer de tipos até folga); **B70** wizard liderança standalone (A1 ainda pode embutir passo curto pós-B69; cortar = sem grid 2/3/4 até folga — pacote Cairu sofre); **B57** delta 7d (Início continua com total+cobertura do B56; Δ era futuro de propósito); **B56** resumo no Início (Quadro já tem os mesmos agregados — cortar = Início sem briefing numérico); **B55** ações WA/share na busca (linha continua clicável); **B54** grid/cap (empilhar sempre); **B51**/**B53**/**B52**/**B50**/**B49** grupos secundários da busca (nessa ordem — Municípios B48 fica); **D5** inbox→rascunhos (manter registro manual + `wa.me`); **D4** envio bridge (manter `wa.me`); **D3** fundação do canal (atalho `wa.me` continua); **E12** camada TI (rollup manual por lista; **E17** já dá a leitura regional básica no Início); **E13** planejador de giros (rebaixado na fila de corte em 2026-07-24: "perna"/agenda é a restrição dominante nomeada em campo — cortar só depois de E12; agenda segue manual com J-A/J-B como guia); **E15** backtest (pós-eleição por definição — cortar = perder o aprendizado 2030); **E11** motor v1 (manter a fila E9 ✓ sem sugestões); **B13** símbolo proporcional (manter quantis/LQ como escala); ~~**E14** níveis~~ (entregue 2026-07-27 — `priority` continua, intocado); ~~**B8 F2** polígonos~~ (entregue 2026-07-26 — o mapa não é mais agregado em Salvador); **D2** push (adiar); **A6**; ~~**B14** município mais próximo~~ (entregue 2026-07-26); ~~**B38** sidebar recolhido em tablet~~ (entregue 2026-07-26); ~~**B40** login biométrico~~ (entregue 2026-07-28 — senha + B39 ✓ continuam, e cortar teria custado só o atalho de digital/Face ID; era o mais caro e o primeiro a cair desta leva B39–B42); **B42** polimento mobile da lista de municípios (Popover e card longos continuam usáveis — cortar custa conforto de teclado e densidade no celular); ~~**B41** scroll horizontal + sticky~~ (entregue 2026-07-27) (a tabela continua legível com zoom/pan da página — cortar custa o overflow em tablet; cai **depois** de B42 porque o bug de layout em mesa é mais caro que o polish mobile); ~~**B18** filtros salvos~~ ✓ entregue (lista + filtros manuais continuam; Visitados cobrem “voltar”); **B21** página dos Territórios de Identidade (o painel do E17 ✓ no Início continua entregando a leitura regional) — **B25** cai junto por definição (sem destino, sem link); ~~**B17** seletor de colunas~~ ✓ entregue (tabela completa continua; scroll horizontal); ~~**B22** explicação no header~~ (entregue 2026-07-26); ~~**B23** tooltip nas células~~ (entregue 2026-07-26); ~~**B24** auto-save + justificativa na Tendência~~ (entregue 2026-07-26); **B27** combobox + chips nos Assessores (a lista de checkboxes com "Salvar" continua atribuindo — cortar custa a mesma coerência do B24 mais o tempo do CG procurando nomes numa coluna durante o onboarding; corte junto com B24, já que dividem o endpoint); **B28** e-mail + celular na lista de lideranças (a ficha `/liderancas/[id]` continua mostrando o contato — cortar custa o gesto de copiar/abrir ZAP na varredura; quick win barato de cortar e de fazer); ~~**B30** convite de completar cadastro por WhatsApp na lista~~ (entregue 2026-07-26); **B31** coluna de dobradinhas nas lideranças (o `RelationMultiSelect` da ficha interna continua vinculando — cortar custa o preenchimento em lote do onboarding, uma ficha aberta por liderança, e mantém o vínculo invisível na varredura; corte junto com B27, já que dividem a peça de célula, e antes de B29 só se a mesa já tiver preenchido as dobradinhas à mão); ~~**B32** editar Status de apoio na célula~~ (entregue 2026-07-26); **B34** chips editáveis de municípios na lista de lideranças (o texto simples `row.municipalityNames.join(', ')` continua legível e a ficha `/liderancas/[id]` continua vinculando município via formulário — cortar custa o link direto ao município, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha; corte junto com B31, já que dividem a mesma peça de célula editável, e antes de B29 pelo mesmo motivo de coerência); **B37** chips editáveis de municípios na lista de dobradinhas (o número `municipalityCount` continua legível e a ficha de município continua vinculando dobradinha pelo `MunicipalityStrategyForm` — cortar custa o link direto, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha do município; corte junto com B34, já que dividem a mesma lib e a mesma decisão de container); ~~**B36** coluna de lideranças na lista de dobradinhas~~ (entregue 2026-07-26; a contagem `leadershipCount` era o fallback e a ficha `/liderancas/[id]` continua vinculando dobradinha via formulário — cortar custa o link direto à liderança, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha; corte junto com B31, já que dividem a mesma mutação/schema/lock); ~~**B33** sort + filtro no header das dobradinhas~~ (entregue 2026-07-26); **B29** sort + filtro no header das lideranças (a busca por nome continua funcionando e o escopo do assessor já reduz a lista — cortar custa o recorte por status/setor/município no onboarding da rede e mantém o header rico como cópia única de municípios; por ser o item mais caro desta faixa (~1,5–2 dias com a extração do head), cai **antes** do B26, que é o que sustenta o gate de adoção); **B26** registrar sinal na célula (o formulário completo em `/[slug]?tab=updates` continua sendo o caminho — cortar custa o laço da fila do E9 ✓ e o registro em campo pelo celular, que é justamente onde o gate de adoção se decide; por isso cai **depois** de B22/B23/B24); ~~**C13** renomear Plano de Ação → Atividade~~ (entregue 2026-07-25); **B20** prioritários no Início (lista `?priority=alta` continua; só perde o atalho — mas a seção atual mente, então cortar = conviver com o bug); fill-in **renomear coluna Cobertura** (a lista continua legível com o rótulo longo — corte = header mais largo); fill-in **remover coluna Tipo** (a lista continua completa; só mantém densidade morta — corte = conviver com a coluna); ~~fill-in **remover lista de zonas do Início**~~ ✓ (entregue 2026-07-28 — o mapa B8 F2 ✓ continua abrindo cada ZE); ~~**B16** filtros no header~~ (entregue 2026-07-25); ~~**B15** sort por coluna~~ (entregue 2026-07-24); ~~**A11**/**E17**~~ (entregues 2026-07-24); ~~**E18** documentação de conceitos~~ (entregue 2026-07-24); ~~**E16** dossiê~~ (entregue 2026-07-25); demais débitos/fill-ins.
+**Cortes seguros** (se o prazo apertar, nesta ordem): **B74** gap strip v2 (B72 já apertou uma vez — cortar = strip um pouco esparça); **B71** polish dos resultados de busca (hits continuam clicáveis; cortar = bullets/título/hover feios até folga); **B68** sugestões na busca aberta (digitação B48 continua; cortar = empty mudo no focus até folga); **B64** wizard tendência standalone (A1 ainda pode embutir tendência via B24 ✓ / passo curto; cortar = sem grid colorido + prefill até folga); **B63** wizard sinal standalone (A1 ainda pode embutir select pós-B62; cortar = sem grid/Drawer de tipos até folga); **B70** wizard liderança standalone (A1 ainda pode embutir passo curto pós-B69; cortar = sem grid 2/3/4 até folga — pacote Cairu sofre); **B57** delta 7d (Início continua com total+cobertura do B56; Δ era futuro de propósito); **B56** resumo no Início (Quadro já tem os mesmos agregados — cortar = Início sem briefing numérico); **B55** ações WA/share na busca (linha continua clicável); **B54** grid/cap (empilhar sempre); **B51**/**B53**/**B52**/**B50**/**B49** grupos secundários da busca (nessa ordem — Municípios B48 fica); **D5** inbox→rascunhos (manter registro manual + `wa.me`); **D4** envio bridge (manter `wa.me`); **D3** fundação do canal (atalho `wa.me` continua); **E12** camada TI (rollup manual por lista; **E17** já dá a leitura regional básica no Início); **E13** planejador de giros (rebaixado na fila de corte em 2026-07-24: "perna"/agenda é a restrição dominante nomeada em campo — cortar só depois de E12; agenda segue manual com J-A/J-B como guia); **E15** backtest (pós-eleição por definição — cortar = perder o aprendizado 2030); **E11** motor v1 (manter a fila E9 ✓ sem sugestões); **B13** símbolo proporcional (manter quantis/LQ como escala); ~~**E14** níveis~~ (entregue 2026-07-27 — `priority` continua, intocado); ~~**B8 F2** polígonos~~ (entregue 2026-07-26 — o mapa não é mais agregado em Salvador); **D2** push (adiar); **A6**; ~~**B14** município mais próximo~~ (entregue 2026-07-26); ~~**B38** sidebar recolhido em tablet~~ (entregue 2026-07-26); ~~**B40** login biométrico~~ (entregue 2026-07-28 — senha + B39 ✓ continuam, e cortar teria custado só o atalho de digital/Face ID; era o mais caro e o primeiro a cair desta leva B39–B42); **B42** polimento mobile da lista de municípios (Popover e card longos continuam usáveis — cortar custa conforto de teclado e densidade no celular); ~~**B41** scroll horizontal + sticky~~ (entregue 2026-07-27) (a tabela continua legível com zoom/pan da página — cortar custa o overflow em tablet; cai **depois** de B42 porque o bug de layout em mesa é mais caro que o polish mobile); ~~**B18** filtros salvos~~ ✓ entregue (lista + filtros manuais continuam; Visitados cobrem “voltar”); **B21** página dos Territórios de Identidade (o painel do E17 ✓ no Início continua entregando a leitura regional) — **B25** cai junto por definição (sem destino, sem link); ~~**B17** seletor de colunas~~ ✓ entregue (tabela completa continua; scroll horizontal); ~~**B22** explicação no header~~ (entregue 2026-07-26); ~~**B23** tooltip nas células~~ (entregue 2026-07-26); ~~**B24** auto-save + justificativa na Tendência~~ (entregue 2026-07-26); **B27** combobox + chips nos Assessores (a lista de checkboxes com "Salvar" continua atribuindo — cortar custa a mesma coerência do B24 mais o tempo do CG procurando nomes numa coluna durante o onboarding; corte junto com B24, já que dividem o endpoint); **B28** e-mail + celular na lista de lideranças (a ficha `/liderancas/[id]` continua mostrando o contato — cortar custa o gesto de copiar/abrir ZAP na varredura; quick win barato de cortar e de fazer); ~~**B30** convite de completar cadastro por WhatsApp na lista~~ (entregue 2026-07-26); **B31** coluna de dobradinhas nas lideranças (o `RelationMultiSelect` da ficha interna continua vinculando — cortar custa o preenchimento em lote do onboarding, uma ficha aberta por liderança, e mantém o vínculo invisível na varredura; corte junto com B27, já que dividem a peça de célula, e antes de B29 só se a mesa já tiver preenchido as dobradinhas à mão); ~~**B32** editar Status de apoio na célula~~ (entregue 2026-07-26); **B34** chips editáveis de municípios na lista de lideranças (o texto simples `row.municipalityNames.join(', ')` continua legível e a ficha `/liderancas/[id]` continua vinculando município via formulário — cortar custa o link direto ao município, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha; corte junto com B31, já que dividem a mesma peça de célula editável, e antes de B29 pelo mesmo motivo de coerência); **B37** chips editáveis de municípios na lista de dobradinhas (o número `municipalityCount` continua legível e a ficha de município continua vinculando dobradinha pelo `MunicipalityStrategyForm` — cortar custa o link direto, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha do município; corte junto com B34, já que dividem a mesma lib e a mesma decisão de container); ~~**B36** coluna de lideranças na lista de dobradinhas~~ (entregue 2026-07-26; a contagem `leadershipCount` era o fallback e a ficha `/liderancas/[id]` continua vinculando dobradinha via formulário — cortar custa o link direto à liderança, a navegação por chip e o atalho de adicionar/remover sem abrir a ficha; corte junto com B31, já que dividem a mesma mutação/schema/lock); ~~**B33** sort + filtro no header das dobradinhas~~ (entregue 2026-07-26); **B29** sort + filtro no header das lideranças (a busca por nome continua funcionando e o escopo do assessor já reduz a lista — cortar custa o recorte por status/setor/município no onboarding da rede e mantém o header rico como cópia única de municípios; por ser o item mais caro desta faixa (~1,5–2 dias com a extração do head), cai **antes** do B26, que é o que sustenta o gate de adoção); **B26** registrar sinal na célula (o formulário completo em `/[slug]?tab=updates` continua sendo o caminho — cortar custa o laço da fila do E9 ✓ e o registro em campo pelo celular, que é justamente onde o gate de adoção se decide; por isso cai **depois** de B22/B23/B24); ~~**C13** renomear Plano de Ação → Atividade~~ (entregue 2026-07-25); **B20** prioritários no Início (lista `?priority=alta` continua; só perde o atalho — mas a seção atual mente, então cortar = conviver com o bug); fill-in **renomear coluna Cobertura** (a lista continua legível com o rótulo longo — corte = header mais largo); fill-in **remover coluna Tipo** (a lista continua completa; só mantém densidade morta — corte = conviver com a coluna); ~~fill-in **remover lista de zonas do Início**~~ ✓ (entregue 2026-07-28 — o mapa B8 F2 ✓ continua abrindo cada ZE); ~~**B16** filtros no header~~ (entregue 2026-07-25); ~~**B15** sort por coluna~~ (entregue 2026-07-24); ~~**A11**/**E17**~~ (entregues 2026-07-24); ~~**E18** documentação de conceitos~~ (entregue 2026-07-24); ~~**E16** dossiê~~ (entregue 2026-07-25); demais débitos/fill-ins.
## Bloqueadores atuais