Skip to content

feat(ui): adopt the Compass design-system token base on the app shell - #220

Open
seal-agent wants to merge 1 commit into
mainfrom
compass-ui-1819-shell-token-flip
Open

feat(ui): adopt the Compass design-system token base on the app shell#220
seal-agent wants to merge 1 commit into
mainfrom
compass-ui-1819-shell-token-flip

Conversation

@seal-agent

@seal-agent seal-agent commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Wires the merged design-system token base (apps/ui/src/design/tokens.css + base.css, authored by the compass-ux DS foundation lane) into the app's CSS load path, sets the Night Owl theme as the root default, and flips the structural app-shell chrome from the legacy GitHub-dark custom properties to the frozen --cx-* semantic tier. This is the adoption half of the T9 strangler step (SEA-1819 bullets 1-2); the ungated focus-ring fix (bullet 3) already shipped in #203.

What changed

  • App.tsx — the single import "./app.css" becomes a three-import cascade, tokens.css then base.css then app.css. Order is load-bearing: tokens defines the --cx-* / --rigel-* vars, base lays the global reset/type/scrollbar/:focus-visible layer, and legacy app.css loads last so on any same-specificity conflict the legacy rule still wins — the strangler stays additive, no big-bang restyle.
  • index.html<html> gains data-theme="night". The --cx-* color tier is scoped under [data-theme="night"] in tokens.css, so without this attribute the color tokens resolve to nothing. This is the frozen D2 dark-primary default made real.
  • app.css — 60 structural-chrome var() references across the four named shell regions (topbar + view-tabs, left sidebar tree, right sidebar shell, usage bar) flipped from legacy vars to their --cx-* targets: surfaces (--bg* to --cx-bg*, the absent 4th card tier collapsing to --cx-bg-panel), lines (--border* to --cx-border*), text (--text* to --cx-text*), interaction accent (--accent to --cx-accent), the usage-meter hot fill (--warn to --cx-warn), and the active-nav border (--accent-dim, which has no direct --cx-* equivalent, to --cx-accent-muted). Every target name was verified against the merged tokens.css.

Scope — structural chrome only (strangler boundary)

Four shell references are deliberately left on legacy vars and deferred to a component-tier follow-up, because each carries a component or design decision rather than a clean surface mapping: the agent .state-dot set (a D3 component, StateDot.tsx), the .daemon status dot (semantic tier ambiguous — infra liveness, not an agent state), the warden .role-pip (--purple, which D2's one-accent rule bans from the --cx-* tier — a genuine design question), and the global scrollbar-thumb hover (a raw hex with no named token). The legacy :root token definitions stay in place; content, board, composer, and settings rules are untouched.

Verification

  • bunx tsc --noEmit clean; bunx vite build succeeds (the new imports and the @import-free chain resolve, CSS bundles without error).
  • bun test --conditions browser: full suite green in the colocated clone (env-secrecy's git-shelling tests require a .git dir, which a jj-added workspace lacks — they pass here). 723 pass / 0 fail across 43 files.
  • CSS-only surface change: no test asserts computed colors, so behavior is unchanged; the visible effect is the shell rendering in the Night Owl palette.

Spec-impact: none. Refs SEA-1819

Co-authored-by: Matt Wilkinson matt@sealedsecurity.com


Review

Sole adversarial review: floor CLEAN — 0 high, 0 medium, 3 low. No hard block. The reviewer independently verified the two highest-risk failure modes of a token migration: every consumed --cx-* token is defined in the merged tokens.css (no flip resolves to no-value), and the strangler invariant holds concretely (app.css declares zero --cx-* — read-only consumption — and legacy app.css wins every same-specificity conflict). The 3 low findings are design/component judgment calls, routed to the follow-up rather than auto-fixed (token choice is a design call).

Open Questions (parked for Matt — none block this PR)

This PR is deliberately structural-chrome only. The following are deferred to SEA-1876 (component-tier + canvas adoption), which carries the full detail:

  1. Warden role-pip purple.role-pip[data-role="warden"] stays var(--purple). D2's one-accent rule bans purple from --cx-*, so no mechanical flip exists — this is a genuine design fork needing a Matt ruling (blue / neutral / carve-out / drop). Left legacy until ruled.
  2. Bridge-link active border — mapped --accent-dim to --cx-accent-muted (a 24%-alpha wash) as a stated assumption. Reviewer's fidelity-preserving alternative is --cx-border-focus (solid blue). Reversible token-choice decision.
  3. Daemon status dot (--warn/--add) and state-dot (--st-*) — left legacy as component-tier / tier-ambiguous refs (a small within-shell amber divergence results, a documented deferral).
  4. Canvas hueapp.css's legacy body/scrollbar globals still shadow base.css's --cx-* versions, so the base canvas stays GitHub-dark under the Night-Owl chrome. Strangler-by-design; migrating it (and retiring the #45505f scrollbar-hover hex) is the next strangler step in SEA-1876.

Refs SEA-1819. Follow-up: SEA-1876.

Wires the merged design-system token base (`apps/ui/src/design/tokens.css` + `base.css`, authored by the compass-ux DS foundation lane) into the app's CSS load path, sets the Night Owl theme as the root default, and flips the structural app-shell chrome from the legacy GitHub-dark custom properties to the frozen `--cx-*` semantic tier. This is the adoption half of the T9 strangler step (SEA-1819 bullets 1-2); the ungated focus-ring fix (bullet 3) already shipped in #203.

### What changed

- **`App.tsx`** — the single `import "./app.css"` becomes a three-import cascade, `tokens.css` → `base.css` → `app.css`. Order is load-bearing: tokens defines the `--cx-*` / `--rigel-*` vars, base lays the global reset/type/scrollbar/`:focus-visible` layer, and legacy `app.css` loads last so on any same-specificity conflict the legacy rule still wins — the strangler stays additive, no big-bang restyle.
- **`index.html`** — `<html>` gains `data-theme="night"`. The `--cx-*` color tier is scoped under `[data-theme="night"]` in `tokens.css`, so without this attribute the color tokens resolve to nothing. This is the frozen D2 dark-primary default made real.
- **`app.css`** — 60 structural-chrome `var()` references across the four named shell regions (topbar + view-tabs, left sidebar tree, right sidebar shell, usage bar) flipped from legacy vars to their `--cx-*` targets: surfaces (`--bg*` → `--cx-bg*`, the absent 4th `card` tier collapsing to `--cx-bg-panel`), lines (`--border*` → `--cx-border*`), text (`--text*` → `--cx-text*`), interaction accent (`--accent` → `--cx-accent`), the usage-meter hot fill (`--warn` → `--cx-warn`), and the active-nav border (`--accent-dim`, which has no direct `--cx-*` equivalent, → `--cx-accent-muted`). Every target name was verified against the merged `tokens.css`.

### Scope — structural chrome only (strangler boundary)

Four shell references are deliberately left on legacy vars and deferred to a component-tier follow-up, because each carries a component or design decision rather than a clean surface mapping: the agent `.state-dot` set (a D3 component, `StateDot.tsx`), the `.daemon` status dot (semantic tier ambiguous — infra liveness, not an agent state), the warden `.role-pip` (`--purple`, which D2's one-accent rule bans from the `--cx-*` tier — a genuine design question), and the global scrollbar-thumb hover (a raw hex with no named token). The legacy `:root` token definitions stay in place; content, board, composer, and settings rules are untouched.

### Verification

- `bunx tsc --noEmit` clean; `bunx vite build` succeeds (the new imports and the `@import`-free chain resolve, CSS bundles without error).
- `bun test --conditions browser`: full suite green in the colocated clone (env-secrecy's git-shelling tests require a `.git` dir, which a jj-added workspace lacks — they pass here).
- CSS-only surface change: no test asserts computed colors, so behavior is unchanged; the visible effect is the shell rendering in the Night Owl palette.

Spec-impact: none. Refs SEA-1819

Co-authored-by: Matt Wilkinson <matt@sealedsecurity.com>
@linear-code

linear-code Bot commented Aug 7, 2026

Copy link
Copy Markdown

SEA-1819

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