Hue Codex converts accepted color input into one resolved sRGB fallback for shared tool logic, while conversion tools also report the authored source value when it differs from that fallback.
Hue Codex distinguishes the authored input from the resolved display value. If a user enters Lab, LCH, OKLab, or OKLCH, the converter preserves that authored value for source reporting and gamut notes, then resolves a displayable sRGB HEX fallback for contrast checks, palettes, exports, swatches, and other shared downstream logic. Display precision changes what users see, not the internal math used for decisions.
Accepted colors are resolved to an opaque sRGB HEX fallback before shared downstream tool logic runs.
Authored Lab/LCH/OKLab/OKLCH values are preserved as source metadata in conversion and gamut messaging, not as the canonical value for every downstream calculation.
HSL, HSV, and HWB are RGB-derived models; Lab/LCH and OKLab/OKLCH are perceptual or device-independent views of the same resolved color.
Lab and LCH use D50 Lab after adapting from sRGB D65 XYZ. OKLab and OKLCH use D65 XYZ.
Out-of-range RGB results are clamped when converted back to displayable sRGB.
Standards status
These badges identify which parts of this methodology are standards-backed, draft-track, Hue Codex-specific, approximate, or dependent on browser behavior.
StandardDraft standardBrowser-dependent
StandardStable standard or standards-backed behavior used as authority, such as WCAG 2.2 and broadly implemented CSS Color 4 behavior.
Draft standardDraft, candidate, or preview specification material, such as CSS Color 5 features or the Design Tokens draft; not treated as final authority.
Browser-dependentOutput depends on browser APIs, rendering, color management, canvas pixels, clipboard, download, or CSS support.
Formulas, choices, heuristics, and limits
This separates standards-based formulas from Hue Codex implementation decisions, product heuristics, and known limitations for this methodology.
Standards-based formulas
Formula, threshold, syntax, or data behavior taken from a cited standard or standards-backed source.
CSS Color 4 color-space definitions, sRGB linearization, XYZ conversion context, and Lab/LCH or OKLab/OKLCH coordinate behavior.
Stable CSS color syntax for HEX, rgb(), hsl(), hwb(), lab(), lch(), oklab(), and oklch() where supported by the tool.
Implementation choices
How Hue Codex chooses to parse, normalize, round, export, or sequence calculations.
Hue Codex distinguishes authored input from the resolved fallback: the authored Lab/LCH/OKLab/OKLCH string is preserved for source reporting in conversion tools, while shared downstream calculations use a displayable six-digit uppercase sRGB HEX fallback.
Lab and LCH are calculated through D65 to D50 adaptation; OKLab and OKLCH use D65 XYZ.
Precision modes affect output strings, while internal checks keep raw calculation values when thresholds matter.
Hue Codex heuristics
Product rankings, bands, labels, suggestions, or role hints that are useful guidance but not external standards.
Compact, readable, token, and detailed precision presets are Hue Codex output choices.
Fallback and summary wording are chosen to make handoff safer, not because a standard requires that exact wording.
Known limitations
Caveats, edge cases, browser dependencies, approximations, or contexts the method does not prove.
Converting an out-of-gamut perceptual color back to sRGB can clamp channels and hide lost chroma.
Browser rendering, color management, and unsupported notation can change what users actually see.
CSS Color 5 references are draft context and should not be treated as final standards authority.
Inputs and parsing
StandardBrowser-dependent
Hue Codex accepts common CSS-style color notation, including short and long HEX, rgb(), hsl(), hwb(), lab(), lch(), oklab(), and oklch() forms where the tool exposes typed input. Unsupported or incomplete input is rejected instead of guessed.
Alpha values can be displayed or exported by tools that ask for alpha, but most color-model comparison and conversion outputs resolve the base color as an opaque sRGB value.
Authored source versus resolved fallback
StandardBrowser-dependent
Canonical sRGB HEX means the resolved display fallback, not necessarily the full authored color. For sRGB-compatible input, the authored value and fallback describe the same color and only notation or rounding changes.
For Lab, LCH, OKLab, or OKLCH input outside sRGB, Hue Codex preserves the authored functional value for the converter source panel, detected-input reporting, gamut warning, and change note. The shared color object then uses the clipped sRGB HEX fallback for swatches, contrast, palette generation, color difference, copied HEX/RGB values, and most exports.
Hue Codex is therefore not claiming that an out-of-gamut authored Lab or OKLCH value survives unchanged through every tool. The preserved authored value explains the source and the loss; the resolved fallback is what most downstream calculations operate on.
How Hue Codex treats authored values and resolved fallbacks.
Situation
Preserved as authored input
Used for downstream logic
#4169E1 or rgb(65 105 225)
Equivalent sRGB value; notation may be normalized
#4169E1
In-gamut Lab/LCH/OKLab/OKLCH
Original functional value shown in source reporting
Equivalent resolved sRGB HEX fallback
Out-of-gamut Lab/LCH/OKLab/OKLCH
Original functional value shown with clipping and gamut notes
Clipped displayable sRGB HEX fallback
Input alpha
Detected and reported where the tool exposes alpha
Base color resolves to opaque sRGB unless that tool explicitly composites or exports alpha
Conversion path
Standard
HEX is normalized to six uppercase sRGB digits for the canonical display color.
sRGB channels are linearized before XYZ, Lab, OKLab, luminance, or contrast math.
XYZ D65 is derived from linear sRGB with the exact linear sRGB-to-XYZ D65 matrix listed below.
Lab and LCH are calculated from D50 XYZ after linear Bradford chromatic adaptation from D65; reverse conversion uses the D50-to-D65 Bradford matrix.
OKLab and OKLCH are calculated from D65 XYZ with the listed XYZ-to-LMS and LMS-to-OKLab matrices, then converted between Cartesian and polar forms for chroma and hue.
Precision and rounding
Hue Codex heuristic
Hue Codex rounds display strings according to the output mode. Compact modes use fewer places for readability; token and detailed export modes preserve more decimal places for repeatable handoff.
Rounding is applied at output boundaries. Tool checks such as contrast pass/fail use the raw values from the calculation path whenever the threshold matters.
Common display precision used across conversion tools.
Model
Typical display
RGB, HSL, HSV, HWB
Whole or short decimal component values depending on mode
XYZ
Up to six or seven decimal places in detailed modes
Lab and LCH
Up to five decimal places in detailed modes
OKLab and OKLCH
Up to seven decimal places for OK axes or chroma in detailed modes
Gamut and clamping
StandardBrowser-dependent
When a perceptual or device-independent value converts back to sRGB, output channels are clamped to the 0 to 255 display range. This makes the color displayable in the browser but can hide the fact that a theoretical color was outside sRGB.
The gamut methodology page explains why this is different from profile-aware color management or print proofing.
Validation checks
StandardBrowser-dependent
Representative conversion validation checks.
Input
Expected normalized behavior
Reason
#fff
#FFFFFF
Three-digit HEX expands channel pairs
#4169E1
rgb(65 105 225)
Royal-blue sRGB channel values
hsl(0 0% 100%)
#FFFFFF
Neutral white in HSL resolves to white
oklch values outside sRGB
Clamped sRGB display color
Browser display output must fit sRGB channels
Conversion equations
StandardBrowser-dependent
Hue Codex normalizes to sRGB HEX first, then derives the requested color-space views. These equations list the transfer functions, matrices, adaptation steps, and polar conversions used for sRGB, XYZ, D50 Lab/LCH, and D65 OKLab/OKLCH.
sRGB transfer functions and XYZ D65 matrices
# Inputs r8, g8, and b8 are encoded sRGB channels in [0, 255].
srgb_to_linear(c8):
v = c8 / 255
if v <= 0.04045: return v / 12.92
return ((v + 0.055) / 1.055) ^ 2.4
linear_to_srgb_channel(c):
if c <= 0.0031308:
encoded = 12.92 * c
else:
encoded = 1.055 * (c ^ (1 / 2.4)) - 0.055
return round(clamp(encoded, 0, 1) * 255)
M_srgb_to_xyz_d65 = [
[506752/1228815, 87881/245763, 12673/70218],
[87098/409605, 175762/245763, 12673/175545],
[7918/409605, 87881/737289, 1001167/1053270],
]
M_xyz_d65_to_srgb_linear = [
[12831/3959, -329/214, -1974/3959],
[-851781/878810, 1648619/878810, 36519/878810],
[705/12673, -2585/12673, 705/667],
]
rgb_to_xyz_d65(r8, g8, b8):
rgb_linear = [srgb_to_linear(r8), srgb_to_linear(g8), srgb_to_linear(b8)]
return M_srgb_to_xyz_d65 * rgb_linear
xyz_d65_to_rgb(X, Y, Z):
rgb_linear = M_xyz_d65_to_srgb_linear * [X, Y, Z]
return [
linear_to_srgb_channel(rgb_linear[0]),
linear_to_srgb_channel(rgb_linear[1]),
linear_to_srgb_channel(rgb_linear[2]),
]
Bradford D65/D50 adaptation, Lab, and LCH
D50 = [0.3457/0.3585, 1, (1 - 0.3457 - 0.3585)/0.3585]
D65 = [0.3127/0.3290, 1, (1 - 0.3127 - 0.3290)/0.3290]
M_d65_to_d50 = [
[1.0479297925449969, 0.022946870601609652, -0.05019226628920524],
[0.02962780877005599, 0.9904344267538799, -0.017073799063418826],
[-0.009243040646204504, 0.015055191490298152, 0.7518742814281371],
]
M_d50_to_d65 = [
[0.955473421488075, -0.02309845494876471, 0.06325924320057072],
[-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],
[0.012314014864481998, -0.020507649298898964, 1.330365926242124],
]
xyz_d65_to_d50(X, Y, Z):
return M_d65_to_d50 * [X, Y, Z]
xyz_d50_to_d65(X, Y, Z):
return M_d50_to_d65 * [X, Y, Z]
xyz_d50_to_lab(X, Y, Z):
Xn, Yn, Zn = D50
epsilon = 216/24389
kappa = 24389/27
f(t) = t > epsilon ? cbrt(t) : (kappa*t + 16)/116
fx = f(X / Xn)
fy = f(Y / Yn)
fz = f(Z / Zn)
L = 116*fy - 16
a = 500*(fx - fy)
b = 200*(fy - fz)
return L, a, b
lab_to_xyz_d50(L, a, b):
Xn, Yn, Zn = D50
epsilon = 216/24389
kappa = 24389/27
fy = (L + 16)/116
fx = a/500 + fy
fz = fy - b/200
finv(f) = (f^3 > epsilon) ? f^3 : (116*f - 16)/kappa
return [Xn*finv(fx), Yn*finv(fy), Zn*finv(fz)]
lab_to_lch(L, a, b):
C = sqrt(a*a + b*b)
H = normalize_degrees(atan2(b, a) * 180 / pi)
if C <= 0.0015: H = undefined
return L, C, H
lch_to_lab(L, C, H):
return [L, C*cos(H*pi/180), C*sin(H*pi/180)]
These vectors validate normalization, RGB-family conversion, Lab conversion, OKLab conversion, and a round trip back to the canonical sRGB HEX value.
Color conversion vectors.
Input
Expected output
Notes
#fff
#FFFFFF
Short HEX expands to six uppercase sRGB digits
#4169E1 to RGB
rgb(65 105 225)
Canonical sRGB channel values
#4169E1 to HSL
hsl(225 72.727273% 56.862745%)
RGB-derived hue, saturation, and lightness
hsl(225 72.727273% 56.862745%) to HEX
#4169E1
HSL round trip returns the source HEX after channel rounding
#4169E1 to HWB
hwb(225 25.490196% 11.764706%)
RGB-derived whiteness and blackness
#4169E1 to Lab
lab(46.800061 17.782586 -66.657521)
D65 sRGB converted through D50 Lab
#4169E1 to OKLab
oklab(0.559848187 -0.011820607 -0.187862028)
D65 XYZ to OKLab
Sources and standards
These references anchor the public standards and formats used by Hue Codex. Status badges distinguish stable standards, drafts, Hue Codex heuristics, approximations, and browser-dependent behavior.