UX Spec — Securities Anomalies (search-ui)
This is the design-and-interaction reference for the fraud-heuristics front end
(search-ui/, the public Securities Anomalies site at
sec.atsignhandle.xyz). It defines tokens, layout,
popups, controls, badges, charts, search, information hierarchy, and responsive
behavior so new pages and popups stay visually consistent.
Relationship to the primary spec
The federation primary UX spec is gpumon —
gpu.atsignhandle.xyz/ux-spec. That document
governs the pastel-brutalist instrument-panel look (2px #1a1a1a borders, mono
body, popup/overlay anatomy, badge-fill map, chart primitives) for the whole
federation. When you build a new control or popup, follow the gpumon spec
first.
This search-ui spec is the data-density extension of the primary spec — the same family gpumon documents under its "Postcrime Extension" section. Where gpumon is sparse telemetry cards, search-ui is dense corpus search, document reading, filtering, and expanded stats/charts. Concretely:
- Borrow from gpumon (unchanged): monospace body, hard 2px borders on primary surfaces, pastel accent semantics, FA-thin icons, dismiss-on-scrim/X/Escape modal behavior, no emojis.
- search-ui adds: a softer
#d0d0d0hairline border for dense tables, a serif display face (Playfair) for headings/landing, dark-mode, FTS5 search, document reading surfaces, and the 12-column stats grid.
If a control is not covered by the gpumon primary spec, it is defined here.
Design tokens — "Parque Towers" system
Defined in search-ui/src/app.css :root (dark-mode under [data-theme='dark']).
Base
| Token | Value | Role |
|---|---|---|
--bg |
#fafafa |
page background |
--bg-alt |
#f0f0f0 |
alternate / sunken surface |
--fg |
#1a1a1a |
ink |
--fg-muted |
#666 |
secondary text |
--border |
#d0d0d0 |
hairline (dense tables, cards) |
--border-light |
#e8e8e8 |
faint separators |
--accent |
#4a90d9 |
links, active state |
--accent-hover |
#3a7bc8 |
link hover |
Typography
| Token | Stack | Use |
|---|---|---|
--font-mono |
JetBrains Mono, Fira Code, SF Mono, ui-monospace | body (default), data, tables |
--font-serif |
Playfair Display, Georgia, serif | landing display headings |
--font-sans |
Inter, system-ui | optional prose |
html { zoom: 0.9 },font-size: 16px, antialiased.body { font-family: var(--font-mono); line-height: 1.6 }.- Headings: mono, weight 700,
line-height: 1.2,letter-spacing: -0.02em. - Layout:
--max-width: 1200px,--header-height: 60px,--transition: 150ms ease.
Category / source colors (pure pastel, distinct hues)
| Token | Hex | Source |
|---|---|---|
--cat-doj |
#8B6FBF |
DOJ SDNY (lavender-deep) |
--cat-sec-pr |
#6FA8D6 |
SEC Press Releases (sky-deep) |
--cat-sec-lr |
#C77FA8 |
SEC Litigation Releases (rose-deep) |
Neo-brutalist pastel palette (stats, badges)
--pastel-pink #FFB3D1, --pastel-mint #A8E6CF, --pastel-lemon #FFE787,
--pastel-peach #FFCBA4, --pastel-lavender #C7B4E8, --pastel-sky #A4D4F2,
--pastel-coral #FFB5A7, --pastel-lime #D4F1A8; --brutal-border #1a1a1a,
--brutal-shadow 3px 3px 0 #1a1a1a.
Stats card pairs (bg / border)
| Card | Background | Border |
|---|---|---|
| mint | #f0fff4 |
#2d8a56 |
| sky | #f0f4ff |
#4a72b0 |
| cream | #fffbf0 |
#b08a4a |
| rose | #fff0f0 |
#d4686a |
Layout
- Shell:
+layout.svelteprovides a sticky header (--header-height) carrying the brand, primary nav,SearchInput, andNavSettings. Content centers within--max-width: 1200px. - Routes (
search-ui/src/routes/):/(landing),/[source],/anomalies,/anomalies/[source],/scheme,/scheme/[slug],/statutes,/statutes/[slug],/progress,/doc/[id],/stats. Server data via+page.server.ts; JSON under/api/*and/stats/api/*. - Doc detail (
/doc/[id]) is a split-pane: metadata/statute/party rail beside thePDFViewer(range-streamed PDF).
Popups and overlays
Follow the gpumon popup anatomy. search-ui instantiates three:
| Popup | Component | Type | Anatomy |
|---|---|---|---|
| Settings / health | NavSettings.svelte |
anchored dropdown | opens from the gear; health chips poll /api/health-summary; theme toggle |
| Metadata popover | MetaPopup.svelte |
anchored popover | hover/click a row field; small, borderless-X dismiss |
| Document preview | DocumentPreview.svelte |
full overlay modal | scrim rgba(26,26,26,0.45); centered panel min(1100px, 96vw); sticky head with borderless ×; dismiss on scrim / × / Escape |
- Default state: all closed. Dropdowns open on click, not hover.
- Modal panel uses the hard 2px
#1a1a1aborder (gpumon rule), not the#d0d0d0table hairline. - Mobile (≤720px): anchored dropdowns become full-width sheets; the preview
modal goes near-fullscreen (
96vw, generous vertical padding).
Controls and default states
| Control | Component | Default | Notes |
|---|---|---|---|
| Search box | SearchInput.svelte |
empty, idle | FTS5; fires at 3+ chars, POST /api/search |
| Filter badges | FilterBadges.svelte |
all off (no filter) | toggle source / scheme / statute pills |
| Nav settings | NavSettings.svelte |
closed | gear → health chips, theme, links |
| Source tree | AgencyTreePage.svelte |
collapsed | expand an agency to list sources |
| Theme | [data-theme] |
light | dark-mode tokens swap under [data-theme='dark'] |
| Progress controls | /progress |
live poll | restart / prune / replay call /api/progress/* |
Badges and pills
Badge.svelte— source/category chip; fill from the--cat-*source colors (DOJ lavender, SEC-PR sky, SEC-LR rose) or the pastel palette for stats.StatusChip.svelte— health/state chip (ok / warn / error), pastel fill, dark ink, used inNavSettingshealth row and/progress.FilterBadges— toggle pills; off = outline, on = filled accent.- Section titles: mono, uppercase, letter-spaced,
--fg-muted— same treatment as gpumon sidenav headings.
Charts (src/lib/charts/)
D3 + SVG, sharing d3-helpers.ts / gpumon-types.ts. These are the expanded
stats/chart reference the gpumon spec points back to.
| Component | Kind | Used by |
|---|---|---|
gpumon-trend.svelte |
line trend | time series |
gpumon-barlist.svelte |
horizontal bar list | top-N breakdowns |
gpumon-heatmap.svelte |
heat grid | density |
progress-sparkline.svelte |
inline sparkline | /progress, rows |
calendar-filings.svelte |
calendar heat | filings over time |
force-entities.svelte |
force graph | entity co-occurrence |
force-cross-corpus.svelte |
force graph | cross-corpus links |
sankey-scheme-outcome.svelte |
Sankey | scheme → outcome flow |
pack-scheme-amount.svelte |
circle pack | scheme $ amounts |
- Stroke/fill semantics inherit the gpumon palette; pastel fills for categorical
series,
--accentfor the primary measure. - Charts are render-only (no ax; sparklines especially) when embedded in rows.
Search
- Endpoint: POST
/api/search(SQLite FTS5 over the corpus). - Trigger: 3+ characters in
SearchInput. - Results:
DocumentTableofDocumentRows; each row opensDocumentPreviewor links to/doc/[id]. - Refinement:
FilterBadgesnarrow by source / scheme / statute without re-querying text.
Information hierarchy
- Search / filter (header) — entry point to the corpus.
- Result table (
DocumentTable) — scannable rows, source/statute badges. - Preview (
DocumentPreviewmodal) — quick look without leaving results. - Document detail (
/doc/[id]) — full split-pane read + metadata + PDF. - Aggregate views —
/anomalies,/scheme,/statutesgroup the corpus;/statsis the cross-corpus analytic layer;/progressis operational.
Stats page grid
- 12-column responsive grid: full = 12, half = 6, third = 4.
- Cards use the mint / sky / cream / rose pairs above with the brutal border.
- Coverage bars collapse 2-col → 1-col on narrow screens.
Responsive breakpoints
Data-density layouts (this site) use more breakpoints than gpumon telemetry:
- 960px — drop to single content column; stats grid reflows.
- 900px — coverage / 2-up panels collapse to 1-up.
- 768px — header condenses; nav + search stack; dropdowns → sheets.
- 640px — table-dense views switch to stacked cards; honor orientation.
(For reference, gpumon's telemetry breakpoints are 1100 / 720 / 560.)
Rendering and serving
This page is rendered by search-ui/tools/render-docs.ts into
search-ui/static/docs/ux-spec.html and served from the /docs site (sidenav is
auto-built from docs/application/*.md). It follows the locked gpumon /docs
style (see global CLAUDE.md "Documentation site style guide").