gpumon — Dashboard Design System

⌂ dashboard

Aesthetic: pastel-brutalist

Instrument-style dashboard. Hard 2px solid #1a1a1a borders everywhere. Pastel fills — never gradients, never translucency. Mono fonts for numbers. No drop shadows except 4px offset on tooltips. The dashboard must read like precision test equipment, not a consumer web app.

Color Palette

Thermal (reserved — DO NOT use outside temperature context)

#c5e1a5
GPU cool
#ffd54f
GPU warm
#ef9a9a
GPU hot
#c62828
critical
#d4ebbf
CPU cool
#ffe082
CPU warm
#f4b3b3
CPU hot

Status

#66bb6a
live
#cccccc
stale
#ffe082
staleness banner
#ef9a9a
down

Neutral Surfaces

#f5f4ee
page bg
#fff
card bg
#f5f4ee
pill bg
#1a1a1a
border / text
#6b6b6b
muted text

Accent (NIM bars + activity fill)

#80deea
cyan (NIM fill)
#66bb6a
success

Vision Pill

#bdbedc
lavender

Shared-key API Key Pastels

#b3e5fc
blue
#80cbc4
teal
#f48fb1
pink
#ce93d8
purple

Project Colors (PROJ_COLOR map)

#bdbedc
claude-mem
#ef9a9a
fraud-processor
#a5d6a7
doc-server
#ffd54f
openwebui
#80deea
claude-proxy
#cccccc
unknown

Host Palette (HOST_PALETTE array, index-stable)

#bdbedc
[0]
#ef9a9a
[1]
#a5d6a7
[2]
#ffd54f
[3]
#80deea
[4]
#d1c4e9
[5]
#f8bbd0
[6]
#c5e1a5
[7]
#ffab91
[8]
#b39ddb
[9]

Typography

ElementFontSizeWeightOther
stat-value--mono16px800font-variant-numeric: tabular-nums
stat-label--mono9px700uppercase, 0.05em letter-spacing
pill--mono10px700
body--mono12px400all chrome is mono — no sans-serif anywhere
all numerics--monovariesfont-variant-numeric: tabular-nums

--mono = ui-monospace, "SF Mono", Menlo, monospace

Layout — Section Order (top to bottom)

  1. Staleness banner (conditional — shown when writer unreachable or samples >5 min old)
  2. GPU host strip (HeatStrip) — one card per GPU host + fleet-total aggregate card
  3. GPU util trend chart (multi-series, one line per active host)
  4. GPU power trend chart (multi-series, one line per active host)
  5. LLM calls per-host trend (multi-series by upstream_host)
  6. LLM calls + latency trends (fleet-wide)
  7. NIM card grid (3+ cards, 340px min-width, always-on — never hidden even when idle)
  8. Projects card (filtered by attributed/unattributed header)
  9. Top models + top callers (BarList)
  10. LiveStream (recent LLM calls)
  11. Desktop footer status bar (≥1100px — shows WAL size, 5xx count, SSE state)

Component Conventions

Card

border: 2px solid #1a1a1a; background: #fff; padding: 10px 12px 8px;
example card content

Pill

border: 2px solid #1a1a1a; padding: 1px 6px; font-weight: 700; font-size: 10px; background: #f5f4ee;
PILL NIM LOCAL CLOUD MIXED

Stat Bar

height: 4px; background: #f5f4ee; border: 1px solid #1a1a1a; fill: background: #80deea;

Tooltip

background: #1a1a1a; color: #f5f4ee; 4px solid box-shadow offset; mono font
host: spark-2
util: 62%

Pulse Bar (NIM activity)

Gradient fill animated on per-call llm SSE event, keyed by last_call_ts. Decays over 60s.

Interaction Rules

BehaviorDetail
Polling interval5s for all /api/* endpoints
SSE/stream for live llm + nvidia-rpm events; auto-reconnects
Per-card pulseOn llm SSE event matching NIM model, optimistic rpm_used increment before next broadcast
RPM window60-second rolling window; timer badge flashes when ≤10s remain
Idle-hideNon-seeded series hidden when no data in window; NIM cards always render (seeded)
Stale dotShown on NIM card when last_call_ts >5 min ago
Boot retryExponential backoff: 0.5s, 1s, 2s, 4s, 8s until first success, then steady 5s

Forbidden

RuleReason
No emojis anywhereUse Font Awesome Pro Thin (fat prefix) icons or text symbols only
No drop shadows except 4px brutalist offset on tooltipsShadows read as consumer UI, not instrument panel
No red/amber/green outside thermalThose hues are reserved for temperature state — using elsewhere creates false urgency
No CDN-loaded resourcesFA Pro bundled locally; no external fonts, scripts, or stylesheets
No gradients on data barsSolid fill only; gradients obscure value at small heights

Popups & Modals

Two interaction surfaces: header dropdowns (anchored, non-modal, no scrim) and full overlays (centred, scrimmed, scroll-locked). Both are mono, 2px ink-bordered, pastel-or-white filled. Default state of every popup is closed; opened only by its trigger; closed by click-outside, by trigger re-click, and (overlays only) by Escape.

Anchored dropdowns (nav-popup / settings-popup)

Propnav-popup (hamburger)settings-popup (gear)
positionabsolute; top: 100%; right: 18px; margin-top: 4pxabsolute; top: 100%; right: 18px; margin-top: 4px
min-width200px240px
surface#fff · 2px solid #1a1a1a · padding 10px 12px 12px#fff · 2px solid #1a1a1a · padding 10px 12px 12px
z-index5050
trigger.hamburger (left).gear (right)
dismissdocument click outside .nav-popup/.hamburger (resp. .settings-popup/.gear); re-click toggles
section titleh3: 9px · 800 · uppercase · letter-spacing 0.08em · #6b6b6b · margin 8px 0 4px (first-child margin-top 0)
row (nav-link)flex · gap 6px · padding 4px 8px · 11px · 2px solid transparent → hover border #1a1a1a + bg #f5f4ee; leading i 10px #6b6b6b width 14px centred

Full overlays (FederationLayout, RoutingPanel, HostPromptModal, ChatPanel)

PartSpec
overlay (.fl-overlay)position: fixed; inset: 0; background: rgba(26,26,26,0.45); display:flex; align-items:flex-start; justify-content:center; padding: 32px 16px; z-index: 60; overflow-y: auto
modal (.fl-modal)background #f5f4ee; 2px solid #1a1a1a; width: min(1100px, 96vw); max-width: 96vw; mono
head (.fl-head)sticky; top: 0; z-index: 2; bg #fff; 2px bottom border; padding 12px 16px; title h2 14px/900 with muted leading icon
close (.fl-x)borderless floating glyph (fa-xmark) — 15px, color #6b6b6b → hover #1a1a1a; NO border, NO box. Reload (.fl-btn) is the same borderless treatment.
dismissclick scrim, click .fl-x, or Escape

Mobile (≤720px)

Header collapses; dropdowns keep their anchor but width tracks viewport. Overlays keep the 16px gutter (padding: 32px 16px) so min(1100px, 96vw) becomes full-bleed-minus-gutter. Card grids inside overlays reflow to one column. Footer status bar (≥1100px only) is hidden.

Controls & Dropdown Default States

ControlDefaultBehaviour
Hamburger menuclosedToggles nav-popup (navigation + docs links). Click-outside closes.
Gear / settingsclosedToggles settings-popup (live status, 24h totals, display toggles, Cache, routing/federation, storage backends, quick links). Click-outside closes.
Display togglesonPer-section show/hide checkboxes inside settings-popup; persisted to localStorage.
Hard RefreshidleCache section: clears Cache Storage + unregisters service workers, reloads with ?_hr= bust. Spinner while running.
Routing / Federationclosedbutton.nav-link (.routing-open) opens the matching overlay; hover bg #f5f4ee, no border-fill.
Refresh glyphidleBorderless fa-arrows-rotate; manual re-fetch on top of the 5s poll.

Buttons styled as nav-link rows must look identical to anchor nav-links (same padding, transparent 2px border, hover fill) — a control never advertises itself as a different species than the link beside it.

Badges & Pill Fill Map

Pills are 2px ink-bordered, 10px/700 mono, ~1px 6px padding. Fill encodes meaning — never decorative. White fill = neutral/identifier (port, address, key-count). Pastel fill = typed value.

Federation pills (.fl-pill)

mem kind ctx best / tier engine vision warn port / addr / keys
ClassFillMeaning
.fl-pill.mem#a5d6a7 greenin-memory / resident
.fl-pill.kind#bdbedc lilacengine kind (llama.cpp / vllm / nim)
.fl-pill.ctx#80deea cyancontext window (white when estimated: .ctx.est)
.fl-pill.best / .tier#ffd54f ambertop-ranked / routing tier
.fl-pill.engine#ffcc80 orangebackend engine label
.fl-pill.nim-vision / vision#bdbedc lilacvision / multimodal capable
.fl-pill.warn#ef9a9a coraldegraded / not serving
.fl-pill.port / .addr / .nim-keys / .hostmem#fff whiteneutral identifier (right-aligned via margin-left:auto for hostmem)

Project pills (PROJ_COLOR)

claude-mem fraud-processor doc-server openwebui claude-proxy unknown

Method badges (docs tables)

GETPOSTPATCHDELETE

Filled-black is reserved for the bare .method default only; typed methods take their pastel.

Charts & Data Viz

ComponentGeometryEncoding
Trendheight 220px, width responsive (ResizeObserver), D3 viewBoxmulti-series lines, stroke-width 1.6, per-series color; axes 1px #1a1a1a; hover crosshair 1.5; idle series hidden
NimSparklineviewBox 280×56 (fills ~50% of card body)single line stroke-width 1.6 solid; NO axes/tooltip — too noisy at this size
HeatStripstacked horizontal bars per GPU host + fleet aggregateUTIL = thermal ramp (#c5e1a5→#ffd54f→#ef9a9a→#c62828); MEM = #d1c4e9; POWER = #80cbc4; label row UPPER/value
BarListlabel (min-width 140px) + tracktrack fill default #bdbedc, overridable per row; value right-aligned tabular-nums
RpmGauge20px tall barfill width = rpm/cap; width+background transition 400ms linear; flashes when ≤10s left in window
RoutingVizSVG class="flow", viewBox responsive, preserveAspectRatio xMidYMinnode rects rx 3, 2px #1a1a1a; source node #ffd54f; connectors #b8b6ad 1.5 with arrow marker; edge labels mono 12px

All viz obeys the palette rules: thermal hues only for temperature/util, solid fills (no gradients on bars), 2px ink borders on boxed nodes. Numbers are mono with tabular-nums.

Postcrime Extension — search, hierarchy & expanded stats

gpumon is the primary spec. For surfaces gpumon does not define — full-text search, dense result tables, document detail/preview, and large multi-tile stats/chart pages — adopt the patterns below from the postcrime "Securities Anomalies" site (postcrime.atsignhandle.xyz, internal name "Parque Towers Design System"). It is the same brutalist DNA tuned for data-density and reading.

Tokens (where they differ from gpumon)

TokenLightNote
--bg#fafafapage (dark mode #121212)
--fg#1a1a1aink
--border#d0d0d0softer than gpumon's #1a1a1a — table/detail rules
--accent#4a90d9 bluelinks, active states, focus ring
--font-serif'Playfair Display', Georgia, serifpage h1 only — editorial masthead
--font-mono'JetBrains Mono', ui-monospaceeverything else
root zoom0.9global density scale

Reconciliation: keep gpumon's hard #1a1a1a 2px borders and all-mono chrome as the default. Borrow postcrime's softer #d0d0d0 rules only inside dense data tables, and the serif strictly for a page masthead h1.

Search

ElementSpec
SearchInputFTS5; fires at 3+ chars; debounced; POST /api/search; mono field, 2px border, accent focus
FilterBadgestoggle pills above results (source / sub-type / statute / scheme); active = filled pastel; multi-select AND
Result tabledense rows, #d0d0d0 1px separators, mono; row tap → document detail

Information hierarchy

  1. Masthead h1 (serif) + NavSettings header (storage-health chips, gear, hamburger)
  2. Search field + filter badges
  3. Result table (dense) / agency tree
  4. Document detail: split PDF-pane / text-pane; caption, statute pills, party pills, scheme pills
  5. Cross-links to /stats, /progress, /scheme, /statutes

NavSettings header chips

Storage-backend health chips (.ns-chip: DB / SeaweedFS) poll /api/health-summary while the gear popup is open; a status .dot goes err (down) / unknown (null); latency shown inline. Same anchored-popup mechanics as gpumon (.ns-nav-popup / .ns-settings-popup, click-outside dismiss).

Document preview modal

Full overlay (same scrim + centred-card pattern as gpumon's .fl-overlay) hosting a streamed PDF (HTTP Range) beside extracted text; statute / party / scheme pills in the header.

Expanded stats / charts (/stats)

This is the reference for any gpumon page that outgrows a single card grid.

AspectSpec
Gridgrid-template-columns: repeat(12, 1fr); tiles span .full=12 / .half=6 / .third=4; collapse all to span 12 at ≤1100px
Tile tintscard-mint #f0fff4/#2d8a56 · card-sky #f0f4ff/#4a72b0 · card-cream #fffbf0/#b08a4a · card-rose #fff0f0/#d4686a (bg/border)
StatusChipsmall state pill (ok / warn / down) inside tiles
ChartsD3: GpumonTrend, GpumonBarList, CalendarFilings (heat-calendar), ForceEntities (force-directed graph), SankeySchemeOutcome (flow), PackSchemeAmount (circle-pack), Benford leading-digit viz
Coverage bars.cov-bars 2-col grid → 1-col at ≤900px

Responsive breakpoints

gpumon: 1100px (footer/grid), 720px (header collapse), 560px (tight). postcrime adds 960px, 900px, 768px, 640px plus orientation queries for the heavier data pages. Use gpumon's three for chrome; reach for postcrime's finer set only on data-table / stats pages.