Skip to content

[design] The console has never been measured against DESIGN-SYSTEM.md — no light theme, no theme mechanism, colour-named status tokens, and nothing lints store/ #367

Description

@serge-ivo

The workspace claims this is enforced. Nothing checks it.

~/dev/stores/DESIGN-SYSTEM.md opens with:

Source of truth. If this file disagrees with a site's CSS, the site is wrong.

and the workspace CLAUDE.md says the shared design system is "Enforced via CI lint + PR
checklist."

For this repo neither half exists. ci.yml:72 runs biome check --error-on-warnings packages workers/mcpstore/ is not in the scan, which is the entire UI (documented honestly in
1587022/#326, so this is a known boundary, not a surprise). And Biome is a JS/TS linter: there is
no stylelint, no token lint, and no vendored tailwind-preset.js in this repo — the preset the
design system says every Tailwind app copies lives only at ~/dev/stores/scripts/tailwind-preset.js.

So the design system is a document the console has never been measured against. Below is what a
first measurement finds. This is the same shape as the defects this batch keeps turning up — a
surface asserting a guarantee nothing behind it enforces.

1. There is no light theme, and no theme mechanism

store/console/src/index.css:14-34 defines one palette, and it is dark:

@theme {
  --color-paper: #0a0a0a;
  --color-ink:   #fafafa;

The design system requires both themes, switched by a data-theme attribute on <html>, with the
preference in localStorage["stores-theme"] so it follows the user between stores. Grepping the
console for data-theme, prefers-color-scheme or stores-theme returns nothing — not in the
CSS, not in the app.

That is a deliberate-looking product decision (a dark developer console) that was never written
down, so it currently reads as 300 lines of unimplemented spec. Either the console is exempt and the
design system should say so, or the light theme is real work. It should not stay ambiguous — the
next person to add a surface cannot tell which rules apply.

It also has live consequences. DataTab.tsx:46,57 sets bg-gray-200 text-gray-600 for a dead
status chip. On a #0a0a0a page that is a light-grey chip with mid-grey text — not a theme bug
waiting to happen, a legibility bug shipping today. 40 raw Tailwind palette classes are in the tree
(text-amber-500 ×8, text-purple-400 ×7, bg-amber-500 ×4, plus violet/orange/gray) against a
standard that says never hardcode these.

2. Status tokens are named for their colour, not their meaning

The console declares --color-green, --color-red, --color-yellow, --color-blue. The design
system declares --danger, --success, --warning, each with a -soft background pairing, and
says explicitly: "Use these for validation, alerts, badges, and state — never hardcode
red/green/yellow."

Naming the token after the pigment defeats the purpose one level up. text-red has 78 uses carrying
at least four unrelated meanings: an error message, a destructive action, the write scope label on
a tool row (SettingsTab.tsx:854), and an offline/failed state. A reader cannot tell which, and a
future decision to make destructive actions orange-not-red becomes 78 case-by-case judgements.

Rename to intent (danger · success · warning · info), add the missing -soft pairings —
several inline bg-red/10 and bg-accent/10 opacity hacks exist precisely because the soft variant
was not available.

3. Nothing measures any of this

Whatever is decided above, it needs a check, or it will drift straight back. Cheapest useful version:

Order matters: land #366's primitives first, then lint — a lint with nowhere to put the fix is
just 168 blocked PRs.

Related: #366 (component primitives), #326 (lint scope), #305.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfrontendFrontend / UI work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions