Fourth Dimension Sports: one system, every screen.
Colour, type, spacing, radius, elevation and components all resolve from
tokens.css. Edit a token there and it cascades to every page below. Components live in
components.css as reusable classes: no inline colours anywhere.
Screens built on this system
wireframes/README.md.
Registered palette
Sanctioned extensions
Status ramp Draft
Not in the registered brand set: kept muted/institutional. Palette-align before production.
Type scale
Lead 17 · Plus Jakarta Sans for display, Inter for body. Evidence first: we substantiate, we do not describe.
Body 15 · the analytical rigour of a top-tier advisory firm applied to fan economies. British English throughout.
Mono · 1,284,905 fans · 7–11% ARPU · v3.0
Metrics
Buttons
Hierarchy: at most one btn-primary per surface (page or dialog) — the action that surface exists to accomplish (page-head CTA, dialog confirm, sign-in submit). Everything else is btn-secondary; btn-ghost for low-emphasis inline actions; btn-danger takes the primary slot in a destructive dialog. A dialog trigger is primary only when it launches the page's main job ("Invite member" on Members) — supporting edits ("Edit profile" on Account) stay secondary. A submit that would be a no-op (nothing changed yet) renders disabled.
a.btn when it navigates, button.btn when it acts: identical styling, no hover underline.
Form fields
Badges · Chips · Stats
Table
Console modules
Shared building blocks for the admin console screens: KPI card, meter, operational feed, metric list, and top-bar chrome. Used first on the Admin dashboard.
Operational queue
feed · status discsEconomy snapshot
metric list| Tenant | Wallet | Latest signal |
|---|---|---|
| All Things Rugby | No wallet | Provisioning failed |
| Tour Demo Co | Ready | Settlement queued |
| Sample | Ready | Reconciled today |
| No matches. Clear filters. | ||
Live: the Filter button opens a faceted drawer (multi-select, AND across groups); search and removable pills update the table. Single-axis screens use a select instead (see Form fields). One engine, shared in console.js: also on the tenant and member lists.
Notices
Empty state
Attention queue
in-section · defaultNo dedicated class — an empty state composes .stack + .muted. Inside a section that already has a .panel-head h4 title, the message is a quiet strong.muted line that must never out-size that title. Only a full-page boundary state (404, loading) promotes the title to a real heading styled .h3, with an optional description and action. Table bodies use the table-scoped .table-empty row instead (see Table above).
Timeline
Step states: is-done (green), is-current (blue), is-blocked (red; see User XP), or default (pending).
Modal · toast
console.js: data-modal-open / data-modal-close, backdrop click and Escape.
Detail drawer
.drawer + .drawer-overlay with .drawer-head/body/foot; long mono values stack via .deflist-hybrid. Close via ✕, the backdrop, or Escape.
Site footer
Chrome bookend to the topbar: a full-bleed band on --bg-page separated by a 1px top border — flat, not an elevated surface. console.js injects it on every console page via mountFooter(); opt a page out with <body data-no-footer> (this catalog does, to demo it inline). Sign-in keeps its own shell and never loads console.js.