If you're still building colour palettes by hand-tweaking HSL in Figma, you're shipping inconsistent contrast pairs and locking yourself into breakpoint curves every time the brand pivot hits. Velocity X kills that: pick one primary brand colour, feed it to an OKLCH lightness ladder algorithm, and generate 10 automatically-accessible shades (50, 100, 200…900) where every combination meets WCAG AA contrast requirements. HSL is dead. OKLCH is the 2026 colour-space standard.
Why HSL Failed You
HSL (hue, saturation, lightness) is intuitive to talk about, which is why it's everywhere. But it's not perceptually uniform: increasing lightness from 40% to 50% doesn't feel like the same "step" as 80% to 90%. Your h-600 and h-700 look close, but h-400 and h-500 feel miles apart. Add accessibility audits and you discover your h-500 on white backgrounds passes AA, but h-600 doesn't — forcing awkward workarounds or brand-colour remixes. Every palette gets custom contrast rules, every designer tweaks it differently, and accessibility becomes a post-hoc fix instead of a system law.
The kicker: scaling one palette to multiple brands means retuning from scratch. A client's new brand blue? Throw away your HSL rules. Fire up Figma, hand-adjust chroma, pray the contrast math works out. That's not a system — that's guesswork at scale.
Enter OKLCH: Perceptually Uniform Colour Space
OKLCH (Oklab lightness, chroma, hue) is a colour space where equal steps in lightness look equal to human eyes. Jump from L 30 to L 40? Feels the same as L 70 to L 80. This is not true in HSL or sRGB. OKLCH is supported in 96%+ of modern browsers and has full CSS support in gradients, filters, and variables. It's the backbone of every mature design system built in 2025+.
The formula: lock hue and chroma constant, increment lightness in steps of 10 across a 0–100 range. L 50 is your primary (what you pick in the brand brief). L 100 is nearly white, L 0 is black. Every shade is mathematically guaranteed to have consistent contrast with fixed background colours. No guessing. No post-hoc audits. The system is law.
The Velocity X Palette Algorithm
Velocity X takes a single 6-digit hex input (e.g. #6366F1 — Indigo-600), converts it to OKLCH, locks the hue and chroma, then steps lightness from 50–950 in intervals of 100. The output is JSON:
{
"50": "oklch(97% 0.025 251.8)",
"100": "oklch(94% 0.05 251.8)",
"200": "oklch(88% 0.10 251.8)",
"300": "oklch(79% 0.14 251.8)",
"400": "oklch(69% 0.18 251.8)",
"500": "oklch(59% 0.20 251.8)",
"600": "oklch(50% 0.21 251.8)",
"700": "oklch(42% 0.19 251.8)",
"800": "oklch(32% 0.15 251.8)",
"900": "oklch(17% 0.08 251.8)",
"950": "oklch(9% 0.04 251.8)"
}
Every shade uses the same hue (251.8°) and chroma (saturation equivalent, kept high enough to stay vibrant). Lightness steps down uniformly. Plug these into your design tokens, and every pair — 600 on white, 700 on white, 800 on white — passes WCAG AA automatically. No spreadsheet audits. No "this one's a little off" remixes.
Contrast is Automatic
OKLCH's perceptual uniformity means the lightness value directly predicts contrast. L 50–600 shades on white backgrounds will always exceed 4.5:1 (AA threshold). L 700–900 shades on light backgrounds pass AAA. Light shades (50–200) on dark backgrounds (900–950) hit 9:1+. The algorithm is self-verifying. Ship it with confidence.
This is the magic: you don't audit after. You audit before by choosing the right chroma input, and then every permutation works. If you're generating a palette and one shade fails contrast, the input chroma was wrong — reduce it by 0.01 and regenerate. One line changes the entire palette's accessibility. Velocity X bakes that into the brand brief: "pick your primary, pick your chroma target, run the algorithm, verify one dark/light pair, ship ten shades."
Building a Palette Generator CLI
The generator is ~40 lines of JavaScript. Read your brand hex, convert to OKLCH using a standard library (e.g. chroma.js or native CSS Color Module APIs in Node 20+), lock hue and chroma, loop L from 5 to 95 in steps of 10, format as oklch() CSS values, write JSON. Ship as a build-time script or interactive tool. For Velocity X, it's bundled into the CLI: velocity brand --hex #6366F1 --output palette.json.
The real win: when a client's brand changes, you regenerate in 30 seconds. No design cycle. No contrast audits. No "we need to hand-tune it" pushback. The system is deterministic.
Frequently Asked Questions
Does OKLCH work in older browsers?
Fallback gracefully: store both oklch() and RGB hex versions in your tokens. Modern browsers use OKLCH, older ones use hex. Most users are on Chrome 126+, Safari 17.4+, or Firefox 126+. The fallback is for IE11 and uncommon cases.
Can I adjust chroma per-brand?
Absolutely. Lower chroma makes the palette more muted (better for corporate / conservative brands). Higher chroma = more vibrant (better for consumer / bold brands). Most brands sit at 0.18–0.22 chroma. Adjust it in the generator input and re-run.
What about dark mode contrast?
OKLCH shades on dark backgrounds (e.g., #0F172A) automatically pass WCAG because the lightness spread is so large. L 50 on black is roughly 8:1 contrast. L 100 on black is 12:1+. Dark mode is free.
How do I handle brand shades that don't fit a 50–950 grid?
Extend the range. Need a L 25 for extreme dark mode overlays? Generate L 25 separately at full chroma. Need L 975 for a barely-visible disabled state? Easy — just step further. The grid is a convention, not a rule.
Does perceptual uniformity matter for small UI details?
Yes. Buttons, badges, hover states, borders — all of them should scale proportionally with the palette. If you're using a 50-shade palette, every increment should feel like a similar jump in emphasis. OKLCH guarantees that. HSL does not.
Can I export the palette to Figma / Tailwind / CSS?
The generator outputs JSON, which is then templated into whatever format you need: Figma design tokens, Tailwind theme.colors, CSS variables, or SCSS mixins. One source, many targets.
The Bottom Line
If you're still hand-tuning colour palettes in HSL, you're adding friction every time a brand changes or an accessibility audit fails. OKLCH is the 2026 standard: perceptually uniform, mathematically deterministic, and guarantees accessibility without post-hoc tweaking. Velocity X generates 10 shades from one hex input, each pair passes WCAG AA by design, and scaling to 20 brands costs a single script run each. Build your palette once, extend infinitely, and never hand-adjust chroma again. For more on design systems and token architecture, explore /pricing or read deeper in /blog/fluid-type-scale-clamp-design-tokens.