Repository navigation
feat(core): parse CSS Color 4 syntax - #206
Merged
Merged
Conversation
This was referenced Oct 6, 2026
Owner
Author
This was referenced Oct 6, 2026
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This was referenced Oct 6, 2026
|
This was referenced Oct 6, 2026
pbroom
force-pushed
the
feat/core-css-color-4-parsing
branch
from
October 7, 2026 23:28
1e39187 to
ebe8c51
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Oct 8, 2026
Owner
Author
pbroom
changed the base branch from
fix/core-input-validation
to
graphite-base/206
October 10, 2026 18:56
parse() now implements CSS Color 4 instead of a handful of regexes:
- The 148 named colors plus `transparent` (conversion/named-colors.ts,
packed into one `name:hex` string; `*grey` folds onto `*gray`).
- rgb()/rgba() and hsl()/hsla() in modern space syntax and legacy comma
syntax, percentages everywhere CSS allows them (rgb 100% = 255), and
plain numbers for hsl saturation/lightness.
- hwb(), lab(), lch() (CIE Lab D50), oklab(), oklch().
- color() with srgb, srgb-linear, display-p3, rec2020 (BT.1886 2.4
gamma, as current CSS Color 4 / colorjs.io), a98-rgb, prophoto-rgb,
xyz, xyz-d65 and xyz-d50, including values outside 0-1.
- Hue units deg/grad/rad/turn and negative hues; every parsed hue is
normalized to [0, 360), matching the Color type's documented range.
- `none` is a missing component and behaves as 0 (CSS's rule for
conversion); it is rejected in legacy comma syntax. Lab/OKLab
lightness and LCH/OKLCH chroma are clamped at parse time per spec.
New conversion/xyz.ts holds the CSS Color 4 float64 matrices (XYZ D65 ->
linear sRGB, Bradford D50 -> D65, Rec2020/A98/ProPhoto -> XYZ) and the
Lab -> XYZ D50 conversion. color(srgb) reuses the existing sign-extended
sRGB transfer function export (p3ToLinearP3Into) rather than a new one.
A final finiteness check rejects values that overflow inside a
conversion (color(srgb 1e300 0 0)).
Tests: reference-accuracy compares every new syntax (all named colors,
random lab/lch/hwb/hsl/rgb% and extended-range color() samples) against
colorjs.io; max observed error is ~5e-15 (tolerance 1e-9). fast-check
properties cover hue normalization in every unit and toCss(oklch) ->
parse round-trips.
Bundle size: `parse + toHex + contrastRatio` grows 2.64 kB -> 5.13 kB
and the everyday toolkit 2.69 kB -> 5.18 kB, so their budgets rise to
5.2 kB and 5.25 kB (~70 B headroom). The named-color table cannot be
tree-shaken out because parse('red') must work; it is ~1.3 kB gzipped,
the color() / Lab matrices ~0.6 kB, and the parser itself ~0.6 kB.
Other budgets are unchanged. README/docs claims updated accordingly.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
CSS Color 4 legacy rgb() needs all-number or all-percentage channels and legacy hsl() needs percentage saturation and lightness; #205 enforced this, and the CSS Color 4 parser accepted rgb(100%, 0, 0) and hsl(0, 100, 50). The modern space syntax still allows mixing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ecks Measured 5.25 kB (parse + toHex + contrastRatio) and 5.29 kB (everyday) gzipped after multiline arguments, the HSL saturation clamp and legacy comma-syntax validation. Co-Authored-By: Claude Opus 5.5 <[email protected]>
pbroom
force-pushed
the
feat/core-css-color-4-parsing
branch
from
October 10, 2026 18:59
ebe8c51 to
f92d170
Compare
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

parse() now implements CSS Color 4 instead of a handful of regexes:
transparent(conversion/named-colors.ts,packed into one
name:hexstring;*greyfolds onto*gray).syntax, percentages everywhere CSS allows them (rgb 100% = 255), and
plain numbers for hsl saturation/lightness.
gamma, as current CSS Color 4 / colorjs.io), a98-rgb, prophoto-rgb,
xyz, xyz-d65 and xyz-d50, including values outside 0-1.
normalized to [0, 360), matching the Color type's documented range.
noneis a missing component and behaves as 0 (CSS's rule forconversion); it is rejected in legacy comma syntax. Lab/OKLab
lightness and LCH/OKLCH chroma are clamped at parse time per spec.
New conversion/xyz.ts holds the CSS Color 4 float64 matrices (XYZ D65 ->
linear sRGB, Bradford D50 -> D65, Rec2020/A98/ProPhoto -> XYZ) and the
Lab -> XYZ D50 conversion. color(srgb) reuses the existing sign-extended
sRGB transfer function export (p3ToLinearP3Into) rather than a new one.
A final finiteness check rejects values that overflow inside a
conversion (color(srgb 1e300 0 0)).
Tests: reference-accuracy compares every new syntax (all named colors,
random lab/lch/hwb/hsl/rgb% and extended-range color() samples) against
colorjs.io; max observed error is ~5e-15 (tolerance 1e-9). fast-check
properties cover hue normalization in every unit and toCss(oklch) ->
parse round-trips.
Bundle size:
parse + toHex + contrastRatiogrows 2.64 kB -> 5.13 kBand the everyday toolkit 2.69 kB -> 5.18 kB, so their budgets rise to
5.2 kB and 5.25 kB (~70 B headroom). The named-color table cannot be
tree-shaken out because parse('red') must work; it is ~1.3 kB gzipped,
the color() / Lab matrices ~0.6 kB, and the parser itself ~0.6 kB.
Other budgets are unchanged. README/docs claims updated accordingly.
Part of a stacked set of PRs (#204 → #221) from the color-kit assessment. Validated per branch with
pnpm buildandpnpm test; lint, format, typecheck, size, artifact, preprod and agents checks pass at the top of the stack.🤖 Generated with Claude Code