Skip to content

refactor(ui): token housekeeping + typography wiring + icon CSS (slice #02, issue #440)#448

Merged
Astro-Han merged 7 commits into
devfrom
claude/i440-slice-02
May 5, 2026
Merged

refactor(ui): token housekeeping + typography wiring + icon CSS (slice #02, issue #440)#448
Astro-Han merged 7 commits into
devfrom
claude/i440-slice-02

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Promotes --surface-base-active from the UNREGULATED section to the REGULATED section in theme.css (light :root, [data-color-scheme="dark"], and @media mirror). Syncs pawwork.json overrides. Parity test: 128 → 131 pass.
  • Adds a Bun consistency test (test/colors-generation.test.ts) that enforces sync between script/colors.txt and tailwind/colors.css: every token in the source must have a corresponding --color-X: var(--X) entry and vice versa. Planned in slice 01 PR feat(ui): token layer + rename to STANDARDS (slice #01) #442 Risk Note §3.
  • Removes 9 --shadow-* and 1 --text-mix-blend-mode entries from script/colors.txt and regenerates tailwind/colors.css. These tokens were polluting the --color-* Tailwind namespace (e.g. --color-shadow-raised), which would attempt to set background-color to a box-shadow string. No callers used these utilities.
  • Replaces 8 inline font-size: 12px / font-size: 13px literals with var(--font-size-x-small) / var(--font-size-small) across checkbox.css, switch.css, radio-group.css, message-part.css, and keybind.css. Avatar rem values are intentionally proportional and left unchanged.
  • Adds [data-color="strong/weak/disabled"] CSS selectors to icon.css so callers can opt into DESIGN.md color states declaratively. Removes stale commented-out property. Documents size="small" (16px) as the standard chrome size.

Why

Carries over three items deferred from slice 01 (PR #442): the --surface-base-active classification, the colors consistency test, and the shadow namespace fix. Adds typography and icon CSS housekeeping as the code-level foundation for slice 02 per issue #440.

Related Issue

Refs #440 (umbrella). This PR is slice 02 of eleven.

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.

Review Focus

  • --surface-base-active placement: confirm it now appears before the UNREGULATED TOKENS comment in all three CSS blocks and that the parity test enforces its sync with pawwork.json.
  • colors.css namespace: confirm no --color-shadow-* or --color-text-mix-blend-mode entries remain; shadow utilities (shadow-xs, shadow-md) in tailwind/index.css are separate and correct.
  • font-size token replacements: all 8 replacements are mechanical (12pxvar(--font-size-x-small), 13pxvar(--font-size-small)); no layout changes expected.

Risk Notes

  • --color-shadow-* removal: any CSS that happened to use bg-shadow-raised etc. as a Tailwind class would silently lose its style. Verified by grep: no callers exist in packages/app/src or packages/ui/src.
  • font-size token substitution: --font-size-x-small and --font-size-small resolve to the same pixel values (12px, 13px) as the literals they replace. Zero visual change at current token values.
  • The two session-diff.test.ts failures are pre-existing (present before slice 01; confirmed by git log that session-diff.ts was not touched).

How To Verify

parity test:
  bun --cwd packages/ui run test test/theme-parity.test.ts
  131 pass, 0 fail
  (was 128; +3 for surface-base-active light/dark/media assertions)

colors consistency test:
  bun --cwd packages/ui run test test/colors-generation.test.ts
  2 pass, 0 fail

undefined-token scan:
  bun --cwd packages/ui run test test/undefined-tokens.test.ts
  2 pass, 0 fail

full packages/ui test suite:
  bun --cwd packages/ui run test
  173 pass, 2 fail (pre-existing session-diff failures, unrelated)

typecheck (packages/ui):  tsgo --noEmit → 0 errors
typecheck (packages/app): tsgo -b       → 0 errors

shadow namespace clear:
  grep --color "color-shadow\|color-text-mix" packages/ui/src/styles/tailwind/colors.css
  (no output — entries removed)

Screenshots or Recordings

No visible UI changes in this PR. All changes are CSS token plumbing, test coverage, and namespace cleanup.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • Chores

    • Removed unused shadow design tokens and reorganized theme variable definitions for a cleaner design system.
  • Style

    • Updated component styling to consistently use design tokens instead of hardcoded values across multiple components for improved consistency and theme flexibility.
  • Tests

    • Added validation suite to ensure design token synchronization between configuration files.

Astro-Han added 5 commits May 5, 2026 17:41
Reclassify --surface-base-active as a state token (it has full dark-mode
coverage and is used by 13+ component CSS files). Move from the UNREGULATED
section to the STANDARDS-aligned regulated block in all three CSS sections
(light :root, [data-color-scheme="dark"], @media mirror), and add to
pawwork.json overrides so the parity test can enforce sync.

parity test: 128 → 131 pass (three new assertions for light/dark/media blocks)
Planned in slice #1 (PR #442 Risk Note §3). Verifies every token in
script/colors.txt has a corresponding --color-X: var(--X) entry in
tailwind/colors.css, and vice versa. Prevents stale artifact drift
where a bg-* Tailwind utility would silently resolve to the wrong value.
…space

Shadow and blend-mode values have no place in the color utility namespace;
--color-shadow-raised would try to set background-color to a box-shadow
string. Remove 9 shadow-* and 1 text-mix-blend-mode entries from
script/colors.txt and regenerate tailwind/colors.css accordingly.

No callers were using these --color-shadow-* utilities (verified by grep).
Shadow values remain accessible as var(--shadow-*) directly.
Replace font-size: 12px with var(--font-size-x-small) and font-size: 13px
with var(--font-size-small) across checkbox, switch, radio-group,
message-part, and keybind components. Avatar rem sizes are intentionally
proportional and left unchanged.
Add [data-color="strong/weak/disabled"] CSS selectors to icon.css so
callers can opt into DESIGN.md color states declaratively rather than
relying solely on Tailwind text-* overrides. Remove stale commented-out
resize property. Add inline comment marking size="small" (16px) as the
standard chrome size per DESIGN.md spec.
@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR standardizes design tokens across the UI theme layer by removing unused shadow tokens, replacing hardcoded font sizes with CSS design token variables in component stylesheets, reordering theme property declarations, enhancing the icon component with explicit color variants, and adding a test suite to validate synchronization between token source files.

Changes

Design Token & Component Standardization

Layer / File(s) Summary
Token Cleanup
packages/ui/script/colors.txt, packages/ui/src/styles/tailwind/colors.css
Removed shadow-related tokens (--shadow-raised, --shadow-floating, --shadow-modal, --shadow-xs-border-* variants) and --color-text-mix-blend-mode.
Theme Reorganization
packages/ui/src/styles/theme.css, packages/ui/src/theme/themes/pawwork.json
Repositioned --surface-base-active declarations earlier in :root and dark-mode blocks; added surface-base-active overrides to pawwork.json light and dark themes.
Component Font Size Standardization
packages/ui/src/components/checkbox.css, packages/ui/src/components/keybind.css, packages/ui/src/components/message-part.css, packages/ui/src/components/radio-group.css, packages/ui/src/components/switch.css
Replaced hardcoded 12px and 13px font sizes with design token variables (var(--font-size-x-small), var(--font-size-small)) across description, error, and label slots.
Icon Component Enhancement
packages/ui/src/components/icon.css
Added explicit color attribute selectors for data-color="strong", data-color="weak", and data-color="disabled" mapping to icon color tokens; refactored size handling to single-line declarations.
Token Validation
packages/ui/test/colors-generation.test.ts
Added Bun test suite validating bidirectional synchronization between colors.txt and colors.css token definitions, ensuring no missing or orphan tokens.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • Astro-Han/pawwork#208: Contains CSS changes that may reference the shadow tokens being removed in this PR, creating a direct dependency.
  • Astro-Han/pawwork#217: Modifies the same token definition files (colors.txt and colors.css) that this PR restructures and validates.

Poem

🐰 Tokens cleaned up, shadows swept away,
Font sizes standardized in every way,
Icons now bright with colors so true,
Tests keep them synced—old and new!
A tidy theme, organized and neat,

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main changes: token housekeeping (shadow/color cleanup), typography token wiring (font-size replacements), and icon CSS enhancements, correctly referencing the slice and issue number.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description comprehensively covers all required template sections with substantive detail: summary of changes, rationale, related issue, human review status, review focus, risk notes (token removal safety, font-size token equivalence, pre-existing test failures), verification steps with results, and completed checklist.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/i440-slice-02

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 and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request standardizes font sizes by replacing hardcoded pixel values with CSS variables across multiple components, including checkbox, keybind, message-part, radio-group, and switch. It also refines the icon component with new color attributes and simplified sizing, updates theme variables for active surfaces, and removes unused shadow and blend mode tokens. A new test was added to ensure synchronization between the color definition file and Tailwind configuration. Feedback was provided to improve the robustness of the token parsing logic in the new test to match the generator script's behavior.

Comment thread packages/ui/test/colors-generation.test.ts
@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Astro-Han Astro-Han added ui Design system and user interface P3 Low priority labels May 5, 2026
parseTxtTokens: switch from regex extraction to split(":")[0].substring(2),
matching the exact logic in tailwind.ts. The old regex truncated names at
the first non-[a-z0-9-] character (e.g. underscore), producing misleading
comparison errors.

parseCssTokens: relax [a-z][a-z0-9-]* to [^\s:]+ so the backreference
correctly handles any character the generator accepts.
@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/ui/test/colors-generation.test.ts (1)

44-60: ⚡ Quick win

Good coverage, but this does not fully enforce 1:1 token sync.

Nice bidirectional checks. One gap: Line 45 and Line 54 convert to Set, so duplicate entries in either file won’t fail the test even though the PR objective says 1:1 consistency. Add a duplicate-count assertion (or compare frequency maps) for both parsed lists.

Proposed patch
 const txtTokens = parseTxtTokens(COLORS_TXT)
 const cssTokens = parseCssTokens(COLORS_CSS)
+
+function countByToken(tokens: string[]): Map<string, number> {
+  const map = new Map<string, number>()
+  for (const t of tokens) map.set(t, (map.get(t) ?? 0) + 1)
+  return map
+}
 
 test("every colors.txt token has a --color-X: var(--X) entry in colors.css", () => {
   const cssSet = new Set(cssTokens)
   const missing = txtTokens.filter((t) => !cssSet.has(t))
@@
   ).toEqual([])
 })
 
 test("every colors.css entry has a corresponding token in colors.txt", () => {
   const txtSet = new Set(txtTokens)
   const orphan = cssTokens.filter((t) => !txtSet.has(t))
@@
   ).toEqual([])
 })
+
+test("token cardinality matches 1:1 between colors.txt and colors.css", () => {
+  const txtCounts = countByToken(txtTokens)
+  const cssCounts = countByToken(cssTokens)
+  expect([...txtCounts.entries()].sort()).toEqual([...cssCounts.entries()].sort())
+})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/test/colors-generation.test.ts` around lines 44 - 60, The tests
use Set conversion (cssSet, txtSet) so duplicate tokens in cssTokens or
txtTokens are ignored; update the two tests ("every colors.txt token has..." and
"every colors.css entry has...") to assert there are no duplicates by checking
that cssTokens.length === new Set(cssTokens).size and txtTokens.length === new
Set(txtTokens).size (or alternatively build frequency maps for cssTokens and
txtTokens and assert every token has count === 1), then keep the existing
bidirectional membership assertions (missing/orphan) to enforce true 1:1 sync
between cssTokens and txtTokens.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ui/test/colors-generation.test.ts`:
- Around line 44-60: The tests use Set conversion (cssSet, txtSet) so duplicate
tokens in cssTokens or txtTokens are ignored; update the two tests ("every
colors.txt token has..." and "every colors.css entry has...") to assert there
are no duplicates by checking that cssTokens.length === new Set(cssTokens).size
and txtTokens.length === new Set(txtTokens).size (or alternatively build
frequency maps for cssTokens and txtTokens and assert every token has count ===
1), then keep the existing bidirectional membership assertions (missing/orphan)
to enforce true 1:1 sync between cssTokens and txtTokens.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ef2d309a-feee-4a86-9a41-b3c6343b731b

📥 Commits

Reviewing files that changed from the base of the PR and between 16cebab and 6e543ff.

📒 Files selected for processing (11)
  • packages/ui/script/colors.txt
  • packages/ui/src/components/checkbox.css
  • packages/ui/src/components/icon.css
  • packages/ui/src/components/keybind.css
  • packages/ui/src/components/message-part.css
  • packages/ui/src/components/radio-group.css
  • packages/ui/src/components/switch.css
  • packages/ui/src/styles/tailwind/colors.css
  • packages/ui/src/styles/theme.css
  • packages/ui/src/theme/themes/pawwork.json
  • packages/ui/test/colors-generation.test.ts
💤 Files with no reviewable changes (2)
  • packages/ui/src/styles/tailwind/colors.css
  • packages/ui/script/colors.txt

Set conversion in the bidirectional membership tests silently ignores
duplicate entries. Add two explicit no-duplicates assertions so accidental
duplicate lines in colors.txt (and corresponding generated entries in
colors.css) are caught early.
@Astro-Han

Copy link
Copy Markdown
Owner Author

Fixed in d1b5605. Added two explicit no-duplicates tests before the existing bidirectional membership checks:

colors.txt has no duplicate token names
colors.css has no duplicate token entries

Used indexOf instead of countByToken frequency map — the same invariant with less code, since we just need to assert each token appears exactly once rather than that two lists share identical frequency distributions. 4 pass, 0 fail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant