# Analytics — Phase 0 dossier

Group: analytics. Files: `routes/Analytics.tsx` (539 ln), `routes/AnalyticsAgentOutcomes.tsx`
(211 ln), `routes/analytics-shared.tsx` (139 ln), `routes/analytics.css` (285 ln).
Reached from the left nav's single "Analytics" entry (`AppShell.tsx:124`, `minRole: viewer`) →
`/analytics`. One in-page drill link ("Open the full automation-rate view ›") →
`/analytics/agent-outcomes`. Two routes total; no other entry points.

Operator verdict already on record as "confusing." This inventory explains *why*,
mechanically, ahead of the definition round he owns.

## Legacy-marker / token debt (measured, not eyeballed)

`Analytics.tsx` is **not in `LEGACY_BASELINE`** — it is already swept, zero violations
required and zero found. The rest carries the lightest debt of any group likely in this
sweep:

| file | markers | what they are |
|---|---|---|
| `analytics.css` | 9 | 6× raw hex (`#fff`, `#bfe3cd`×2, `#e6cfa0`, `#e7c4c4`) on border/text colors that have no `--cm-*` equivalent yet; 3× off-scale `font-size` (44px hero ×2, 22px KPI) — the hero/KPI sizes aren't on the tokens.md type scale |
| `analytics-shared.tsx` | 3 | raw hex for the IG/FB/WhatsApp brand dots (`channelDot()`) — brand colors with no token, not stray legacy debt |
| `AnalyticsAgentOutcomes.tsx` | 1 | inline `fontSize: 34` on the labels-count headline — a fourth off-scale hero size, duplicating the CSS-side 44/22 problem |

Raw `<input>`/`<select>`/`<textarea>` count: **0**. All filtering is a segmented
button group (`role="group"`, `aria-pressed`), URL-backed. This is the cleanest
group in the sweep on tokens/markup — the "confusing" verdict is an IA/content
problem, not a legacy-styling one.

## Analytics.tsx (landing) — five report blocks on one scroll

- **IA/concept count — high.** One screen stacks five independently-idiomed report
  blocks (Volume, Outcomes, Campaigns, Delivery, Cost), each with its own hero
  figure, sublist, and a *different* visualization: horizontal channel bars,
  a hover-driven per-day column chart, a three-way stacked split bar with its own
  legend, a Meta-state chip + failure-reason list, and a second horizontal-bar set
  for spend. A first-time reader must learn five chart idioms in one pass, plus a
  sixth micro-concept (the live/thin/empty `AvailTag`) repeated per block. This is
  the mechanical root of "confusing."
- **Interaction** — the per-day chart (`DailyBars`) only updates its readout on
  mouse hover; the columns are plain `div`s with no `tabIndex`, so keyboard users
  cannot reach any day but the auto-selected peak (a native `title` sits on the
  same unfocusable element, so it never surfaces either). Only 1 of 5 blocks
  (Outcomes) has a drill-through; the other four render as dead ends with no
  affordance signaling "this is everything" vs. "there's more."
- **Content/copy** — plain and honest overall ("Handled without a human",
  "Thin on purpose" pattern lives in the drill, "not yet attributable" here).
  No engineering vocabulary, no AI-isms. `n/a` for automation rate is the one
  terse outlier next to otherwise-full sentences.
- **Visual/tokens** — near-fully on-token; see debt table above (9 css markers,
  all either an un-tokened hex or an off-scale hero/KPI size — a token-sheet gap,
  not sloppy authorship).
- **A11y + responsive** — segmented controls are correctly labelled
  (`role="group"`, `aria-pressed`). Two breakpoints (768/640) stack the
  answer/detail split and the two-column KPI rows; not verified at 320px.
  Color-only signal in two spots: the outcomes split bar's narrow segments
  render no text (`{a.split.queued || ""}`) and rely on a hover `title` only;
  the delivery state dot is color-only next to text that does restate the state,
  so that one is backed up.

**VERDICT: redesign.** The concept-per-scroll density (five distinct chart idioms
+ a repeated triage-tag micro-concept) is the load-bearing cause of "confusing";
a token/polish pass would not fix it. Needs the operator's definition round first.

## AnalyticsAgentOutcomes.tsx (drill) — single focused screen

- **IA/concept count — low.** Four concepts, each in its own card: automation-rate
  headline, per-situation table, silence reasons, review-queue/labels. Reads as a
  standard drill page, not confusing on its own.
- **Interaction** — a plain breadcrumb Link back to Analytics (carries the current
  query string, so filters survive the round trip — good). No dead ends; the table
  and reason bars are static, not interactive, so no keyboard-hover gap like the
  landing page's `DailyBars`.
- **Content/copy** — clear: "Handled autonomously means it replied or acted
  without a human…" spelled out in the subtitle. "Thin on purpose" is an honest,
  plain label for the labels panel.
- **Visual/tokens** — 1 marker only (the `fontSize: 34` headline, matching the
  landing page's 44/22px pattern — same root cause, not a separate defect).
- **A11y + responsive** — table has proper `<th>`/scope-free headers (no
  `scope` attr set, minor); `.an-two` two-column layout collapses to one column
  at 640px. Split-bar segments here are color-only with no text fallback at all
  (unlike the landing block, which at least text-labels wide segments).

**VERDICT: polish.** Structure and copy are already the model to imitate; needs
the shared 44/22/34px hero-size problem folded into a token, and the split-bar
color-only gap closed with `title`/legend-adjacent text.

## analytics-shared.tsx — control/format/icon helpers

Not a screen; supplies both routes. `channelDot()` holds the 3 hex markers
(brand colors, arguably legitimate — IG/FB/WhatsApp have fixed brand hues with
no `--cm-*` slot). Everything else (`readControls`/`writeControls`/`describeRange`/
`fmtUsd`/`AvailTag`/`QIcon`) is plain, well-isolated, and already reused
identically by both screens — good factoring, nothing to flag.

**VERDICT: keep.** If the landing page gets redesigned, this file's helpers
(URL-backed controls, `AvailTag`, date/currency formatters) are the reusable
substrate to carry forward regardless of what the blocks end up looking like.

## Forks (operator-only)

1. **Five blocks, one scroll vs. five surfaces.** Landing stacks all five report
   blocks on one page; only Outcomes has a drill page. Does "fix confusing" mean
   giving Campaigns/Delivery/Cost their own drill pages too (Outcomes' pattern
   becomes the norm), or collapsing to fewer/simpler blocks on one page instead?
   *Recommendation: drill pages per block, landing becomes a summary/nav layer —
   matches the one-concept-per-surface rule better than five chart idioms stacked.*
2. **Hero/KPI type scale.** Three sizes (44px hero, 22px KPI, 34px drill headline)
   sit outside tokens.md's scale and don't even agree with each other. Add
   `--cm-fs-hero`/`--cm-fs-kpi` tokens to the sheet, or fold heroes onto an
   existing large token (`--cm-fs-lg`-class)? *Recommendation: two new tokens —
   hero and KPI figures are a real, recurring size class, not one-offs.*
3. **Brand channel colors.** `channelDot()`'s three hex values are IG/FB/WhatsApp
   brand colors, not stray legacy debt. Should tokens.md gain a documented
   `--cm-brand-instagram/facebook/whatsapp` trio (removes the marker, keeps intent),
   or is a bare hex the accepted exception for third-party brand marks?
   *Recommendation: token them — three fixed values reused in ≥2 files is exactly
   what the token sheet is for.*
