feat(colors): complete color system — shade scale, section theming, swatch coverage - #188
Conversation
…ex map Extends resolve_semantic_tokens() to cover all --sf-color-* tokens registered in inventory.json, not just the handful previously hardcoded. Previously bg--hover/active/selected/focus/disabled, border--subtle/ strong/focus/disabled/translucent, all link-- states, all text--on-* contrast tokens, and other structural tokens (well, raised, inverse, overlay, dim, code-bg/text, heading, mark-bg, selection-bg) appeared in the Bricks variable picker but received no swatch. Each group is approximated from the already-computed family hex values: - bg--*: neutral/action mixed over white at the token's effective opacity - border--*: neutral-source oklch with the same L-clamp offsets as CSS - link--*: action-source oklch with the light-mode lightness clamps; visited applies the CSS +60° hue shift - text--on-*: L-threshold check (< 0.6 → near-white, ≥ 0.6 → near-black) - well/raised/inverse: base-source oklch with ±0.02/+0.04/inverted-L - dim: mid-gray approximation of the 50%-black translucent overlay https://claude.ai/code/session_01JLvpeyEzNZtgc7TVjVMhzu
Previously the 50-950 shade scale only existed as approximate hex
values computed by the Bricks PHP resolver for picker swatches —
var(--sf-color-primary-300) resolved to nothing outside Bricks.
Shade generation (class-color-resolver.php):
Switch from sRGB two-pole mixing (source→base-light, source→#1c1c2e)
to oklch interpolation toward white / black. This matches what
color-mix(in oklch, ...) computes in CSS, eliminating the purple hue
drift that the old dark-navy mix target introduced and producing
perceptually uniform steps across all hues.
Core CSS (tokens.css):
Add a full COLOR SCALE section (11 families × ~22 vars each):
· Numeric steps (50–950) via color-mix(in oklch, …-light X%, white/black)
— stable values that don't flip in dark mode, same DX as Tailwind.
· Semantic aliases (superlight → superdark, hover, active, subtle,
muted, ghost) via oklch relative color from the adaptive
--sf-color-{family} token so they auto-shift when color-scheme
switches — the safe default for component styles.
Bricks inventory (inventory.json):
Add the 100 status-family shade tokens that were missing from the
fallback variable list (success/warning/error/info/danger × 20).
https://claude.ai/code/session_01JLvpeyEzNZtgc7TVjVMhzu
…) tokens light-dark() resolves at :root declaration time, not at inheritance time — a child [data-theme="dark"] only sets color-scheme, leaving every inherited custom property still stuck at the root's resolved value. themes.css now re-declares all 35 mode-sensitive tokens (brand, status, text, borders, links, selection, status-strongs) directly on [data-theme="dark"] and [data-theme="light"] elements using explicit dark/light formulas. This makes section-level theming (dark headers on light pages, light cards in dark pages) work correctly without any per-project workaround. Gated in @supports (color: oklch(from red l c h)) for graceful degradation; older browsers fall back to root values unchanged. Also updates dark-mode.md (recipes 3-8, gotchas), theming.md (manual override tier guide), and theme-example.css (section-level usage note). https://claude.ai/code/session_01JLvpeyEzNZtgc7TVjVMhzu
|
Warning Review limit reached
More reviews will be available in 49 minutes and 54 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThis PR establishes a new color scale system with numeric shade steps and semantic aliases, implements section-level dark/light mode forcing via the ChangesColor Scale Tokens, Section-Level Theming, and Bricks Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
plugins/SLASHED-for-WP/integrations/bricks/includes/class-color-resolver.php (1)
312-357: 💤 Low valueTwo inventory tokens lack corresponding swatches.
--sf-color-mark-textand--sf-color-selection-textexist ininventory.jsonbut are not generated here. This appears intentional given the PR scope explicitly lists specific tokens, and text colors are typically less visually interesting for swatch previews. Consider adding these in a follow-up if users request them.Optional: generate mark-text and selection-text swatches
$hex_map['--sf-color-mark-bg'] = self::rgb_to_hex( self::mix_rgb( $warning_rgb, $white_rgb, 0.25 ) ); + $hex_map['--sf-color-mark-text'] = $dark_text; // mark-bg is light → dark text + $hex_map['--sf-color-selection-text'] = $hex_map['--sf-color-text--inverse']; return $hex_map;🤖 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 `@plugins/SLASHED-for-WP/integrations/bricks/includes/class-color-resolver.php` around lines 312 - 357, Add generation for the two missing swatch tokens: if isset($sources['warning']) set '--sf-color-mark-text' using the same lightness rule as the on-family loop (use $sources['warning'][0] < 0.6 ? $light_text : $dark_text) so it contrasts with the mark background (mark-bg uses $warning_rgb), and set '--sf-color-selection-text' to a contrasting value for the selection background—preferably use $sources['action'][0] (if isset) with the same lightness rule, otherwise fall back to $hex_map['--sf-color-text--on-base']; place these assignments alongside the other $hex_map entries in class-color-resolver.php so consumers get mark and selection text swatches.
🤖 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.
Inline comments:
In `@core/themes.css`:
- Line 152: The CSS variable declaration for --sf-color-text--secondary (and
similar occurrences at the other reported spots) violates
function-calc-no-unspaced-operator due to missing/incorrect spacing around
operators inside calc; update the calc expressions (e.g., in the
--sf-color-text--secondary rule using oklch(from var(--sf-color-neutral)
clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h)) to ensure a
single space on both sides of each operator (e.g., change "calc(l + 0.1 +
var(...))" to "calc(l + 0.1 + var(...))") and apply the same spacing fix to the
other affected declarations referenced in the review.
In `@docs/dark-mode.md`:
- Around line 98-103: The CSS snippet uses invalid nesting `:root&`; replace it
by explicitly writing the selectors instead of using `&`: update the rule that
targets forced dark and OS-dark fallback to use explicit selectors such as
`[data-theme="dark"]` and `:root:not([data-theme])` combined with `@media
(prefers-color-scheme: dark)` (i.e., write the full selector for the inner rule
rather than `:root&`) so the variable assignment for `--sf-color-primary` is
applied correctly in both the forced dark case and the prefers-color-scheme
fallback.
---
Nitpick comments:
In
`@plugins/SLASHED-for-WP/integrations/bricks/includes/class-color-resolver.php`:
- Around line 312-357: Add generation for the two missing swatch tokens: if
isset($sources['warning']) set '--sf-color-mark-text' using the same lightness
rule as the on-family loop (use $sources['warning'][0] < 0.6 ? $light_text :
$dark_text) so it contrasts with the mark background (mark-bg uses
$warning_rgb), and set '--sf-color-selection-text' to a contrasting value for
the selection background—preferably use $sources['action'][0] (if isset) with
the same lightness rule, otherwise fall back to
$hex_map['--sf-color-text--on-base']; place these assignments alongside the
other $hex_map entries in class-color-resolver.php so consumers get mark and
selection text swatches.
🪄 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 Plus
Run ID: 8abc0863-9749-4303-bc03-4c9000fb46ac
📒 Files selected for processing (7)
core/themes.csscore/tokens.cssdocs/dark-mode.mddocs/theming.mdoptional/theme-example.cssplugins/SLASHED-for-WP/integrations/bricks/data/inventory.jsonplugins/SLASHED-for-WP/integrations/bricks/includes/class-color-resolver.php
- themes.css: remove double spaces in three calc() expressions that tripped stylelint function-calc-no-unspaced-operator - dark-mode.md: replace invalid :root& CSS nesting with explicit :root[data-theme="dark"] + @media fallback selector pair (CodeRabbit) - docs/tokens.md, docs/registry.json, inventory.json: regenerate after the status-family shade scale addition (docs were stale) - tests/token-api.snapshot.json: advance snapshot to include the 100 status-family shade tokens (danger/error/info/success/warning 50-950 + semantic aliases) — intentional API expansion, no removals https://claude.ai/code/session_01JLvpeyEzNZtgc7TVjVMhzu
Summary
A comprehensive pass over the SLASHED color system touching the core framework CSS, the Bricks builder integration, and the documentation. All changes are additive; nothing public is removed or renamed.
1. Bricks variable-picker swatch coverage
All
--sf-color-*tokens now have hex swatches in the variable-picker dropdown.Missing semantic tokens added to
class-color-resolver.php:bg--hover/active/selected/focus/disabled— neutral/action mixed over white at the token's effective alphaborder--subtle/strong/focus/disabled/translucent— neutral-source oklch with the CSS L-clamp offsetslink/link--hover/link--active/link--visited— action-source oklch with light-mode lightness clamps; visited uses the CSS +60° hue shifttext--on-*— L-threshold check (< 0.6 → near-white, ≥ 0.6 → near-black) for all 11 familieswell/raised/inverse/overlay— base-source oklch with ±0.02/+0.04/inverted-Lsuccess/warning/error/info/danger -strong— source L minus the same offsets as the CSS formula (-0.15 success, -0.25 warning, -0.10 error/info/danger)dim,code-bg/text,heading,mark-bg,selection-bgShade generation switched from sRGB to oklch interpolation:
Before: mixed source hex toward a dark-navy text color in sRGB → purple hue drift on cool palettes.
After: interpolates L and C toward white (light steps) or black (dark steps) in oklch space — perceptually uniform, no hue drift regardless of source hue.
2. Perceptually-uniform shade scale (
core/tokens.css)Adds 11 × 20 = 220 new tokens, two groups per family:
Numeric palette (50–950) — built with
color-mix(in oklch, source X%, white/black). Reference the-lightsource so they are stable across dark mode (Tailwind convention — pick a different step in dark mode if needed):Semantic aliases — reference the adaptive
--sf-color-{family}token so they automatically shift in dark mode:Inventory fallback (
data/inventory.json) updated from 631 → 731 variables.3. Section-level
[data-theme]— now fully works (core/themes.css)Root cause:
light-dark()resolves when a property is declared (on:root), not when it is inherited. A<section data-theme="dark">only setcolor-schemeand--sf-is-dark— every color token inherited from:rootstayed baked at the root's light values.Fix: Added an
@supports (color: oklch(from red l c h))block that re-declares all 35 mode-sensitive tokens directly on[data-theme="dark"]and[data-theme="light"]elements using explicit formulas (the dark/light sides of the originallight-dark()calls extracted and mirrored). Covered groups:Graceful degradation: Chrome < 119, Safari < 17.2, Firefox < 128 skip the block —
color-schemeand--sf-is-darkstill flip correctly, only the explicit token re-declarations are absent.Usage — now just works out of the box:
4. Documentation
docs/dark-mode.md— recipes 3–8 expanded (section theming, single-value override, per-section brand, contrast boost); Gotchas section updated with browser compatibility notedocs/theming.md— added three-tier override guide (source token → -dark token → resolved token)optional/theme-example.css— section 3b: section-level dark/light theming usage noteTest plan
sf-color-*entries show a colored swatch (no plain-text rows among color tokens)sf-color-{success,warning,error,info,danger}-strongswatches are deep/saturated (darker than the base family color)data-theme="dark"to a<section>on a light page → confirm all text, background, border, and link colors invert correctly (not justcolor-scheme)data-theme="light"insidehtml[data-theme="dark"]→ confirm the nested section renders in full light modenpm run docs && git diff --exit-code docs/ plugins/→ no stale generated fileshttps://claude.ai/code/session_01JLvpeyEzNZtgc7TVjVMhzu