Goal
Single tracking log for all design-token system debt — redundant aliases, source-of-truth drift between docs/DESIGN.md and runtime theme.css, and parallel-system overlaps. No commitment to clear every entry on a fixed timeline. Entries are resolved opportunistically as the UI rewrite work in #601 (and follow-ups) touches the relevant surfaces.
Scope and intent
This issue is intentionally not a cleanup PR queue. It is a record so the next person who edits typography, colors, spacing, or theme files can pull from a single place rather than rediscovering the same debts. Each entry below states the current observed state and what decision is required, not a scheduled fix.
Findings
Category A · Real dead tokens and stray hardcoded values (low-risk to clean opportunistically)
Either duplicate an existing token, live outside the docs/DESIGN.md spec, or are hardcoded values that should be token references. Safe to delete or fix the next time someone is in the relevant file for an unrelated reason.
--font-size-hierarchy (13px, identical to --font-size-base). 9 callsites in packages/ui are all mechanical, no semantic distinction.
--brand-danger and --brand-danger-hover. Upstream-inherited aliases for --error. docs/DESIGN.md uses --error exclusively for the danger semantic (see L326-330). Zero callsites in packages/.
- Hardcoded
border-radius: 6px in packages/ui/src/components/message-part.css L42 (user-message-attachment) and L374. Value is correct (matches --radius-sm = 6px from the project frontmatter) but missed token-ization. Two callsites, both safe to replace with var(--radius-sm).
Category B · DESIGN.md ↔ runtime drift (needs source-of-truth decision)
Where the design source and the runtime disagree. Resolve when the affected component surface is next touched.
- Light
--surface-sunken value. docs/DESIGN.md L135 and docs/design/colors_and_type.css declare #F4F0EC as an independent third neutral tier reserved for inline code and code-block headers. packages/ui/src/styles/theme.css declares #faf9f7 (identical to --bg-cream) and carries the comment light alias → bg-cream; no third neutral tier. The runtime stance contradicts the design source. Decide which is canonical: either DESIGN.md drops the third tier (matching runtime), or runtime restores #F4F0EC (matching design).
- Dark
--surface-sunken is too dark to see inline-code decoration. docs/DESIGN.md reserves --surface-sunken for inline code; in dark theme its value (#16130F) sits below --bg-base (#1A1714), so the decoration disappears. docs/design/ui_kits/desktop/styles.css already routes .pw-agent-text code, .pw-chip, .pw-tool, .pw-input, .pw-kbd to --surface-base (one tier above bg) instead. The fix is either lifting the dark sunken value, or dropping the "sunken" semantic and renaming the token to reflect the actual usage.
Category C · Parallel-system overlap (resolves with rewrite progress)
Two parallel token systems express the same concept. Picking one and deprecating the other is a real design call, not a cleanup.
- Typography:
--type-* vs --font-size-*. docs/DESIGN.md L195-208 specs nine --type-* composite tokens (each bundles weight, size, line-height, family). Only --type-body is actually used (three callsites). The remaining eight (--type-display, --type-h1, --type-h2, --type-h3, --type-caption, --type-mono, --type-mono-small, --type-kbd) have zero component callsites. Components use the older --font-size-* family (45+ callsites for --font-size-small alone). Decide whether the rewrite migrates components to font: var(--type-*), or whether --type-* is dropped in favor of the existing per-property tokens.
--font-size-small (13px, identical to --font-size-base). 45 callsites in packages/ui plus three .ts files. The name implies smaller-than-base but the value is the same. Three options to evaluate when the typography decision above is taken: delete and migrate to --font-size-base; re-tune --font-size-small to 12px so the scale (small < base < large) reads honestly; or keep --font-size-small and remove --font-size-base from the public surface.
- Radii: Tailwind
--radius-* vs project --radius-* (same name, different scale, different values). Tailwind utility radii in packages/ui/src/styles/tailwind/index.css L59-63 are rem-based (xs=0.125rem / sm=0.25rem / md=0.375rem / lg=0.5rem / xl=0.875rem → 2 / 4 / 6 / 8 / 14 px). Project radii in docs/DESIGN.md frontmatter L72-76 are explicit px (sm=6 / md=10 / lg=14 / pill=9999). Same name md disagrees on value: Tailwind rounded-md = 6px, project var(--radius-md) = 10px. Components mixing the two namespaces get unexpectedly different geometry — for example dock attachments (packages/app/src/components/prompt-input/image-attachments.tsx) use Tailwind rounded-md and render at 6px, while W1 preview docs/design/preview/message-flow.html originally locked file chips at var(--radius-md) = 10px. Decide whether to align values, or document the dual-namespace as the deliberate design (Tailwind = utility shorthand for fine-grained pixel control, project tokens = product-design coarser scale).
Category D · Already resolved (recorded for completeness, no action)
Closed locally in docs/ only (which is .git/info/exclude'd per AGENTS.md and not in git):
--icon-chev was reverted before reaching packages/. All preview and scratch files now use the existing --icon-base. The chevron paragraph in docs/DESIGN.md was rewritten to drop the new-token rationale; the 12-px chev size carries the secondary-symbol hierarchy on its own.
--bg-strong removed. Nine real callsites in docs/design/ui_kits/desktop/styles.css rewired to --surface-base (same value as the deleted alias). Dead declarations purged from colors_and_type.css and nine preview files.
docs/DESIGN.md frontmatter deviations: ledger expanded from two entries to thirteen, capturing previously inline-only exceptions (kbd off-grid padding, dialog text-only buttons, branch dirty three-button dialog, popover inline search row, discard armed button, branch popover width 280, settings nav width 240, hotkey hover dashed-to-solid, app picker multi-color icon, file-type vendor icons, Lucide library) so the ledger is now the only formal record of sanctioned exceptions.
Not problems (forward-looking spec, keep)
Tokens with zero current callsites that are nonetheless intentional. They are part of the docs/DESIGN.md frontmatter scale and reserved for future components.
--radius-pill (9999px). docs/DESIGN.md frontmatter L75 explicitly defines the pill tier ("pill": 9999). Reserved for badge / chip / tag / avatar shapes the rewrite has not yet built.
--space-xl (20px), --space-2xl (24px), --space-3xl (32px), --space-4xl (48px), --space-5xl (64px). docs/DESIGN.md frontmatter L62-70 declares the full xs through 5xl spacing scale. Reserved for layouts the rewrite has not yet built.
Pointers
Verification (when an entry is eventually closed)
Whichever Category-A entry ships as a cleanup PR:
bun --cwd packages/app run typecheck clean.
bun test packages/ui green (theme-parity test ensures pawwork.json mirrors theme.css).
grep -rn <removed-token> packages/ returns zero hits after the PR.
- Visual diff zero for direct aliases (Category A); visual diff inspection required for Category B and C entries that actually change rendered values.
Execution mode
Agent should investigate and propose a plan first for any Category B or C entry. Category A can be cleaned directly when the surrounding code is being modified for another reason; do not open a standalone PR just for Category A.
Goal
Single tracking log for all design-token system debt — redundant aliases, source-of-truth drift between
docs/DESIGN.mdand runtimetheme.css, and parallel-system overlaps. No commitment to clear every entry on a fixed timeline. Entries are resolved opportunistically as the UI rewrite work in #601 (and follow-ups) touches the relevant surfaces.Scope and intent
This issue is intentionally not a cleanup PR queue. It is a record so the next person who edits typography, colors, spacing, or theme files can pull from a single place rather than rediscovering the same debts. Each entry below states the current observed state and what decision is required, not a scheduled fix.
Findings
Category A · Real dead tokens and stray hardcoded values (low-risk to clean opportunistically)
Either duplicate an existing token, live outside the
docs/DESIGN.mdspec, or are hardcoded values that should be token references. Safe to delete or fix the next time someone is in the relevant file for an unrelated reason.--font-size-hierarchy(13px, identical to--font-size-base). 9 callsites inpackages/uiare all mechanical, no semantic distinction.--brand-dangerand--brand-danger-hover. Upstream-inherited aliases for--error.docs/DESIGN.mduses--errorexclusively for the danger semantic (see L326-330). Zero callsites inpackages/.border-radius: 6pxinpackages/ui/src/components/message-part.cssL42 (user-message-attachment) and L374. Value is correct (matches--radius-sm= 6px from the project frontmatter) but missed token-ization. Two callsites, both safe to replace withvar(--radius-sm).Category B · DESIGN.md ↔ runtime drift (needs source-of-truth decision)
Where the design source and the runtime disagree. Resolve when the affected component surface is next touched.
--surface-sunkenvalue.docs/DESIGN.mdL135 anddocs/design/colors_and_type.cssdeclare#F4F0ECas an independent third neutral tier reserved for inline code and code-block headers.packages/ui/src/styles/theme.cssdeclares#faf9f7(identical to--bg-cream) and carries the commentlight alias → bg-cream; no third neutral tier. The runtime stance contradicts the design source. Decide which is canonical: eitherDESIGN.mddrops the third tier (matching runtime), or runtime restores#F4F0EC(matching design).--surface-sunkenis too dark to see inline-code decoration.docs/DESIGN.mdreserves--surface-sunkenfor inline code; in dark theme its value (#16130F) sits below--bg-base(#1A1714), so the decoration disappears.docs/design/ui_kits/desktop/styles.cssalready routes.pw-agent-text code,.pw-chip,.pw-tool,.pw-input,.pw-kbdto--surface-base(one tier above bg) instead. The fix is either lifting the dark sunken value, or dropping the "sunken" semantic and renaming the token to reflect the actual usage.Category C · Parallel-system overlap (resolves with rewrite progress)
Two parallel token systems express the same concept. Picking one and deprecating the other is a real design call, not a cleanup.
--type-*vs--font-size-*.docs/DESIGN.mdL195-208 specs nine--type-*composite tokens (each bundles weight, size, line-height, family). Only--type-bodyis actually used (three callsites). The remaining eight (--type-display,--type-h1,--type-h2,--type-h3,--type-caption,--type-mono,--type-mono-small,--type-kbd) have zero component callsites. Components use the older--font-size-*family (45+ callsites for--font-size-smallalone). Decide whether the rewrite migrates components tofont: var(--type-*), or whether--type-*is dropped in favor of the existing per-property tokens.--font-size-small(13px, identical to--font-size-base). 45 callsites inpackages/uiplus three.tsfiles. The name implies smaller-than-base but the value is the same. Three options to evaluate when the typography decision above is taken: delete and migrate to--font-size-base; re-tune--font-size-smallto 12px so the scale (small < base < large) reads honestly; or keep--font-size-smalland remove--font-size-basefrom the public surface.--radius-*vs project--radius-*(same name, different scale, different values). Tailwind utility radii inpackages/ui/src/styles/tailwind/index.cssL59-63 are rem-based (xs=0.125rem /sm=0.25rem /md=0.375rem /lg=0.5rem /xl=0.875rem → 2 / 4 / 6 / 8 / 14 px). Project radii indocs/DESIGN.mdfrontmatter L72-76 are explicit px (sm=6 /md=10 /lg=14 /pill=9999). Same namemddisagrees on value: Tailwindrounded-md= 6px, projectvar(--radius-md)= 10px. Components mixing the two namespaces get unexpectedly different geometry — for example dock attachments (packages/app/src/components/prompt-input/image-attachments.tsx) use Tailwindrounded-mdand render at 6px, while W1 previewdocs/design/preview/message-flow.htmloriginally locked file chips atvar(--radius-md)= 10px. Decide whether to align values, or document the dual-namespace as the deliberate design (Tailwind = utility shorthand for fine-grained pixel control, project tokens = product-design coarser scale).Category D · Already resolved (recorded for completeness, no action)
Closed locally in
docs/only (which is.git/info/exclude'd perAGENTS.mdand not in git):--icon-chevwas reverted before reachingpackages/. All preview and scratch files now use the existing--icon-base. The chevron paragraph indocs/DESIGN.mdwas rewritten to drop the new-token rationale; the 12-px chev size carries the secondary-symbol hierarchy on its own.--bg-strongremoved. Nine real callsites indocs/design/ui_kits/desktop/styles.cssrewired to--surface-base(same value as the deleted alias). Dead declarations purged fromcolors_and_type.cssand nine preview files.docs/DESIGN.mdfrontmatterdeviations:ledger expanded from two entries to thirteen, capturing previously inline-only exceptions (kbd off-grid padding, dialog text-only buttons, branch dirty three-button dialog, popover inline search row, discard armed button, branch popover width 280, settings nav width 240, hotkey hover dashed-to-solid, app picker multi-color icon, file-type vendor icons, Lucide library) so the ledger is now the only formal record of sanctioned exceptions.Not problems (forward-looking spec, keep)
Tokens with zero current callsites that are nonetheless intentional. They are part of the
docs/DESIGN.mdfrontmatter scale and reserved for future components.--radius-pill(9999px).docs/DESIGN.mdfrontmatter L75 explicitly defines the pill tier ("pill": 9999). Reserved for badge / chip / tag / avatar shapes the rewrite has not yet built.--space-xl(20px),--space-2xl(24px),--space-3xl(32px),--space-4xl(48px),--space-5xl(64px).docs/DESIGN.mdfrontmatter L62-70 declares the full xs through 5xl spacing scale. Reserved for layouts the rewrite has not yet built.Pointers
--fg-secondaryand--icon-chevtokens both turned out to be redundant with existing ones, so slice U was cancelled (see [Feature] UI rewrite v2 Area A: message flow modular rollout #601 comment 4459413309).docs/DESIGN.mdfrontmatterdeviations:ledger is the only formal record of sanctioned design exceptions; new exceptions go there, not inline in body text.packages/ui/src/styles/theme.css,packages/ui/src/theme/themes/pawwork.json,packages/ui/src/styles/utilities.css,packages/ui/src/components/list.css,packages/ui/src/components/tabs.css,packages/ui/src/components/toast.css,packages/ui/src/components/message-part.css.Verification (when an entry is eventually closed)
Whichever Category-A entry ships as a cleanup PR:
bun --cwd packages/app run typecheckclean.bun test packages/uigreen (theme-parity test ensurespawwork.jsonmirrorstheme.css).grep -rn <removed-token> packages/returns zero hits after the PR.Execution mode
Agent should investigate and propose a plan first for any Category B or C entry. Category A can be cleaned directly when the surrounding code is being modified for another reason; do not open a standalone PR just for Category A.