Same tokens as the app (Inter · primary hsl(221 83% 53%) · slate-900 nav · real Button/Badge/Sheet). This is the comp we agreed on before implementation — the build shipped a drifted version. Each pin marks where the shipped UI broke from this and how the comp restores it. Sample filter throughout: CA/TX licensed · Life · (email “agency” OR has phone) → 12,431.
Left rail gone → full-width table. One toolbar row, “Edit filters” the clear primary. Applied filters read as removable field · value chips you can actually read.
Source-aware field picker, an ALL/ANY tree with single-line conditions and inline NOT, a plain-language preview and the live match count beside Apply. Opens seeded with what’s applied — never empty.
Clicking Add a filter opens a searchable, categorized list. Multi-source fields are tagged multi; inferred fields labelled inferred; gap fields show how many agents have no value (n/a · 572k) so you’re never silently misled. Data source lists all 16 (the shipped build showed ~3), and the new area-code → state field is parked here for Phase B.
inferred / n/a · count tags, area-code→state.--primary blue, slate neutrals, semantic accents.filter-sidebar + advanced-filter-drawer + base-filter-summary.The “shipped” side is the live build recreated in the same tokens, so the contrast is apples-to-apples.
The full record so nothing is lost. In comp = shown above · Build-time = implement during the build (state / motion / cleanup) · Out of drawer = agents-page / table / global, tracked separately.
| Pin | Area | Finding (shipped build) | Status |
|---|---|---|---|
| 5 | Correctness | Drawer opened empty — silently dropped the applied filter (P0 data loss) | In comp |
| 1 | Filter bar | Edit / Add filters were the faintest things on the page, split across two ghost rows | In comp |
| 2 | Filter bar | Chips truncated mid-word; verbose “is any of …”, lowercased values | In comp |
| 3 | Filter bar | Active preset name truncated; “Save Preset / Presets” split from filtering | In comp |
| 1 | Filter bar | Fragile wrapping — “Edit filters” orphaned onto its own row | In comp |
| — | Filter bar | “Clear all” shown at rest with nothing to clear | Build-time |
| 4 | Drawer footer | Actions clustered far-right; “Filter breakdown” heavier than Apply; Clear flush to Apply (misclick) | In comp |
| 4 | Drawer header | Live count collided with the ✕; showed unfiltered 1.6M, not the draft | In comp |
| 9 | Drawer footer | Plain-language preview not reliably surfaced | In comp |
| §6 | Drawer footer | Apply stayed enabled in the empty / invalid state | Build-time |
| 6 | Conditions | New rows defaulted to “Email contains” → byte-identical stub rows | In comp |
| 7 | Conditions | Floating “NOT” pill on its own line above every row | In comp |
| 7 | Conditions | Two undifferentiated “NOT”s — per-condition vs “NOT group” | In comp |
| 8 | Groups | Header crammed ALL · ANY · (AND); redundant; weak toggle states | In comp |
| — | Conditions | Three inconsistent “add” affordances (condition / OR group / group) | In comp |
| 8 | Groups | OR divider too weak for a load-bearing operator | In comp |
| B/A | Conditions | Malformed placeholder “@agency, gmail.com” | In comp |
| 10 | Field picker | Dropdown overlapped condition rows, weak separation | In comp |
| — | Field picker | Permanent blue focus-ring even when unfocused | Build-time |
| 10 | Fields / data | Data Source showed ~3 of 16; gap fields gave no source signal | In comp |
| 11 | System | Palette mishmash — indigo / rose / amber / emerald / violet hardcoded | In comp |
| — | System | 10–12px micro-typography legibility throughout the builder | Build-time |
| 12 | Code | ~1,235 lines of dead filter code shipped to prod (3 files) | In comp |
| — | Code | Unused Badge import in active-filters-bar | Build-time |
| §6 | Motion | Origin-aware popovers · press feedback · real disabled/loading states · <300ms easing · reduced-motion | Build-time |
| — | Table | Carrier “Unknown” loud solid pill, inconsistent with Cell / VoIP / N-V | Out of drawer |
| — | Presets popover | Every row tagged “Shared” while the Mine tab is active — redundant | Out of drawer |
| — | Presets popover | Low-contrast metadata; descriptions truncate mid-sentence | Out of drawer |
| — | Presets popover | “AI suggestions” row clipped at the popover’s bottom edge | Out of drawer |
| — | Global header | Bell badges “99+” / “9+” crowd and overlap their icons | Out of drawer |
| — | Table | Email column truncates mid-address, hiding the domain | Out of drawer |
A static comp can’t render motion; these are required at build time, per the emil review.
The field picker & value popovers scale from their trigger (Radix transform-origin), not from center.
scale(.97) on Apply, chips and pressable rows — instant “it heard me”, ~120–160ms ease-out.
Apply disabled until the draft differs & is valid; count shows “Counting…”; option lists show a loading row.
Drawer ~240ms ease-drawer; popovers ~160ms ease-out; everything <300ms; honor prefers-reduced-motion.