chore(tokens): migrate color system from HEX to OKLCH#757
chore(tokens): migrate color system from HEX to OKLCH#757paanSinghCoder wants to merge 6 commits intomainfrom
Conversation
Convert all 414 design token color values to oklch() across primitives, semantic appearance tokens, viz palettes, overlay tokens, and shadow effects. Conversion is mechanical and visually lossless. Every value is byte-identical in 8-bit sRGB after re-parsing the rounded oklch() output, with CIEDE2000 delta-E < 0.5 — no rendered pixel changes. Files: - styles/primitives/gray.css (96 hex) - styles/primitives/accent.css (78 hex) - styles/primitives/appearance.css (192 hex) - styles/colors.css (24 hex+alpha overlays) - styles/effects.css (24 rgba shadows) Includes the one-shot migration script under scripts/ for reviewer verification (run with --validate). The script and its culori devDep are removed in the follow-up commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The migration is complete; the script and its sole consumer (culori) have no further use. Run state lives in git history. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Convert the lone rgba() drop-shadow on the number-field scrub cursor to oklch() for consistency with the now-migrated effects.css shadow tokens. Pure black with 50% alpha — visually lossless. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughThis pull request migrates color definitions across the Raystack design system from hex/rgba formats to OKLCH color syntax. Changes update CSS custom properties for overlays, shadows, accents, appearance, and gray palettes, plus component stylesheets (announcement-bar, badge, callout, number-field) and a few demo snippets to use Possibly related issues
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
Convert the brand-decoration gradients in callout, badge, and announcement-bar from raw HEX (with alpha) to oklch() for format consistency with the tokens layer. Byte-identical 8-bit sRGB. These values remain hardcoded brand-decoration magic numbers, not tokens — tokenization is a separate design-team conversation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the tokens-layer convention in the dialog overlay demo so the docs preach what the design system uses internally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
packages/raystack/components/number-field/number-field.module.css (1)
79-81: Optional: use the overlay token instead of an inline oklch.
--rs-color-overlay-black-a7is defined asoklch(0 0 0 / 0.502)inpackages/raystack/styles/colors.cssand is effectively the same value. Consuming the token here would keep this drop-shadow consistent with the rest of the migrated overlay surface.♻️ Suggested change
.scrub-area-cursor { - filter: drop-shadow(0 1px 1px oklch(0 0 0 / 0.5)); + filter: drop-shadow(0 1px 1px var(--rs-color-overlay-black-a7)); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/raystack/components/number-field/number-field.module.css` around lines 79 - 81, Replace the hardcoded oklch color in the .scrub-area-cursor drop-shadow with the overlay token to match design tokens; locate the .scrub-area-cursor rule and change the color value used in filter: drop-shadow(...) from oklch(0 0 0 / 0.5) to the CSS variable --rs-color-overlay-black-a7 (i.e., use var(--rs-color-overlay-black-a7)) so the shadow follows the centralized overlay token.packages/raystack/components/callout/callout.module.css (1)
103-200: Optional: extract the duplicated gradient into a CSS variable.The same
oklch(0.5674 0.2831 312.58 / 0.2) → oklch(0.5988 0.2445 29.12 / 0.2)color stops appear at Line 104 and Line 197 here, and also inpackages/raystack/components/badge/badge.module.css(Line 64) andpackages/raystack/components/announcement-bar/announcement-bar.module.css(Lines 10–11, full-opacity variant). The PR notes decorative gradients remain hardcoded; while keeping them un-tokenized is fine for now, at minimum centralizing the two stop colors as--rs-color-gradient-decorative-from/to(or similar) inside this file would prevent drift between the three component stylesheets.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/raystack/components/callout/callout.module.css` around lines 103 - 200, The gradient stop colors are duplicated in .callout-gradient and .callout-outline.callout-gradient; introduce two CSS custom properties (e.g. --rs-color-gradient-decorative-from and --rs-color-gradient-decorative-to) at the top of this stylesheet, assign the two oklch color values to them, and update the radial-gradient usages in the .callout-gradient and .callout-outline.callout-gradient selectors to reference these variables so both gradient instances use the centralized tokens.packages/raystack/styles/primitives/appearance.css (1)
28-258: Optional: consider an@supportsfallback for older OKLCH-incapable consumers.The CSS oklch() color function has strong support in modern browsers (Chrome 111+, Firefox 113+, Safari 15.4+, >93% global coverage), but documented gaps exist in email clients (Outlook Windows 2007–2019, sporadic older client support) and PDF rendering tools (html2pdf.js and similar generators lack oklch() support as of 2026). Since this file is a primary token source, applying
@supports (color: oklch(0 0 0))with hex/rgba fallbacks alongside oklch values would allow graceful degradation for older runtimes instead of resolving to the CSS initial value. If the project's stated browser support matrix already excludes those runtimes or this is part of the acknowledged follow-up plan, this can be safely deferred.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/raystack/styles/primitives/appearance.css` around lines 28 - 258, The file uses many oklch() tokens (e.g., --rs-neutral-1, --rs-success-1, --rs-danger-1, --rs-overlay-1) with no fallback for runtimes that don't support OKLCH; add an `@supports` fallback strategy: declare hex/rgba fallback values first for each key, then override them inside `@supports` (color: oklch(0 0 0)) { /* set the oklch() values for the same variables */ } so older clients/PDF generators/email renderers get stable colors while modern browsers keep oklch().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/raystack/styles/primitives/accent.css`:
- Around line 9-103: The VSCode plugin token file uses hex color values that are
out of sync with the CSS primitives now expressed in oklch; update the accent
token exports (the accent token constants for accent-1 through accent-12 and
accent-contrast) to use the exact oklch strings from the CSS (e.g., oklch(0.9943
0.0013 286.38) for accent-1, etc.) so each exported token matches its CSS
counterpart, then run the plugin build/tests to confirm no regressions and add a
short comment or doc note in the token file about keeping hex→oklch parity with
the design primitives going forward.
---
Nitpick comments:
In `@packages/raystack/components/callout/callout.module.css`:
- Around line 103-200: The gradient stop colors are duplicated in
.callout-gradient and .callout-outline.callout-gradient; introduce two CSS
custom properties (e.g. --rs-color-gradient-decorative-from and
--rs-color-gradient-decorative-to) at the top of this stylesheet, assign the two
oklch color values to them, and update the radial-gradient usages in the
.callout-gradient and .callout-outline.callout-gradient selectors to reference
these variables so both gradient instances use the centralized tokens.
In `@packages/raystack/components/number-field/number-field.module.css`:
- Around line 79-81: Replace the hardcoded oklch color in the .scrub-area-cursor
drop-shadow with the overlay token to match design tokens; locate the
.scrub-area-cursor rule and change the color value used in filter:
drop-shadow(...) from oklch(0 0 0 / 0.5) to the CSS variable
--rs-color-overlay-black-a7 (i.e., use var(--rs-color-overlay-black-a7)) so the
shadow follows the centralized overlay token.
In `@packages/raystack/styles/primitives/appearance.css`:
- Around line 28-258: The file uses many oklch() tokens (e.g., --rs-neutral-1,
--rs-success-1, --rs-danger-1, --rs-overlay-1) with no fallback for runtimes
that don't support OKLCH; add an `@supports` fallback strategy: declare hex/rgba
fallback values first for each key, then override them inside `@supports` (color:
oklch(0 0 0)) { /* set the oklch() values for the same variables */ } so older
clients/PDF generators/email renderers get stable colors while modern browsers
keep oklch().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8156f346-dd6b-4792-a097-b1df31b4d190
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
apps/www/src/content/docs/components/dialog/demo.tspackages/raystack/components/announcement-bar/announcement-bar.module.csspackages/raystack/components/badge/badge.module.csspackages/raystack/components/callout/callout.module.csspackages/raystack/components/number-field/number-field.module.csspackages/raystack/styles/colors.csspackages/raystack/styles/effects.csspackages/raystack/styles/primitives/accent.csspackages/raystack/styles/primitives/appearance.csspackages/raystack/styles/primitives/gray.css
Summary
Mechanical, visually lossless migration of the design token color system from HEX / rgba() to OKLCH across the token layer, plus a small consistency sweep over component CSS that carried hardcoded color literals and one doc demo.
oklch()oklch()output, with CIEDE2000 ΔE < 0.5Files touched
Tokens (primary scope, byte-identical sRGB):
styles/primitives/gray.cssstyles/primitives/accent.cssstyles/primitives/appearance.cssstyles/colors.cssstyles/effects.cssComponent / docs sweep (consistency, hardcoded literals only):
components/number-field/number-field.module.csscomponents/callout/callout.module.csscomponents/badge/badge.module.csscomponents/announcement-bar/announcement-bar.module.cssapps/www/src/content/docs/components/dialog/demo.tsVerification
pnpm test)Notes for reviewers
var(--rs-*)consumer is unaffected.culoridevDep were removed in a follow-up commit on this branch — git history preserves the tool for future reference.apps/www/src/app/(llms)/tokens.mdx/[category]/route.tsparsesstyles/*.cssdynamically — after this PR it servesoklch()values to LLM consumers instead of HEX. No code change needed; just calling out the surface change.Out of scope (intentional)
These are deliberately not in this PR — each is a meaningful, separable workstream:
colornpm package has no OKLCH support; library swap (→ culori/colorjs.io), adding OKLCH toSUPPORTED_MODES, andlinear-gradient(in oklch longer hue, …)for the perceptually-correct hue strip belong in their own PR. Docs still correctly listHEX, RGB, HSL.coin-colored.svgandcheck-circle-filled.svg— separate icon-tokenization effort.packages/raystack/style.cssat the package root — appears to be dead (not imported byindex.tsx, not bundled intodist/style.css); flagged for separate cleanup.L).#ad00e9/#ef0404style) — design-team decision.Test plan
🤖 Generated with Claude Code