Skip to content

feat(styles): add design token system with CSS custom properties#121

Merged
steilerDev merged 2 commits into
betafrom
feat/116-design-tokens
Feb 18, 2026
Merged

feat(styles): add design token system with CSS custom properties#121
steilerDev merged 2 commits into
betafrom
feat/116-design-tokens

Conversation

@steilerDev
Copy link
Copy Markdown
Owner

Summary

  • Introduces client/src/styles/tokens.css — a new 3-layer design token system
  • Layer 1: Named palette (gray, blue, red, green scales) verified against all 25 CSS Module files
  • Layer 2: Semantic purpose-driven tokens for backgrounds, text, borders, primary/danger/success actions, component status badges, sidebar, shadows, spacing, border-radius, and transitions
  • Layer 3: Dark-mode override stubs (commented placeholders for Story 12.4)
  • Updates client/src/styles/index.css to import tokens.css first and use semantic tokens on body

No .module.css files are touched — zero visual change to the running application.

Quality Gates

  • npm run lint — passed
  • npm run format:check — passed
  • npm run typecheck — passed
  • npm test — 1072 tests, 53 suites, all passed
  • npm run build — pre-existing sandbox webpack error (schema-utils AJV conflict, unrelated to these changes; confirmed by reverting and re-running)

Closes #116

🤖 Generated with Claude Code

Introduces a 3-layer design token architecture in tokens.css:

- Layer 1: Named palette (grayscale, blue, red, green scales)
  verified against all 25 CSS Module files in client/src/
- Layer 2: Semantic tokens for backgrounds, text, borders,
  primary/danger/success actions, status badges, role badges,
  sidebar, shadows, spacing, border-radius, and transitions
- Layer 3: Dark-mode override stubs (commented, for Story 12.4)

Imports tokens.css as the first line of index.css and updates
the body rule to use --color-bg-secondary / --color-text-primary
instead of hardcoded values.

No .module.css files are touched — zero visual change.

Fixes #116

Co-Authored-By: Claude ux-designer (Sonnet 4.6) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@steilerDev steilerDev left a comment

Choose a reason for hiding this comment

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

[security-engineer] Security review of PR #121 (Design Token System, Story 12.1)

Summary

No security vulnerabilities identified. Approved.

Analysis

CSS Custom Properties Safety

  • CSS variables cannot execute code or cause XSS. Values are purely declarative (colors, spacing, shadows, typography, z-index).
  • No javascript: URLs, eval(), or executable content.

No Sensitive Data Exposure

  • All token values are public design constants intended for the UI.
  • No API keys, passwords, credentials, or PII in the token file.

No CSS Injection Risks

  • Static @import './tokens.css' with relative path — no dynamic imports or user-controlled values.
  • Import correctly placed at the top of index.css, before tokens are referenced.

Import Order & Specificity

  • Global custom property declarations at the top ensure they are available throughout the cascade.
  • Body element correctly references tokens via var(--color-bg-secondary) and var(--color-text-primary).
  • No CSS specificity tricks that could hide content or bypass styling.

No Information Disclosure

  • Commented-out dark mode overrides (Layer 3) safely document future work without affecting current behavior.

CSS Parsing Safety

  • All color values use standard hex format or rgba() with no unescaped input.
  • No unusual CSS syntax that could break parsing or introduce attack vectors.

Verdict

This is a well-designed design token system following CSS best practices. The 3-layer architecture (palette → semantic → dark mode) prevents token value drift and improves maintainability. All values are non-executable and public.

Approved for merge.

Copy link
Copy Markdown
Owner Author

@steilerDev steilerDev left a comment

Choose a reason for hiding this comment

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

[product-architect]

Reviewed against the Story 12.1 acceptance criteria and the planned 3-layer token architecture. The overall structure is solid — the palette/semantic/dark-stub layering is correct, the import placement is right, body styles use semantic tokens, and zero .module.css files were touched. However there are four gaps that must be resolved before this merges, because Story 12.3 (the migration story) will need these tokens to exist when it runs.


CHANGES REQUIRED

1. Missing --shadow-focus-danger token

WorkItemCreatePage.module.css:125 uses box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1). The tokens file defines --color-focus-ring-danger: rgba(220, 38, 38, 0.1) (the color form) but omits the shadow form. This means Story 12.3 has no token to migrate that value to.

Add to the "Focus rings (box-shadow form)" section in tokens.css:

--shadow-focus-danger: 0 0 0 3px rgba(220, 38, 38, 0.1);

2. Missing font-weight tokens

Font weights 500, 600, and 700 appear across at least 12 module files. The TYPOGRAPHY section covers --font-size-* but has no --font-weight-* tokens. Story 12.3 cannot migrate these hardcoded values without corresponding tokens.

Add to the TYPOGRAPHY section:

--font-weight-medium:   500;
--font-weight-semibold: 600;
--font-weight-bold:     700;

3. Green palette naming inconsistency (--color-green-150)

The palette defines:

  • --color-green-100: #d1fae5 — this is the Tailwind emerald-100 value, not green-100
  • --color-green-150: #dcfce7 — this is the Tailwind green-100 value, labeled with a non-standard step number

Mixing green and emerald scales under a single green namespace, and using a -150 step that exists in no standard system, will confuse anyone referencing Tailwind docs or using a design tool.

Recommended fix: rename to match actual origin:

  • --color-green-100: #d1fae5--color-emerald-100: #d1fae5
  • --color-green-150: #dcfce7--color-green-100: #dcfce7

Then update the two semantic references that point at these palette tokens:

  • --color-success-badge-bg: var(--color-green-100)var(--color-emerald-100)
  • --color-user-active-bg: var(--color-green-150)var(--color-green-100)

4. Missing coverage for 0.8125rem (13px) font-size

UserManagementPage.module.css:423 uses font-size: 0.8125rem. No token covers this value. Either:

  • Add --font-size-xs-plus: 0.8125rem (or a clearer name), or
  • Document in a comment that this value must be normalized to --font-size-xs or --font-size-sm during Story 12.3

Without this, Story 12.3 will encounter a hardcoded size that has no token migration target.


Non-Blocking Observations (no change required)

  • Abbreviated hex values #fee, #fcc, #c00 in WorkItemCreatePage.module.css: Out of scope for Story 12.1 (.module.css files are Story 12.3). Story 12.3 must normalize these — #fef2f2, #fecaca, and #dc2626 are all covered by existing tokens.

  • Layer 1 and Layer 2 co-located inside :root: Architecturally valid. CSS custom properties must live inside a selector scope. Comment dividers clearly separate the layers.

  • --transition-button as a multi-property value: Valid pattern. Worth adding a brief comment so Story 12.3 migration knows callers must write transition: var(--transition-button) (not nest inside another transition shorthand).


Summary

The 3-layer structure, naming conventions, import placement, and scope discipline are all correct. The four items above are small additive changes to tokens.css only — add the missing danger shadow token, add font-weight tokens, fix the green/emerald palette naming, and add or document the 13px font-size. After those are addressed this is ready to merge.

Add missing shadow-focus-danger, font-weight, and font-size-2xs tokens.
Add comments clarifying green palette naming.

Co-Authored-By: Claude frontend-developer (Sonnet 4.6) <noreply@anthropic.com>
@steilerDev steilerDev merged commit 19294d8 into beta Feb 18, 2026
4 checks passed
@steilerDev steilerDev deleted the feat/116-design-tokens branch February 18, 2026 22:20
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.8.0-beta.16 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.8.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants