Skip to content
commission

The dashboard's design system

commission serve renders the observer view: the pages a human opens to see what their agents are doing and what needs them. This page says what its design is, what it borrows, and — more usefully — what it deliberately does not.

Everything visual here is generated from site/src/styles/tokens.css into src/server/tokens.ts by bun run generate:tokens, and tests/design.test.ts fails if the two have drifted. There is no second place to change a colour.

Three systems, not two

site/README.md opens by splitting the marketing site in two: / uses a product system, /technical and /design use a documentary one. The dashboard is a third case, and the split is the same kind of argument.

surfacesystemread
/ (the landing page)productonce, by someone deciding
/technical, /design, /blogdocumentaryonce, carefully, in order
commission serveoperationalmany times a day, by owner

A landing page has to stop somebody scrolling. A reference page has to be readable end to end. An operational page has to be instantly legible to somebody who has already seen it two hundred times — which is a different job from either, and it is the one the dashboard is designed for.

The consequences follow from that sentence:

  • Nothing is a reward for arriving. No entrance animation, no loop, no stage, no scroll indicator. All of them are first-impression devices, and by the third visit of the day they are a tax. tests/design.test.ts asserts the stylesheet contains no @keyframes and no animation at all.
  • Nothing is larger than it has to be. The type scale is the site’s, and it stops at --t-h1 (32px); the four display steps above it are unavailable to this surface. The page title is --t-h2 (26px), because the project name is already in the bar above and in the tab strip below.
  • Whitespace is not automatically an upgrade. A reader here is scanning for the exception, and every row pushed below the fold is a row they have to scroll to find. Space is spent where it separates kinds of thing and reclaimed everywhere else.
  • Colour is state. See below.

What carries over from the landing page

The colour identity, the type scale, the 4px spacing rhythm, the 4px/2px radii, the chip and badge treatment, the two designed themes, and the confidence to use a saturated brand colour at all. The site’s mono micro-label — uppercase, 0.09em, faint — is the section heading here, exactly as it is on /technical: it marks what a block is and never carries the argument.

What does not, and why

Named with reasons in CLASSIFICATION in scripts/generate-tokens.ts, which throws on a token it has not been told about — so a value added to the site cannot leak into an operational tool because nobody looked. The headline exclusions:

excludedwhy
--c-stage*a dark ground that ignores the reader’s theme; a tool honours it
--glow-*the hero aura — decoration with no state to report
--t-display*a 92px condensed headline on a page read daily is shouting
--c-grad-*gradient text is a landing device; a heading read daily should be ink
--dur-loop, --dur-entrance, --reveal-stepnothing here should arrive late or move on its own
--shadow-branda coloured glow would compete with the status colours
--space-section4.5rem is a scrolling page’s pace; the operational scale is --sp-*, on the same 4px step

Colour means a state in the task graph

The site’s rule, and it binds harder here because a person is triaging. Commission has five statuses; the site names four semantic colours. The mapping, and the one extension:

colourmeans
--c-accentlinks, in_progress
--c-okdone, criteria met, evidence present
--c-warnblocked (derived), a gate not yet satisfied
--c-refusalcancelled, a refusal, a divergence
--c-brand-violeta person is neededin_review, and the two judgement controls
--c-brandthe wordmark, and nothing else

Violet is the extension and it is the surface’s one idea. in_review is the state that means a human has to look, and the approve and answer controls are where a human looks. Giving them one colour makes the write surface findable and makes the read-only boundary visible rather than merely true: a violet chip is a task waiting on a person, and a violet control is the only place in the whole view where a person can act on one. Nothing else is violet.

--c-brand appears exactly once, as the mark in the wordmark. A dashboard that painted its brand across the chrome would be spending attention it needs for state.

Colour is never the only signal. A dot always travels with its word. Where a row’s status chip is suppressed, it is because the section heading above it is that word for every row underneath — IN REVIEW over three rows beats three chips saying “in review”, and the dot is aria-hidden so assistive technology gets the heading instead.

Constraints that are features

These are not incidental and must survive any future work here.

  1. Server-rendered, no client JS beyond native elements. <details> and <form> are the whole interaction budget. That is why this view works over SSH on a bad connection, and it is worth more than any animation. tests/web-inbox.test.ts asserts the page ships no <script> and no on* attribute.
  2. The stylesheet is inline and self-contained. No stylesheet link, no font file, no CDN — asserted by tests/design.test.ts. The fonts are named (IBM Plex Sans / Mono, falling back to the system UI face), not shipped: a single-file binary serving three webfonts would be a heavier page over exactly the connection this view exists for. The type scale is what carries over; the face is a bonus where it is installed.
  3. Every route is a GET except four. The judgement routes under /p/:slug/inbox are the only mutations, they live in their own sub-app, and the route table is asserted.
  4. commission serve never reads site/. The tokens are compiled in.

Themes

Two designed themes, following prefers-color-scheme. There is no toggle, and that is a consequence of constraint 1 rather than an oversight: a toggle without client JS means a route that writes a cookie, and the read-only boundary is worth more than a toggle. It is on the list in docs/design/dashboard-beta.md.

Verifying a change

bun run generate:tokens          # after any change to the site's tokens
bun test tests/design.test.ts    # drift, colour literals, spectacle, scale
bun run scripts/shoot-dashboard.ts .screenshots/dashboard

The last one seeds a scratch database with real commands, serves it, and photographs every page at 390px and 1440px in both themes, reporting page height and failing on horizontal overflow. Read the heights: on this surface a page that got taller for the same content is a regression.

This page is docs/design/dashboard.md in the Commission repository, rendered in place — the site keeps no copy of it. The repository is private, so there is no edit link to follow.