From 4b8031585dd11e95350201fd20f23e0133aaea9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Ign=C3=A1cio=20Fontoura=20Solla?= Date: Thu, 30 Jul 2026 03:17:50 -0300 Subject: [PATCH] =?UTF-8?q?docs(roadmap):=20register=20B79=E2=80=93B90=20q?= =?UTF-8?q?uick-actions=20bottom=20drawer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Capture the post-B73 mobile chrome: non-modal drawer chassis plus per-vertical action catalogs (Quadro excluded; batch non-cuttable). --- .cursor/rules/projects/nucleos-eleitorais.mdc | 1 + docs/plans/acoes-rapidas-apoiadores.md | 64 ++++++++++ docs/plans/acoes-rapidas-assessores.md | 65 ++++++++++ docs/plans/acoes-rapidas-atividades.md | 66 ++++++++++ docs/plans/acoes-rapidas-conceitos-perfil.md | 65 ++++++++++ .../plans/acoes-rapidas-contatos-lideranca.md | 66 ++++++++++ docs/plans/acoes-rapidas-demandas.md | 65 ++++++++++ docs/plans/acoes-rapidas-dobradinhas.md | 65 ++++++++++ docs/plans/acoes-rapidas-liderancas.md | 65 ++++++++++ docs/plans/acoes-rapidas-municipios.md | 88 +++++++++++++ docs/plans/acoes-rapidas-organizacoes.md | 64 ++++++++++ docs/plans/acoes-rapidas-territorios.md | 67 ++++++++++ .../chassis-bottom-drawer-acoes-rapidas.md | 116 ++++++++++++++++++ docs/roadmap.md | 53 +++++++- 14 files changed, 904 insertions(+), 6 deletions(-) create mode 100644 docs/plans/acoes-rapidas-apoiadores.md create mode 100644 docs/plans/acoes-rapidas-assessores.md create mode 100644 docs/plans/acoes-rapidas-atividades.md create mode 100644 docs/plans/acoes-rapidas-conceitos-perfil.md create mode 100644 docs/plans/acoes-rapidas-contatos-lideranca.md create mode 100644 docs/plans/acoes-rapidas-demandas.md create mode 100644 docs/plans/acoes-rapidas-dobradinhas.md create mode 100644 docs/plans/acoes-rapidas-liderancas.md create mode 100644 docs/plans/acoes-rapidas-municipios.md create mode 100644 docs/plans/acoes-rapidas-organizacoes.md create mode 100644 docs/plans/acoes-rapidas-territorios.md create mode 100644 docs/plans/chassis-bottom-drawer-acoes-rapidas.md diff --git a/.cursor/rules/projects/nucleos-eleitorais.mdc b/.cursor/rules/projects/nucleos-eleitorais.mdc index c873580c..5f8365a8 100644 --- a/.cursor/rules/projects/nucleos-eleitorais.mdc +++ b/.cursor/rules/projects/nucleos-eleitorais.mdc @@ -7,6 +7,7 @@ alwaysApply: false ## Status +- **B79–B90 registrados (2026-07-30):** pós-**B73** (remover bottom nav), chrome mobile fora do Início = bottom drawer **não-modal** (ações contextuais + busca global) — chassis **B79** + catálogos por vertical **B80–B90** (Municípios, Territórios, Lideranças, Dobradinhas, Atividades, Demandas, Apoiadores, Assessores, Organizações, Contatos leader, Conceitos+Perfil). **Quadro fora** do inventário. Granularidade = uma vertical (lista+detalhe). Lote inteiro **não cortável**. Planos em `docs/plans/chassis-bottom-drawer-acoes-rapidas.md` e `acoes-rapidas-*.md`. - **B77 registrado (2026-07-30):** simplificar wizard ajuste de votos — três cenários numa tela (strip + inputs como popover da lista); atalhos no input focado; coerência só no confirm com highlight; substitui ritual `?cenario=` de B61/B76. Plano: [`simplificar-ajuste-votos-wizard.md`](../../../docs/plans/simplificar-ajuste-votos-wizard.md). - **B71 entregue em código (2026-07-30):** polimento visual dos resultados de busca no Início (UX-1) — `src/lib/homeSearchUi.ts` (`HOME_SEARCH_HIT_ROW_WRAPPER_CLASS` = bleed + hover + `focus-within`; heading/list); `HomeSearchHitRow` faixa full-bleed `-mx-4 px-4 md:-mx-6 md:px-6` (mantém `onMouseDown` preventDefault de B66); todos os `HomeSearch*Group` com `ul list-none` e título `text-xs` sentence-case (sem `uppercase`/`tracking-wide`). Unit `homeSearchUi.unit.spec.tsx`. Sem migration/action/JSON. Plano: [`polimento-resultados-busca-inicio.md`](../../../docs/plans/polimento-resultados-busca-inicio.md). - **B66 entregue em código (2026-07-30):** modo focado da busca no **focus** (emenda B47) — `homeSearchUiFocused` (`inputFocused || query.isActive`) já no contrato/hook; overlap B68 (sugestões no focus vazio). **Nesta entrega:** `CampaignHomeLayout` retrai summary+spacer (`data-slot="home-chrome"`) e actions com grid `0fr/1fr` + opacity 220ms (`motion-reduce:transition-none`) em vez de `hidden`; `md:flex-none` no chrome; `HomeSearchHitRow` `onMouseDown` preventDefault (blur→click); e2e focus sem digitar + regressão com digitação. Sem migration. Plano: [`modo-focado-busca-no-focus.md`](../../../docs/plans/modo-focado-busca-no-focus.md). diff --git a/docs/plans/acoes-rapidas-apoiadores.md b/docs/plans/acoes-rapidas-apoiadores.md new file mode 100644 index 00000000..4293a478 --- /dev/null +++ b/docs/plans/acoes-rapidas-apoiadores.md @@ -0,0 +1,64 @@ +# Ações rápidas — Apoiadores + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B86**) +Impeccable: B — drawer B79 em `/apoiadores` (staff) +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · C2 · B79. Craft + **Revisão na implementação**. + +Brief: staff no cadastro nominal quer cadastrar / importar / buscar sem voltar ao Início. Leader usa **B89**, não esta rota. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/apoiadores` staff (access `canAccessSupporterArea`). Import CSV e create já existem na vertical. + +## Objetivos + +- Catálogo sugerido: “Cadastrar apoiador” (rota/create da vertical), atalho import se houver URL estável, busca global B79; **não** empurrar A1–A5 como primários. +- Sem migration / sem novo Consent (usa chaves C2 existentes nos flows). + +## Revisão na implementação _(obrigatória)_ + +Se import estiver escondido atrás de wizard multi-step, o launcher deve apontar ao step 1 — não inventar atalho que bypassa preview. + +## Decisões travadas + +- **Staff only nesta rota.** Leader → B89. **Rejeitado:** misturar catálogos. +- **i18n:** `register-supporter` / labels da vertical. + +## Questões em aberto + +- **Incluir A1–A5 como secundários?** **Opções:** A) não | B) no expanded. **Recomendação:** **A**. + +## Abordagem proposta + +Registry `/apoiadores` → 1–2 launchers da vertical + busca. + +## Dependências + +Dura: **B79**. Soft: C2 eng ✓. + +## Não escopo + +B89 Contatos; B79. + +## Rabbit holes + +Import token / bulk no drawer. Mitigação: wizard existente. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`apoiadores/**` · B79 · C2 plans diff --git a/docs/plans/acoes-rapidas-assessores.md b/docs/plans/acoes-rapidas-assessores.md new file mode 100644 index 00000000..ab91fbf2 --- /dev/null +++ b/docs/plans/acoes-rapidas-assessores.md @@ -0,0 +1,65 @@ +# Ações rápidas — Assessores + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B87**) +Impeccable: B — drawer B79 em `/assessores` (unrestricted) +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · B19 ✓ · B79. Craft + **Revisão na implementação**. + +Brief: CG/candidato gerindo contas quer novo assessor / abrir carteira / busca — sem A1–A5 como foco. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/assessores` + detalhe; só `isCampaignUnrestricted`. Assessor autenticado **não** monta esta vertical. + +## Objetivos + +- Catálogo: “Novo assessor” → `/assessores/nova` (ou rota real); no detalhe, atalho carteira/municípios se útil; busca global. +- Gate: drawer nesta rota só se o actor for unrestricted (alinhado ao page gate). +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Confirmar paths reais (`nova` / `[id]`) no tree atual antes de hardcodar hrefs. + +## Decisões travadas + +- **Sem ações de município como primárias.** **Rejeitado:** strip B45 completa aqui. +- **i18n:** `new-advisor`; labels pt-BR B19. + +## Questões em aberto + +- **Reset de senha no drawer?** **Opções:** A) não (fica no detalhe) | B) sim. **Recomendação:** **A**. + +## Abordagem proposta + +Registry + role gate unrestricted. + +## Dependências + +Dura: **B79**. Soft: B19 ✓. + +## Não escopo + +B79; B86. + +## Rabbit holes + +Editar carteira inteira no drawer. Mitigação: B34/B19 cells. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`assessores/**` · B19 plan · B79 diff --git a/docs/plans/acoes-rapidas-atividades.md b/docs/plans/acoes-rapidas-atividades.md new file mode 100644 index 00000000..2b2ab376 --- /dev/null +++ b/docs/plans/acoes-rapidas-atividades.md @@ -0,0 +1,66 @@ +# Ações rápidas — Atividades (lista + detalhe + giros) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B84**) +Impeccable: B — drawer B79 em `/atividades`, `/atividades/[slug]`, `/atividades/giros` +Appetite: ~0,5 dia eng; atalhos de criação/agenda; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · C13 · E13 giros · B79. Craft + **Revisão na implementação**. + +Brief: staff na agenda quer criar atividade / planejar giro / (no detalhe) atalho ligado ao município da atividade. Anti-goal: segundo compositor no drawer. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +Lista, detalhe e compositor `/atividades/giros` (E13). Wizard A1–A5 do Início são secundários aqui; verbo próprio da vertical importa mais. + +## Objetivos + +- **Lista:** “Nova atividade” → `/atividades/nova`; “Planejar giro” → `/atividades/giros`; opcional subset Início sem prefill. +- **Detalhe:** se houver município na atividade, A1–A5 com `?municipio=`; atalho editar/tarefas via tabs existentes se útil. +- **Giros:** drawer mínimo (busca + voltar lista) — não competir com o compositor. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Se o compositor de giro já tiver CTAs suficientes, o agente pode **omitir** o drawer em `/giros` (exceção local ao mount B79) — documentar. + +## Decisões travadas + +- **Priorizar verbos da vertical sobre os 6 do Início.** **Rejeitado:** só espelhar B45. +- **i18n:** `new-activity`, `plan-tour`; labels pt-BR. + +## Questões em aberto + +- **Drawer em `/giros`?** **Opções:** A) omitir | B) só busca. **Recomendação:** **A** ou **B** — não strip de ações. + +## Abordagem proposta + +Registry por pathname; context `{ municipalitySlug? }` do loader do detalhe. + +## Dependências + +Dura: **B79**. Soft: E13 ✓, B45 ✓, B60 ✓. + +## Não escopo + +B79; demandas B85. + +## Rabbit holes + +Checklist de tarefas no drawer. Mitigação: fica no detalhe. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`atividades/**` · E13 plan · B79 diff --git a/docs/plans/acoes-rapidas-conceitos-perfil.md b/docs/plans/acoes-rapidas-conceitos-perfil.md new file mode 100644 index 00000000..b719ccbb --- /dev/null +++ b/docs/plans/acoes-rapidas-conceitos-perfil.md @@ -0,0 +1,65 @@ +# Ações rápidas — Conceitos + Perfil (só busca) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B90**) +Impeccable: B — drawer B79 sem strip de ações (ou strip vazia) em `/conceitos` e `/perfil` +Appetite: ~0,25 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · E18 conceitos · B79. Craft + **Revisão na implementação**. + +Brief: páginas de referência/conta — usuário ainda precisa da busca global para sair rápido para um município/pessoa; ações de ritual **não** competem com leitura de glossário ou form de perfil. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/conceitos` (staff secondary nav); `/campanha/perfil`. Não são mesas de operação. + +## Objetivos + +- Mount B79 com **busca global staff** e **sem** catálogo de ações (ou só “Voltar ao Início” se critique exigir âncora). +- Leader em `/perfil`: sem home-search staff; drawer mínimo ou omitir — **Recomendação:** omitir drawer no perfil leader se não houver busca segura. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Se o perfil ganhar atalhos úteis (ex. biometria B40), o agente pode adicionar 1 launcher — não a strip B45. + +## Decisões travadas + +- **Sem A1–A5 em Conceitos/Perfil.** **Rejeitado:** paridade Início “por consistência”. +- **i18n:** nenhum id de ação obrigatório; `home-href` se existir. + +## Questões em aberto + +- **“Ir ao Início” no peek?** **Opções:** A) não (sidebar) | B) sim. **Recomendação:** **A**. + +## Abordagem proposta + +Registry entries com `actions: []` + search enabled para staff. + +## Dependências + +Dura: **B79**. Soft: B47 ✓. + +## Não escopo + +Quadro (fora do inventário 2026-07-30); B79 chrome. + +## Rabbit holes + +Glossário searchable no drawer. Mitigação: página Conceitos já é o índice. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`conceitos/**` · `perfil/**` · B79 diff --git a/docs/plans/acoes-rapidas-contatos-lideranca.md b/docs/plans/acoes-rapidas-contatos-lideranca.md new file mode 100644 index 00000000..cc22b533 --- /dev/null +++ b/docs/plans/acoes-rapidas-contatos-lideranca.md @@ -0,0 +1,66 @@ +# Ações rápidas — Contatos (liderança) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B89**) +Impeccable: B — drawer B79 para role `leader` em `/campanha/contatos` +Appetite: ~0,25–0,5 dia eng; lockdown; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT.md Depth for staff / light for leader · B43/B45 leader · B79. Craft + **Revisão na implementação**. + +Brief: liderança no celular cadastra apoiador / vê contatos; **sem** omnibus estadual nem A1–A5. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +Leader home de trabalho = `/campanha/contatos` (B43). Catálogo B45: `register-supporter`, `my-contacts`. + +## Objetivos + +- Montar drawer só para `leader` nas rotas leader (Contatos; Início leader já tem ações — **sem** drawer no Início, mesma exclusão B79). +- Ações: espelho B45 leader; busca: **não** reusar `home-search` staff — ou omitir busca, ou busca local só nos próprios contatos se já existir endpoint/lista filter. **Recomendação v1:** ações + sem omnibox global (fail closed). +- Sem migration; Consent das actions de apoiador inalterado. + +## Revisão na implementação _(obrigatória)_ + +Se no momento existir busca local de contatos, o agente pode plugar no slot de busca do B79 **sem** abrir `home-search` staff. + +## Decisões travadas + +- **Lockdown: zero wizards de município.** **Rejeitado:** “só leitura” de mapa/lista. +- **Sem POST `/campanha/home-search` para leader.** **Rejeitado:** scoped hack no mesmo endpoint sem access review. +- **i18n:** ids B45 leader. + +## Questões em aberto + +- **Busca local no drawer?** **Opções:** A) omitir v1 | B) filtrar lista client-side. **Recomendação:** **A** se a página já tem search; **B** se a lista for longa e sem filtro. + +## Abordagem proposta + +Registry role=leader + path contatos → 2 ações B45. Slot search vazio ou filtro local. + +## Dependências + +Dura: **B79**. Soft: B45 ✓, B43 ✓. + +## Não escopo + +B86 staff apoiadores; B79 staff search providers. + +## Rabbit holes + +WebAuthn / perfil no drawer. Mitigação: `/perfil` separado (B90). + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`contatos/**` · `campaignHomeActions.ts` leader · B79 diff --git a/docs/plans/acoes-rapidas-demandas.md b/docs/plans/acoes-rapidas-demandas.md new file mode 100644 index 00000000..01a4b5f6 --- /dev/null +++ b/docs/plans/acoes-rapidas-demandas.md @@ -0,0 +1,65 @@ +# Ações rápidas — Demandas (lista + detalhe) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B85**) +Impeccable: B — drawer B79 em `/demandas` (+ detalhe) +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · A5 register-demand · B79. Craft + **Revisão na implementação**. + +Brief: staff quer registrar pedido ou agir no município da demanda aberta. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/demandas`; detalhe por slug se existir. Wizard `register-demand` (quando B59+ wiring existir) + forms da vertical. + +## Objetivos + +- **Lista:** `register-demand` (Início/wizard) + busca; opcional “Nova demanda” rota local se for o caminho canônico atual. +- **Detalhe:** se houver município vinculado, prefills A1–A5; atalho específico da demanda (escalar/fechar) só se já existir action/URL — senão omitir. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Confirmar se o caminho canônico de criação ainda é form da vertical ou já é wizard A5; alinhar o href único. + +## Decisões travadas + +- **Um launcher de “Registrar pedido”, não dois.** **Rejeitado:** botão wizard + botão `/nova` no mesmo peek. +- **i18n:** id `register-demand`. + +## Questões em aberto + +- **Wizard A5 vs form legado?** **Opções:** A) wizard quando rota existir | B) form. **Recomendação:** **A** se `/acoes/registrar-pedido` estiver no ar; senão B. + +## Abordagem proposta + +Registry + `wizardActionHref` / rota de create existente. + +## Dependências + +Dura: **B79**. Soft: B45 ✓, B53, wiring A5. + +## Não escopo + +B79; B84. + +## Rabbit holes + +Fila de decisão de demanda no drawer. Mitigação: detalhe. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`demandas/**` · B79 · fluxos UX-1 A5 diff --git a/docs/plans/acoes-rapidas-dobradinhas.md b/docs/plans/acoes-rapidas-dobradinhas.md new file mode 100644 index 00000000..9829a7ac --- /dev/null +++ b/docs/plans/acoes-rapidas-dobradinhas.md @@ -0,0 +1,65 @@ +# Ações rápidas — Dobradinhas + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B83**) +Impeccable: B — drawer B79 em `/dobradinhas` (+ detalhe se houver) +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · B79 · lista B37/B36. Craft + **Revisão na implementação**. + +Brief: staff na vertical de state deputies quer buscar ou iniciar ritual ligado ao território da dobradinha — sem inventar wizard de dobradinha neste item. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/dobradinhas` (lista). Detalhe se existir na árvore de rotas — mesma política de context. + +## Objetivos + +- Catálogo sugerido: busca global (B79) + ações Início **sem** prefill; atalho opcional “Municípios desta dobradinha” se houver filtro/URL estável. +- Não inventar `?stateDeputy=` nos wizards A1–A5 nesta fatia. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Agente pode cortar ações Início se o único job real for navegação+busca; ou propor deep-link de filtro se o serializador de lista já permitir. + +## Decisões travadas + +- **Sem wizard novo de dobradinha.** **Rejeitado:** fluxo paralelo ao `MunicipalityStrategyForm`. +- **i18n:** ids B45; `stateDeputyId` só se nascer atalho. + +## Questões em aberto + +- **Incluir WA share (B55) como ação do drawer?** **Opções:** A) não (fica na linha de busca) | B) sim. **Recomendação:** **A**. + +## Abordagem proposta + +Registry `/dobradinhas` → subset staff (ações Início ou só busca+1–2 verbos). Soft link para lista de municípios filtrada se API de URL existir. + +## Dependências + +Dura: **B79**. Soft: B45 ✓, B52 ✓. + +## Não escopo + +B79; B82; chips B37. + +## Rabbit holes + +Prefill município “principal” da dobradinha. Mitigação: N municípios — mesma regra do B82. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`dobradinhas/**` · B79 · `campaignHomeActions.ts` diff --git a/docs/plans/acoes-rapidas-liderancas.md b/docs/plans/acoes-rapidas-liderancas.md new file mode 100644 index 00000000..7a3c63f4 --- /dev/null +++ b/docs/plans/acoes-rapidas-liderancas.md @@ -0,0 +1,65 @@ +# Ações rápidas — Lideranças (lista + detalhe) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B82**) +Impeccable: B — catálogo drawer B79 em `/liderancas` e `/liderancas/[id]` +Appetite: ~0,5 dia eng; prefills A4 + município(s) da liderança; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · B45 · B70 · B79. Craft compacto + **Revisão na implementação**. + +Brief: staff na rede quer atualizar a pessoa à frente ou lançar ritual no município dela. Anti-goal: spreadsheet no drawer. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +Lista `/campanha/liderancas`; detalhe `/campanha/liderancas/[id]`. Wizard A4 (**B70**) é o verbo central; municípios da liderança alimentam prefill opcional de A1–A3/A5. + +## Objetivos + +- **Lista:** subset — `update-leadership` (sem id), atalhos de lista se existirem; demais ações Início sem prefill _(recomendado: strip enxuta, não os 6)_ . +- **Detalhe:** `update-leadership` com context `leadershipId` (query a definir no B70/chassis — se ainda não houver, href para ficha `/editar` ou wizard quando o param existir); se a liderança tiver **um** município, prefills A1–A3/A5 com esse slug; se N, não adivinhar — usuário escolhe no B60. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Se B70 ainda não expuser query de liderança, o agente deve (1) propor o param mínimo no wizard ou (2) degradar para link da ficha — registrar escolha no as-built. + +## Decisões travadas + +- **Não auto-escolher município quando N>1.** **Rejeitado:** “primeiro da lista” / TI inteiro. +- **i18n:** `leadershipId` em inglês; labels B58. + +## Questões em aberto + +- **Query `?lideranca=` no wizard A4?** **Opções:** A) sim no B70/B82 | B) só município. **Recomendação:** **A** quando B70 estiver no ar — senão degradar. + +## Abordagem proposta + +Context `{ leadershipId, municipalitySlug? }` → registry. Reuso `wizardActionHref`. + +## Dependências + +Dura: **B79**. Soft: B70, B60 ✓, B45 ✓. + +## Não escopo + +Chassis B79; dobradinhas B83; Contatos leader B89. + +## Rabbit holes + +**Convite WhatsApp (B30) no drawer.** Mitigação: já está na lista; não duplicar. + +## Adiado com gatilho + +Prefill multi-município com picker no drawer — quando N>1 for o caso dominante em campo. + +## Referências + +`liderancas/**` · B70 plan · B79 plan · `campaignHomeActions.ts` diff --git a/docs/plans/acoes-rapidas-municipios.md b/docs/plans/acoes-rapidas-municipios.md new file mode 100644 index 00000000..a5d804ea --- /dev/null +++ b/docs/plans/acoes-rapidas-municipios.md @@ -0,0 +1,88 @@ +# Ações rápidas — Municípios (lista + detalhe) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B80** — consumer do B79) +Impeccable: B — encaixe no drawer B79; catálogo + prefills; sem rota nova +Appetite: ~0,5–0,75 dia eng; registry + hrefs contextualizados; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: `PRODUCT.md` / `DESIGN.md` · catálogo B45 · wizards B59+ · tema `campaign`. + +Na implementação: craft compacto → critique → polish. **Antes do craft:** revisar o catálogo abaixo contra o estado atual dos wizards/rotas (seção Revisão). + +Brief compacto: + +- **Persona:** staff na lista ou no detalhe de município, no celular, quer agir sem voltar ao Início. +- **Job principal:** no detalhe, lançar A1–A5 **já com o município** (pula B60); na lista, mesmas ações do Início (escolhe município no wizard). +- **Estratégia de cor:** Restrained (herda B79). +- **Edit where you see:** não — launchers para wizards/listas já existentes. +- **Anti-goals:** duplicar formulários do detalhe no drawer; esconder edição inline da lista. + +## Dados → decisão → apresentação + +Dados: N/A — launchers; números ficam nos wizards/detalhe. + +## Contexto + +Exemplo canônico do pedido 2026-07-30: no detalhe `/campanha/municipios/[slug]`, as ações do Início partem com `?municipio=` via `wizardActionHref`. Lista `/campanha/municipios` usa os mesmos ids sem prefill (paridade B45). + +## Objetivos + +- Registrar no registry do **B79** as superfícies `municipios` (lista) e `municipios/[slug]` (detalhe). +- **Detalhe:** ações `update-votes`, `register-signal`, `change-trend`, `update-leadership`, `register-demand` com `wizardActionHref(slug, municipio)`; atalho `uncovered-municipalities` opcional (baixa prioridade no detalhe — pode omitir). +- **Lista:** espelhar catálogo staff do Início (B45), hrefs sem município. +- Assessor: mesmas regras de escopo (wizard/access já filtram). +- Sem migration / Consent / action nova. + +## Revisão na implementação _(obrigatória)_ + +No Passo 4–7 de `implement-roadmap-item`, o agente **pode e deve** propor alteração de ids/rótulos/prefills se wizards novos, rotas renomeadas ou evidência de campo contradisserem esta tabela. Registrar a proposta em “Questões em aberto” do PR/plano as-built; não expandir appetite sem validar com produto se mudar o verbo principal. + +## Decisões travadas + +- **Detalhe = Início + `?municipio=` e skip da etapa B60.** **Rejeitado:** abrir `/editar`; Sheet local de votos no drawer. +- **Lista = paridade Início (sem prefill).** **Rejeitado:** forçar “último município visitado” sem pedido. +- **i18n:** ids estáveis do B45; labels curtos da strip (B58). + +## Questões em aberto + +- **Incluir “Ver esquecidos” no detalhe?** **Opções:** A) não | B) sim. **Recomendação:** **A** — fora de contexto no detalhe. + +## Abordagem proposta + +```mermaid +flowchart LR + page["municipios page RSC"] --> ctx["context.municipalitySlug?"] + ctx --> reg["resolveQuickActions"] + reg --> drawer["B79 drawer"] + drawer --> wiz[" /acoes/*?municipio= "] +``` + +Componentes: + +- Provider/registry entries em `src/lib/` (ou ao lado do chassis) lendo `params.slug` no detalhe. +- Reuso `toHomeActionButtonProps` / `wizardActionHref`. +- **Migration:** nenhuma. + +## Dependências + +- Dura: **B79**. Soft: B45 ✓, B60 ✓, B61/B63/B64/B70 conforme disponíveis (href aponta; wizard incompleto = página ponte). + +## Não escopo + +- Chassis UI → **B79**. Outras verticais → **B81–B90**. Territórios → **B81**. + +## Rabbit holes + +- **Deep-link para tab específica do detalhe além do wizard.** **Mitigação:** só wizards + atalhos de lista neste item. + +## Adiado com gatilho + +- **Ação “Definir nível” (E14) no drawer do detalhe.** Revisitar quando o CG pedir N0–N4 no ritual mobile (hoje submit explícito + nota). + +## Referências + +- [chassis-bottom-drawer-acoes-rapidas.md](chassis-bottom-drawer-acoes-rapidas.md) · `campaignActionRoutes.ts` · `campaignHomeActions.ts` · `municipios/[slug]/page.tsx` diff --git a/docs/plans/acoes-rapidas-organizacoes.md b/docs/plans/acoes-rapidas-organizacoes.md new file mode 100644 index 00000000..eec6bda4 --- /dev/null +++ b/docs/plans/acoes-rapidas-organizacoes.md @@ -0,0 +1,64 @@ +# Ações rápidas — Organizações + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B88**) +Impeccable: B — drawer B79 em `/organizacoes` (+ detalhe) +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: PRODUCT/DESIGN · vertical organizações · B79. Craft + **Revisão na implementação**. + +Brief: staff em orgs (ramificações políticas, ex. SindMed) quer criar/buscar/ligar — prioridade baixa vs Municípios/Lideranças, mas **não cortável** no lote (produto 2026-07-30). + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/organizacoes` + `[slug]` / `nova`. Fora do `staffNav` principal em alguns momentos históricos — rota existe. + +## Objetivos + +- Catálogo: “Nova organização”, busca global; no detalhe, atalho para lideranças vinculadas se URL de lista filtrada existir; A1–A5 só se houver município óbvio (geralmente **não**). +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Se a vertical estiver pouco usada no momento do implement, manter **busca + nova** e omitir A1–A5 sem culpa. + +## Decisões travadas + +- **Drawer existe mesmo fora do bottom-nav histórico.** **Rejeitado:** pular org do lote. +- **i18n:** `new-organization`. + +## Questões em aberto + +- **Prefill liderança a partir da org?** **Opções:** A) não v1 | B) se B70 aceitar. **Recomendação:** **A**. + +## Abordagem proposta + +Registry paths org → launchers CRUD locais + busca. + +## Dependências + +Dura: **B79**. Soft: B69 ✓ (org permanece no modelo). + +## Não escopo + +B82; B79. + +## Rabbit holes + +Multi-org membership editor no drawer. Mitigação: forms existentes. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`organizacoes/**` · B79 · B69 plan diff --git a/docs/plans/acoes-rapidas-territorios.md b/docs/plans/acoes-rapidas-territorios.md new file mode 100644 index 00000000..12163e6a --- /dev/null +++ b/docs/plans/acoes-rapidas-territorios.md @@ -0,0 +1,67 @@ +# Ações rápidas — Territórios de Identidade + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B81**) +Impeccable: B — catálogo no drawer B79 para `/campanha/territorios` +Appetite: ~0,25–0,5 dia eng; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: `PRODUCT.md` / `DESIGN.md` · B21 ✓ / E12 ✓ · B79. + +Na implementação: craft compacto → critique → polish + **Revisão na implementação** (abaixo). + +Brief: staff olhando TIs quer ou filtrar municípios da região ou iniciar ritual sem voltar ao Início. Restrained. Anti-goal: fingir que TI é município no `?municipio=`. + +## Dados → decisão → apresentação + +Dados: N/A. + +## Contexto + +`/campanha/territorios` (B21) é lista regional; linha → `municipios?region=`. Sem entidade “município atual”. + +## Objetivos + +- Catálogo sugerido: ações Início **sem** prefill de município + atalho “Ver municípios deste TI” quando houver linha/seleção _(se a UI expuser TI ativo; senão só ações Início)_. +- Sem inventar wizard de TI. +- Sem migration. + +## Revisão na implementação _(obrigatória)_ + +Agente pode reordenar/cortar ações se, no momento do implement, o uso real de Territórios for só “pular para lista filtrada” — documentar desvio. + +## Decisões travadas + +- **Sem `?municipio=` a partir do TI.** **Rejeitado:** pegar “primeiro município do TI” como prefill (mentira geográfica). +- **i18n:** ids B45 + `territory-municipalities` se nascer atalho. + +## Questões em aberto + +- **Atalho por TI exige seleção de linha?** **Opções:** A) só ações Início na v1 | B) expandir drawer ao tocar linha com atalho. **Recomendação:** **A** neste appetite. + +## Abordagem proposta + +Registry path `/campanha/territorios` → catálogo staff Início (hrefs B45). Opcional: deep-link `buildMunicipalityListHref({ region })` se contexto de TI existir. + +## Dependências + +Dura: **B79**. Soft: B21 ✓, B45 ✓. + +## Não escopo + +Chassis → B79. Municípios → B80. + +## Rabbit holes + +**Agregar ações “por TI” com meta/cobertura.** Mitigação: fora — E12 já está na tabela. + +## Adiado com gatilho + +Nenhum neste item. + +## Referências + +`territorios/page.tsx` · `municipalityListUrl` · B79 plan diff --git a/docs/plans/chassis-bottom-drawer-acoes-rapidas.md b/docs/plans/chassis-bottom-drawer-acoes-rapidas.md new file mode 100644 index 00000000..54a28083 --- /dev/null +++ b/docs/plans/chassis-bottom-drawer-acoes-rapidas.md @@ -0,0 +1,116 @@ +# Chassis do bottom drawer de ações rápidas + busca (mobile) + +Status: rascunho +Atualizado em: 2026-07-30 +Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item **B79** — UX-1 chrome pós-B73) +Impeccable: C — chrome novo em toda rota `(app)` exceto Início e wizards; gesto drag + busca embutida +Appetite: ~1,5–2 dias eng; shell não-modal + snap/drag + slot de ações + reuso da busca global; sem migration +Responsável: — + +## Design (Impeccable) + +Âncoras: `PRODUCT.md` (Clarity under pressure; Feel the action; anti spreadsheet) / `DESIGN.md` (hybrid mobile Mandate Red + sidebar Sheet) · tema `data-theme='campaign'` · primitivo `Drawer` (`src/components/ui/Drawer.tsx`, já com `modal={false}` que **não** monta overlay). + +Na implementação (`implement-roadmap-item`): shape → craft → critique → polish. + +Brief compacto: + +- **Persona / contexto:** CG/assessor no celular, **fora** do Início — após **B73** a bottom nav some; o ritual de ação+busca só existia no Início; nas outras páginas sobra só o sidebar fechado. +- **Job principal:** ter ações rápidas do contexto da página + a mesma busca global do Início, sem escurecer nem bloquear a página atrás; poder recolher/expandir o drawer para ver mais conteúdo. +- **Estratégia de cor:** Restrained — superfície de chrome (fundo campaign), não modal dramático. +- **Edit where you see:** não neste item — launchers; escrita nos wizards/listas. +- **Anti-goals:** overlay que muda opacidade/`pointer-events` da página; segunda bottom nav de destinos de domínio; FAB flutuante; drawer no Início (já tem dock B65); drawer em `/campanha/acoes/*` (ritual B59/B75); reinventar busca (reusar B47+). + +## Dados → decisão → apresentação + +Dados: N/A — chrome de navegação/ação; hits da busca = providers B48+ já existentes. + +## Contexto + +Decisão de produto (2026-07-30): com a remoção da bottom nav (**B73**), a navegação mobile frequente fica no Início (ações + busca) e no sidebar (Sheet fechado por padrão, B38 ✓). Nas **demais** páginas falta um atalho de intenção. Solução: **bottom drawer** sempre montado no viewport <`md` (desktop: fora — sidebar + chrome amplo bastam _(assumido)_), com: + +1. Strip/catálogo de ações **contextualizadas** pela página atual (catálogos = **B80–B90**). +2. Barra de busca com o **mesmo escopo global** do Início (`POST /campanha/home-search`, providers B48–B55). +3. Gesto: arrastar para cima/baixo para expandir/recolher; tap na borda/handle superior também alterna. + +O `Drawer` shadcn/base-ui já expõe `modal={false}` (não renderiza `DrawerOverlay`) e `snapPoints` — profundidade certa; não inventar segundo sheet. + +## Objetivos + +- Componente shell (ex. `CampaignQuickActionsDrawer`) montado no layout `(app)` **só** quando: viewport mobile, actor staff (ou leader nas rotas que o plano B89 pedir), pathname **não** é Início exato e **não** está sob `/campanha/acoes`. +- **Não-modal:** página atrás permanece 100% opaca, scrollável e interativa; o drawer **ocupa** faixa inferior (layout shift / padding do scroll) em vez de cobrir com scrim. +- Snap points mínimos: **collapsed** (handle + talvez 1 linha de peek) e **expanded** (ações + busca); drag e tap no handle/borda superior alternam. Persistência de snap na sessão _(recomendado: `sessionStorage`)_ — Adiado se estourar appetite. +- Slot `actions` (lista já resolvida com `href`s) + slot/região de busca reusando `CampaignHomeSearch` / `HomeSearchContext` / results shell — extrair o necessário para não acoplar ao `CampaignHomeLayout`. +- Contrato de contexto client-safe (ex. `CampaignQuickActionContext`: `municipalitySlug?`, `leadershipId?`, …) + helper que resolve `href` via `wizardActionHref` / atalhos de lista — **B80+** só preenchem o contexto e o catálogo. +- Ajuste de padding do `campaign-content-scroll` para a altura do peek (substitui o antigo `pb-24` da bottom nav após B73). +- Guardrails: sem migration, sem collection, sem Consent, sem server action nova de escrita; leader lockdown respeitado (sem omnibox estadual no drawer staff). + +## Decisões travadas + +- **Drawer não-modal (`modal={false}`), nunca scrim.** Pedido explícito 2026-07-30: não mudar opacidade/visibilidade/interatividade da página. **Rejeitado:** `modal={true}` (padrão do kit); Sheet full-screen; dim `bg-black/10`. +- **Fora do Início e fora de `/acoes/*`.** Início já tem dock; wizard tem chrome próprio (B75). **Rejeitado:** unificar Início no mesmo drawer (dois docks); drawer dentro do wizard. +- **Só mobile (<`md`).** Desktop/tablet mantêm sidebar + busca do Início quando o usuário volta. **Rejeitado:** drawer em `md+` (ruído; compete com sidebar). +- **Catálogo por página = itens B80–B90**, não hardcode no chassis. O chassis só renderiza o que a rota fornece (via registry pathname→provider ou prop do layout segment). **Rejeitado:** um único catálogo global idêntico ao Início em toda rota (perde o prefill). +- **Busca = mesmo contrato do Início** (`home-search`, debounce, modo focado **dentro do drawer expandido**). **Rejeitado:** segunda API; command palette desktop neste item. +- **i18n:** ids `CampaignQuickActionsDrawer`, `quickActionContext`, `snap`; copy pt-BR (“Buscar na campanha”, aria do handle “Mostrar ações rápidas” / “Ocultar…”). + +## Questões em aberto + +- **Mount: layout `(app)` com registry vs. slot por `layout.tsx` de cada área?** **Opções:** A) registry central pathname→catalog no `(app)/layout` | B) cada área exporta `quickActions` via parallel route/slot. **Recomendação:** **A** — um mount, B80+ só registram; B se o registry virar switch gigante. _(assumido)_ +- **Peek inicial: collapsed ou expanded?** **Opções:** A) collapsed (mais conteúdo) | B) expanded (ações à mão). **Recomendação:** **A** no 1º paint; expandir no tap/drag — campo precisa ver a lista. _(assumido — critique com device)_ +- **Leader: drawer só em Contatos (B89) ou também se navegar a outras rotas?** **Opções:** A) só rotas leader | B) esconder sempre fora de Contatos. **Recomendação:** **A** — `getCampaignNav` leader já é mínimo. + +## Abordagem proposta + +```mermaid +flowchart TB + layout["(app)/layout.tsx mobile"] --> gate{"pathname Início ou acoes?"} + gate -->|sim| skip["sem drawer"] + gate -->|não| drawer["CampaignQuickActionsDrawer modal=false"] + drawer --> handle["handle + snap"] + drawer --> actions["ações do registry B80+"] + drawer --> search["HomeSearch* reusado"] + actions --> wizards["wizardActionHref + context"] + search --> api["POST /campanha/home-search"] +``` + +Componentes: + +- **`CampaignQuickActionsDrawer`** (`src/components/campaign/shell/`): `Drawer` `modal={false}` + `snapPoints` + `showSwipeHandle`; região de ações (reuso visual de `CampaignHomeActionStrip` / botões B44 se couberem no peek) + busca. +- **`campaignQuickActionRegistry` / `resolveQuickActionsForPath`** (`src/lib/` client-safe): pathname + role + context → `ResolvedCampaignHomeAction[]` (ou tipo irmão). Contextos ricos entram pelos planos B80+. +- **Extrair busca do acoplamento ao Início** o mínimo necessário (`HomeSearchProvider` montável fora de `CampaignHomeStaffChrome`) — depth check: não duplicar debounce/contrato. +- **`(app)/layout.tsx`**: mount condicional; padding inferior do scroll = altura do peek. +- **Migration:** Sem migration, sem collection, sem server action de escrita. + +## Dependências + +- Dura: **B73** (remover bottom nav — senão dois chromes inferiores). Soft: **B47 ✓**/B48+ (busca); **B45 ✓**/B44 ✓ (strip/botão); **B60 ✓** (`wizardActionHref` + `?municipio=`). +- Desbloqueia **B80–B90**. + +## Não escopo + +- Catálogos e prefills por vertical → **B80–B90**. +- Novos wizards / novas actions de escrita. +- Desktop omnibox global. +- Quadro: **fora do inventário** (decisão de produto 2026-07-30). + +## Rabbit holes + +- **State machine de snap sincronizada com teclado virtual / visualViewport.** **Mitigação:** v1 = CSS snap + padding fixo; medir iOS no craft; Adiado com gatilho se o teclado cobrir a busca. +- **Reimplementar Drawer do zero.** **Mitigação:** `modal={false}` + snapPoints do kit. +- **Levantar strip do Início para shared sem medir bundle.** **Mitigação:** reusar botão; extrair strip só se o JSX divergir <~20 linhas. + +## Adiado com gatilho + +- **Persistir snap expanded/collapsed entre navegações.** Revisitar se o CG reclamar de reabrir o drawer a cada rota. +- **Peek com 1–2 ações favoritas sem expandir.** Revisitar após 1 semana de uso do collapsed-only. + +## Referências + +- `docs/roadmap.md` (UX-1, B73, B79–B90) +- `src/components/ui/Drawer.tsx` — `modal={false}` sem overlay +- `src/lib/campaignActionRoutes.ts` — `wizardActionHref` +- `src/lib/campaignHomeActions.ts` + `CampaignHomeActionStrip` / `CampaignHomeSearch` +- `src/app/(campaign)/campanha/(app)/layout.tsx` — scroll + chrome +- [remover-bottom-nav-mobile.md](remover-bottom-nav-mobile.md) · [fluxos-acao-primeiro-inicio.md](fluxos-acao-primeiro-inicio.md) +- `PRODUCT.md` / `DESIGN.md` — Field Desk mobile diff --git a/docs/roadmap.md b/docs/roadmap.md index ad42ac30..28ee603d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap — Teqo -Atualizado em: 2026-07-30 — **B78** pending de navegação no wizard (dim + shimmer header pós-B75); **B77** simplificar wizard ajuste votos (3 cenários numa tela); ~~**B76**~~ ✓ coerência wizard ajuste votos; **B74** gap strip v2; **B75** header mobile do wizard; **B73** remover bottom nav; ~~**B66**~~ ✓ busca no focus; ~~**B71**~~ ✓ polish busca; ~~**B61**~~ ✓; ~~**B51**~~ ✓; ~~**B52**~~ ✓; ~~**B72**~~ ✓; ~~**B69**~~ ✓ liderança exclusiva (org fica); **B70** A4 liderança; ~~**B62**~~ ✓ simplificar sinal (E11 triage 1 por presença); ~~**B56**~~ ✓; ~~**B67**~~ ✓; ~~**B68**~~ ✓; ~~**B59**~~ ✓; ~~**B65**~~ ✓; ~~**B60**~~ ✓; ~~**B48**~~ ✓; ~~**B49**~~ ✓; ~~**B50**~~ ✓; B53–B55; wizards ~~B60~~ ✓/~~**B61**~~ ✓/~~**B76**~~ ✓/**B77**/B63–B64/**B78**. +Atualizado em: 2026-07-30 — **B79–B90** bottom drawer de ações rápidas + busca (chassis + catálogos por vertical; sem Quadro; lote não cortável); **B78** pending nav wizard; **B77** simplificar ajuste votos; **B74** gap strip v2; **B75** header wizard; **B73** remover bottom nav; ~~B76/B66/B71/B69/B62/B56/B67/B68/B59/B65/B60/B48–B52/B72~~ ✓; B53–B55; wizards B63/B64/B70/B77/B78. 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) → **B74** (gap strip v2) → **B73** (remover bottom nav mobile) → ~~**B50**~~ ✓ → ~~**B51**~~ ✓ → ~~**B52**~~ ✓ → **B53–B55** · ~~**B56**~~ ✓ · **B57** futuro. **Wizards:** ~~**B59**~~ ✓ → **B75** (header mobile wizard) → **B78** (pending navegação shell) → ~~**B60**~~ ✓/~~**B61**~~ ✓/~~**B76**~~ ✓ → **B77** (ajuste votos numa tela) /**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) → **B79** (bottom drawer ações+busca fora do Início) → **B80–B90** (catálogos por vertical; Quadro fora) → ~~**B50**~~ ✓ → ~~**B51**~~ ✓ → ~~**B52**~~ ✓ → **B53–B55** · ~~**B56**~~ ✓ · **B57** futuro. **Wizards:** ~~**B59**~~ ✓ → **B75** (header mobile wizard) → **B78** (pending navegação shell) → ~~**B60**~~ ✓/~~**B61**~~ ✓/~~**B76**~~ ✓ → **B77** (ajuste votos numa tela) /**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) @@ -107,10 +107,22 @@ 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 `