Refactor base color ramp to fixed-lightness OKLCH with mode-adaptive interactions - #456
Conversation
F1: switch full-api-demo pages from slashed.optimal.css to slashed.full.css so all 691 tokens (including 6 btn/field component tokens) resolve correctly. F2: mark --sf-color-mark-text and --sf-color-selection-text with data-inherit in token tiles; refresh() now shows "inherit (contextual)" instead of "(empty)" so users understand these are fallback-only override hooks, not broken tokens. F3: document base family exception in llm-guide.md — the 50=Lightest/950=Darkest contract holds for the five mid-tone brand families but not for base (near-white source), which is a surface-elevation ramp; direct users to semantic aliases. F4: exclude classes with bundles:[] from demo tiles — theme-transition lives only in optional/theme-example.css (copy-and-customise, not shipped); its tile was inert and misleading. .sf-theme-transition (shipped in motion.css) remains.
slashed.full.css includes utilities.css and components.css which are both STAGED (all class definitions commented out). optimal-components is the correct bundle: adds only tokens.components.css (the 6 active btn/field tokens) without pulling in dead staged code.
…ch steps The old formula (color-mix text↔base for steps 50-400, base↔text for 600-950) produced a V-shaped ramp for the near-white base source: steps 50→400 darkened, step 500 spiked back to near-white, steps 600→950 re-darkened. This also made base-lighter (step 400) visually darker than base-darker (step 600) — semantically inverted aliases. New approach: fixed OKLCH L steps (0.97 at 50 → 0.06 at 950) preserving the base source hue and chroma, same strategy as Tailwind/Radix. The ramp is now strictly monotonic and mode-independent. Aliases are semantically correct: lighter (0.65) is lighter than darker (0.37). base--hover and base--active are switched from step aliases to relative oklch offsets (l - 0.04 / l - 0.08), so hover/active states adapt correctly to both light mode (base≈0.96) and dark mode (base≈0.22). The --sf-palette-mix-* knobs are unchanged and still govern the five mid-tone brand families (primary/secondary/tertiary/action/neutral). docs/llm-guide.md updated: base now fully honours the 50=Lightest contract; the palette-mix knobs note clarifies they do not affect base.
l - 0.04 darkens in both modes, which is wrong for dark mode (base ≈ 0.22 going to 0.18 is barely perceptible and in the wrong direction). Use --sf-is-dark flag (0 in light, 1 in dark) to flip the direction: light: l - 0.04 = 0.92 (darkens near-white surface, visible) dark: l - 0.04 + 0.08 = 0.26 (lightens near-dark surface, visible) Same logic for --active with a larger delta (0.08 / 0.30).
|
Warning Review limit reached
Next review available in: 41 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (19)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
PR Summary by QodoRefactor base color ramp to fixed-lightness OKLCH with mode-adaptive states
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
6 rules 1.
|
The demo header was displaying classes.length (239) while the page itself only renders bundled classes (238), hiding the theme-transition example-only class. Compute bundledClassCount once at module level and use it in the subtitle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017TkkKpQTutqD8LcaYC2wtN
… family
base is an absolute lightness scale (step 50 always near-white, 950 always
near-black), so direction-named aliases lied depending on where the source
sits — e.g. against a near-white base in light mode --sf-color-base-lighter
resolved *darker* than --sf-color-base. Remove the six relative aliases
(superlight/xlight/lighter/darker/xdark/superdark).
The numeric ramp (base-50…950) covers fixed shades; the surface tokens
(bg/inset/raised) cover mode-adaptive elevation; hover/active cover
interaction states. Each concern now has exactly one home. The relative
aliases remain on the five mid-tone brand families, where the source sits
mid-ramp and the names are honest.
Also drop the comparative reference from the base ramp comment and the
llm-guide. Regenerate docs/api-index/token-index/registry/configurator,
update the token API snapshot, and document the removal in migration.md.
BREAKING CHANGE: --sf-color-base-{superlight,xlight,lighter,darker,xdark,superdark}
removed. See docs/migration.md for the replacement map.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017TkkKpQTutqD8LcaYC2wtN
Summary
Migrates the
--sf-color-base-*family from a mode-dependent V-shaped ramp (mixing toward text/surface) to a fixed-lightness OKLCH ramp that is mode-independent and monotonic. The numbered scale (50–950) now uses absolute lightness values (0.97 → 0.06), while hover and active states become mode-adaptive via--sf-is-darkcalculations.Key Changes
Base ramp definition: Replaced
color-mix(in oklab, ...)expressions withoklch(from var(--sf-color-base) L c h)syntax, where L is fixed per step (50=0.97, 100=0.94, ..., 950=0.06)--sf-color-basewhile fixing lightnessInteraction states:
--sf-color-base--hoverand--sf-color-base--activenow use mode-aware formulas:--hover:oklch(from var(--sf-color-base) clamp(0.01, calc(l - 0.04 + var(--sf-is-dark) * 0.08), 0.99) c h)--active:oklch(from var(--sf-color-base) clamp(0.01, calc(l - 0.08 + var(--sf-is-dark) * 0.16), 0.99) c h)base-darkerandbase-xdarkDocumentation: Updated token comments to reflect the new fixed-lightness approach and removed semantic alias mappings (superlight, xlight, lighter, darker, xdark, superdark) from the main ramp definition
Generated artifacts: Regenerated
docs/api-index.json,docs/api-index.md,docs/token-index.json,docs/token-index.md, anddocs/tokens.mdto reflect new token valuesDemo generation: Updated
demos/generate.mjsto:--sf-color-mark-text,--sf-color-selection-text) withdata-inheritattributeslashed.optimal-components.cssImplementation Details
The new approach uses CSS relative color syntax (
oklch(from ...)) to derive all steps from a single source token while maintaining perceptual consistency. The fixed lightness scale is independent of the source color's original position, making the ramp predictable and composable across light/dark modes without requiring separate palette-mix variables.https://claude.ai/code/session_017TkkKpQTutqD8LcaYC2wtN