# Campaigns — dormant group (light pass)

WhatsApp number is Meta-disabled; this scope is asleep. Verdict + top 3 issues
only, no fork questions (nothing here needs an operator call before the scope
wakes — the redesign happens as part of that wake-up work).

Legacy marker counts (LEGACY_BASELINE, `conformance.test.ts`): Campaigns.tsx 82,
CampaignDetail.tsx 90, CampaignBuilder.tsx 19, CampaignNew.tsx 3,
CsvBroadcast.tsx 24, QrCampaigns.tsx 12. **Total 230** across 6 files — the
single largest legacy pocket in the app.

## Campaigns.tsx (list + QR tab)

**VERDICT: redesign.** Every visual is inline `React.CSSProperties` consts on
`var(--navy)`/`var(--gold-2)` — the ruled-dead palette — not `--cm-*` tokens;
82 markers is the debt to pay down.

Top 3:
1. Navy/gold throughout (tab underline, chips, QR card accents, `#fff` card
   background) — directly contradicts the navy/gold-is-dead ruling.
2. 5-way tab model (All/Broadcast/API/Scheduled + separate QR tab that swaps
   the whole body for a card grid) is a lot of concept for a first-time user;
   QR being a structurally different shape wedged into the same tab row is a
   fork the redesign should resolve, not preserve.
3. Bulk toolbar, archive toggle, CSV report download, and per-row checkboxes
   are all hand-rolled `<input type="checkbox">` / inline-styled buttons with
   no shared list-toolbar component — pure legacy scaffolding.

## CampaignBuilder.tsx

**VERDICT: redesign.** 19 markers, but the ones present are structural
(builder layout, audience box, cost line) not cosmetic sprinkle — a token
pass alone won't fix it.

Top 3:
1. `audienceBox`/`audienceBoxEmpty`/`estCostLine` etc. are all local
   `var(--navy-soft)` / `var(--warn-soft)` inline objects, not tokenized
   components — same off-palette issue as the list screen.
2. Raw `<select>` for template and segment with no search/filter — fine at
   today's volume, will not scale, and isn't the shared headless picker the
   design-token plan calls for.
3. Blocking-reason text is a single string cycling through 6 possible
   messages inline in the submit row — functional but easy to miss (small,
   low-contrast hint), worth a real inline-validation pattern.

## CampaignDetail.tsx

**VERDICT: redesign.** Highest debt in the group at 90 markers; the file is
844 lines holding KPI cards, recipient table, tag editor, lifecycle buttons,
API access panel, and two confirm dialogs all in one screen.

Top 3:
1. Navy/gold on every KPI card, chip, and tab underline (`kpiLabel`,
   `apiPanelTitle`, `archivedChip`, etc.) — the largest single concentration
   of the dead palette in the codebase.
2. `ApiAccessPanel` renders a raw curl command and `X-Api-Key` header text
   directly in product UI — engineering vocabulary the copy ruling asks to
   avoid; this needs a design decision (keep as dev-facing docs panel vs.
   move it into `docs/api`-style content).
3. Screen holds 6+ concerns at once (status/lifecycle, KPIs, tags, template
   preview, recipient table + search + export, API panel) with no visual
   hierarchy beyond stacked sections — a first-time read is a lot to hold.

## CampaignNew.tsx

**VERDICT: polish.** Only 3 markers — a thin tab-switching shell around the
other four builders, so it inherits their debt rather than adding its own.

Top 3:
1. `so-pill`/`so-pill-active` tab buttons for Broadcast/CSV/QR/API — fine as
   a pattern, just confirm it matches whatever tab component the redesign
   standardizes on elsewhere (Campaigns.tsx uses a different tab-bar style).
2. No visible affordance that arriving via `?contactIds=` silently forces the
   CSV tab and hides the other three — works, but is invisible state.
3. Trivial file; carries none of its own visual debt to fix.

## CsvBroadcast.tsx

**VERDICT: redesign.** 24 markers, plus the densest raw-form-control count in
the group: name input, template select, CSV file input, CSV textarea, and a
per-column mapping `<select>` repeated per header — five-plus raw controls
with no shared form system.

Top 3:
1. Navy/gold + off-token hex (`#FCFBF6` table header background) mixed with
   `var(--green)`/`var(--red)` inline validation text.
2. Column-mapping table is a hand-built `<table>` with a `<select>` per row —
   the single most "engineering tool" feeling surface in the group (raw CSV
   paste, WhatsApp-id column detection, per-cell dropdown).
3. Two divergent audience UIs in one file (from-contacts list vs. CSV
   upload/paste) sharing one blocking-reason string — works, but doubles the
   concepts a first-time operator must parse.

## QrCampaigns.tsx (`NewQrForm`)

**VERDICT: polish.** Smallest file in the group (12 markers) and already the
simplest form — one card of fields, one preview rail.

Top 3:
1. Hardcoded `#E7F6E1` WhatsApp-green bubble background — off-token hex, easy
   token-pass fix.
2. Raw checkbox for "Send a follow-up template" with inline `accentColor`
   instead of a token-styled control.
3. Submit is disabled behind a compound condition
   (`!applyTag && (!useTemplate || !template)`) with no inline explanation of
   *why* — same missing-affordance pattern as the other builders.
