Skip to content

The design-system folder: tokens.css, components.css, DESIGN.md - #312

Open
kateebonner wants to merge 13 commits into
local/amicodefrom
kate/design-system-folder
Open

The design-system folder: tokens.css, components.css, DESIGN.md#312
kateebonner wants to merge 13 commits into
local/amicodefrom
kate/design-system-folder

Conversation

@kateebonner

@kateebonner kateebonner commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What this is

The design system gets a home: packages/app/src/design-system/ holds exactly three things — DESIGN.md (the twelve laws, their reasons, and the gate that makes each a law; the Principles tier; the values staged for the sheet; the landing plan), tokens.css (the brand sheet, formerly design-polish.css: every design-system value and nothing else), and components.css (every rule that applies the tokens to a named surface — a skin, in the glossary's word). CONTEXT.md gains the Brand vocabulary. ADR 0006 was drafted, reviewed three times, and then folded into DESIGN.md; ADR 0003's first consequence is superseded by Law 1.

What changes for a user

The split itself moves every declaration verbatim. After an Impeccable critique of this PR (dual-agent; 21/40; snapshot in .impeccable/critique/), the following law-conformance fixes were scoped in before merge — each is a visible change, listed so the reviewer can find it:

  • The Amico mark on the landing renders in the scheme's strong ink (ink on light, cream on dark), no longer in the accent on dark — yellow is the call to action's alone (Law 1). Both landing files paint it (new-session-view.tsx is the one the route renders; the screenshot round caught the first fix landing in the other).
  • The DEV / BETA channel chips are neutral quiet controls — base ink on a strong hairline, no fill — in both schemes; a channel is a status, not the next action (Law 1). The DEV button drops its inline accent style and wears the same skin.
  • The send arrow is a live control in an idle state: never disabled, so assistive tech no longer hears "dimmed" while sighted users see a live control; pressing it while empty focuses the composer (Law 7). Hover is the site's CTA hover colour; the 1px lift is gone (Law 6).
  • The tour spotlight ring is the strong ink, not 1px of yellow that vanished on white (Law 1).
  • The solver banner's "ready" chip is a neutral status chip (strong hairline + a word), not a yellow fill; the banner's float shadow is gone (Laws 1, 2).
  • The running session dot is a neutral pulse, not a darkened-yellow hue (Laws 1, 6); --status-running is retired.
  • The composer↔question card swap is an arrival — rise and fade, no scale — and keeps its fade under reduced motion (Law 6).
  • Running prose is capped at 75 characters a line (--measure); at 1280px it ran ~99 (the detector's line-length finding).
  • The project-avatar badge reads at 5.7:1 on light (white on the grey badge, as dark already did) instead of 3.1:1.
  • Inline code, the prose-fragment card, and the badge's rhythm move onto tokens and the 4px unit; two dead composer selectors are deleted.
  • The titlebar update spinner is a hairline ring in the neutral icon ink (it was a 2px accent ring — the folder's last static-gate hit) and carries data-working; under reduced motion it breathes instead of spinning.

Not changed, and held for the landing change with a DELTA — Law 9 note: the skins' !importants (they beat lazy-loaded component CSS until the skins are re-layered).

One critique finding did not survive verification: the detector reported a transition: height on body. A runtime probe over every loaded stylesheet finds no rule giving body a transition (its computed value is the default); the only height transition in the app is the terminal panel's Tailwind transition-[height] on mobile — an upstream glide, held as a Law 6 delta on the parked list.

What changes for a developer

  • npm run check:design reads tokens.css, gains rule 7 (a border is 1px, nothing else), rule 8 (no shadows, ever — box-shadow, text-shadow, drop-shadow(), shadow-*, ring-* — with no policy switch), rule 1b (a colour literal hiding as a var() fallback), sees box-shadow written as a JSX object key, and no longer exempts the skins — including the 304-line @layer components block that lived in index.css under a "font declarations" exemption and now lives, layer-preserved, in components.css. It is not in CI; it fails on main today and reports the full inventory here (159 on this branch; the folder itself: 0) — the baseline the landing change will record.
  • index.css is six imports and the app-shell rule. The @font-face declarations are token definitions and live in tokens.css.
  • The rendered conformance spec (packages/app/e2e/regression/design-system-conformance.spec.ts) reads the tokens live, sweeps both schemes, asserts Law 5's weights, reads the --text-* names Law 8 introduces, and bans every painting shadow with no switch. Run: PLAYWRIGHT_PORT=3123 VITE_OPENCODE_CHANNEL=dev ./node_modules/.bin/playwright test e2e/regression/design-system-conformance.spec.ts in packages/app. It fails today by design — it is the inventory the landing change and its follow-ups clear.

What does not land here

The landing change DESIGN.md describes: the @theme conversion with the staged values and aliases, deletion of the upstream declarations the sheet supersedes, the theme JSON's accent and focus by reference, the six markers, the remaining gate rules, the baseline, and the CI lane. Each law's parked deltas follow that, one issue per law.

Review

Read DESIGN.md first — it is the thing being decided. The CSS diff is a move; git diff --stat shows the split, and the two files concatenate back to the original minus its header.

Lint

npm run lint on this branch: the seven TypeScript/JavaScript files it touches report 0 errors. The repository's single pre-existing error — an octal escape in the v2 prompt input's class string — is in a file this PR does not change and is left for its own fix.

…f truth

Twelve laws with no exceptions (accent = call to action, no shadows, 1px
hairlines, one corner, the de facto type scale, motion, interaction, namespace
by @theme declaration, self-enforcement, the 4px unit, 400 ms response, visible
progress), a Principles tier of the Laws of UX under their correct names, the
values staged for packages/app/src/design-system/style-tokens.css, and the
landing plan (definition first; static gate required against a baseline;
rendered and skins checks informational until each law's deltas clear).

CONTEXT.md gains the Brand vocabulary (18 terms) and retires Exemptions, State
edges, Yellow selection, and Elevation. ADR 0003 consequence 1 is superseded:
the engines are inside the accent law and the live marker is neutral.
The context tree and brain engines are inside the accent law; no yellow marks
the live position.
Move the twelve laws, the Principles tier, the staged values, and the landing
plan from ADR 0006 to DESIGN.md beside the token file, losing nothing. The
design-system folder holds tokens.css, skins.css, and DESIGN.md. ADR 0006 is
removed; ADR 0003's supersession line and the glossary's citations point at
the new home.
Split design-polish.css into packages/app/src/design-system/tokens.css (the
brand sheet: every design-system value, and nothing else) and skins.css
(every rule that applies the tokens to a named surface), beside DESIGN.md
(the laws). No value changes: every declaration moves verbatim; the app's
entry imports both files where it imported one.

The static design gate reads the new sheet path, gains rule 7 (borders are
1px, nothing else) and rule 8 (no shadow drawn as a border, with a
SHADOW_POLICY=none switch), and no longer exempts the skins — they are gated
like any component. A rendered conformance spec reads the tokens live and
sweeps both schemes for the laws the gate cannot see. Neither runs in CI yet;
the CI lane lands with the baseline in the landing change.

Stories and the travelling-dot test that loaded the old sheet now load the
two files; comments that named design-polish.css point at the folder.
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: b170ec75-fa9f-4008-8f75-5f3d770baf53


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Law 2 says nothing casts a shadow. The gate shipped with a weaker default and
an environment variable to reach the law; a gate that can be weakened by an
environment variable is an exception, and the system has none. Rule 8 now
bans every box-shadow and text-shadow that is not none, every drop-shadow()
filter, and the shadow-*/ring-* utilities, unconditionally. DESIGN.md's Law 2
gate sentence says the same.
The name a reader expects beside tokens.css. The glossary term stays Skin —
a rule that applies the tokens to a named surface — and the file that holds
them is components.css.
@kateebonner kateebonner changed the title The design-system folder: tokens.css, skins.css, DESIGN.md The design-system folder: tokens.css, components.css, DESIGN.md Sep 8, 2026
components.css inlined the system's feedback and glide timings on every
control (0.16s ease ×12, 0.22s cubic-bezier ×6). tokens.css now declares
--motion-feedback / --motion-feedback-ease and --motion-glide /
--motion-glide-ease with those exact values, and the skins consume them; a
skin never defines a token. No visual change.
The rendered conformance spec carried its own SHADOW_POLICY switch, asserted
the old 400/500/600/650/700 weights, and read only --font-size-* tokens; it
now bans every painting box-shadow, text-shadow, and drop-shadow() filter
with no switch, asserts Law 5's 440/530/600, and reads the --text-* names
Law 8 introduces alongside the old ones for the migration.

The static gate could not see a box-shadow written as a JSX object key or a
colour literal hiding as a var() fallback; both are rule violations now.
Inventory rises from 89 to 165 — the same code, seen honestly.
Harden the design-system folder after the Impeccable critique of #312
(21/40): everything the critique found inside the folder is fixed here,
and everything it found outside it is recorded as a delta.

tokens.css declares; components.css only consumes. The six @font-face
blocks and the 304-line @layer components block move out of index.css
(where the gate exempted them as "font declarations") into the folder,
layer preserved, so the static gate finally sees every skin. New tokens:
--ink-strong (ink on light, cream on dark) with --focus-ring as its
alias, --measure (75ch), and the feedback/glide motion tokens; retired:
--elev-float and --status-running.

Visible changes, each a law: the Amico mark renders in the strong ink,
never the accent (Law 1); the tour ring is the strong ink, not 1px of
yellow on white; the send arrow is a live control in an idle state, never
disabled, and focuses the composer when pressed empty (Law 7), with the
CTA hover and no lift (Law 6); the solver banner's ready chip is a
neutral status chip and its float shadow is gone (Laws 1, 2); the
running session dot is a neutral Working pulse, not a darkened yellow
(Laws 1, 6); the composer/question swap is a rise-and-fade arrival that
keeps its fade under reduced motion; running prose is capped at
--measure; the project-avatar badge reads 5.7:1 on light; the titlebar
update spinner is a hairline neutral working ring carrying data-working.

DESIGN.md records where the values stand (landed vs staged), the mark and
the running pulse under Law 1, stadiums under Law 4, the --text-ui /
--text-content aliases, today's ten gate exemptions as deltas, and the
response margin. The skill is regenerated by hand from it.

Gate: 161 (folder: 0). Build, both typechecks, unit tests green.
The screenshot round after d956244 caught two accents that still pointed
instead of prompting. The landing route renders new-session-view.tsx, not
session-new-view.tsx, so the Amico mark was still painted with the icon
accent on dark; both files now paint it in the strong ink (Law 1). The
DEV button in the titlebar carried an inline yellow-fill style and the
BETA chip a yellow skin with a dark-scheme amber override; a channel is a
status, not the next action, so both chips are neutral quiet controls —
base ink on a strong hairline, no fill — in both schemes, and the DEV
button wears the same data-slot skin instead of inline styles (Laws 1, 3).

Gate: 159 (folder: 0; the two var() fallback literals in the old BETA
skin are gone). App and ui typechecks green; lint unchanged (the one
error is the pre-existing octal escape in session-ui's prompt input).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant