Home · Accessible Palette Generator
Accessible Color Palette Generator
One brand colour in — a complete light + dark palette out, where every pairing is checked by the job it does. Generation here is constrained by construction: role colours are solved against their real neighbours until they pass, not generated first and apologised for later.
The short version: enter a colour; get primary and neutral scales plus eight assigned roles per theme (background, surface, body text, muted text, action, action label, border, focus ring, brand accent); every role pairing graded on the spot; failing edits repaired by moving lightness only; and an export whose semantic tokens contain only the pairings that pass.
Step 1 — Your brand colour
Type or pick one colour. The palettes below are built from it in OKLCH — never HSL — with every role colour solved against the colours it will actually sit on, in the light and dark themes at the same time.
Light theme — every role, graded
Dark theme — every role, graded
The scales behind the roles
Primary scale — your hue, solved step by step.
Neutral scale — the same hue at a whisper of chroma, for text, borders and grounds.
Step 2 — Every role pairing, graded by the job it does
The same grading the contrast matrix runs. Edit any swatch above and this list re-grades instantly — an edit that breaks a pairing is flagged, never silently fixed. A failing pairing carries its repair button: one click moves lightness only, holds the hue, and re-grades the whole palette.
Step 4 — Export the verified tokens
Semantic tokens point only at pairings that pass. Anything failing is left out and named in the file. The raw scales ship alongside, labelled as building material.
What "by construction" actually means
Most generators work in HSL, pick steps that look even, and leave contrast to luck. The luck runs out predictably: the mid-steps of a typical brand scale fail body-text contrast on white, and the dark theme is an afterthought inverted by eye. This generator works differently. Each role is a small search: starting from your hue in OKLCH, it walks lightness in small steps, converts each candidate to a real hex colour, measures that hex against the actual adjacent colours — background and surface, not a generic white — and stops at the softest candidate that clears the threshold for the role's job. Body text must clear 4.5:1 (and is aimed at 7:1 where the hue allows); muted text 4.5:1; borders, focus rings and the action's boundary 3:1 against both grounds they touch.
Because the verdict is always recomputed from the final hex, the palette cannot drift from its own grading: what is exported is what was measured. The methodology page publishes the formula and the hand-computed vectors this measurement is tested against — including the pair that displays 4.50 and still fails, which is the single most common way contrast tools mislead.
Editing, without the silent fixes
You can edit any role colour in place. The pairing list re-grades immediately, and if your edit breaks a pairing it stays broken on screen — flagged, with a repair button — rather than being quietly nudged back. Repair moves lightness only, in OKLCH, with the hue held, and after it applies, the whole palette re-grades so a fix that breaks a second pairing is visible in the same moment. That loop — generate, audit, repair, export — is the whole product; the contrast matrix runs the same audit on palettes you bring from elsewhere.
Palette generator questions
How is this different from a normal palette generator?
A normal generator picks colours that look good together and checks contrast afterwards, if at all. This one solves each role colour against the colours it will sit on while it generates: body text is searched along your hue until it measures at least 4.5:1 against the actual background and surface, borders and focus rings until they measure 3:1 against both grounds, in the light and the dark theme in the same pass. The generated palette opens already graded, and a fresh, unedited palette passes every role pairing by construction.
What happens to my brand colour if it cannot be used as-is?
It is never silently changed. If you lock it, the colour is assigned only to roles it can serve accessibly — a light brand yellow, for example, cannot carry white button text, so it may keep the action role with a dark label, or step aside to large text and graphics while a derived step from its own hue takes the action role. The tool states which happened, in plain words, at the top of the palette.
Why OKLCH and not HSL?
HSL lightness is not perceptual: two colours at the same HSL lightness can measure wildly different contrasts, so a scale built in HSL drifts in and out of compliance step by step. OKLCH lightness tracks perceived lightness far more evenly, which is what makes a whole scale solvable against fixed ratio thresholds — and it is also the space the repair step moves in, so generation and repair agree with each other.
Are the palettes really free, with no account?
Yes. There is no account, no paid tier and no upload: the palette lives in the page link itself, so the link is the save. The export statement in every downloaded file repeats the boundary that matters: measured ratios are working evidence for one part of accessibility conformance, not a certification of anything.