Colour Scheme Generator
Enter one colour – get a complete scheme: three to five colours that sit harmoniously together, each in eleven steps, plus matching neutrals and status colours and the roles for light and dark mode. Ready to download for CSS, Tailwind, SCSS, Less, shadcn/ui and Material UI. Everything runs locally in your browser.
That is not a valid CSS colour value.
Colour scheme
Every colour in eleven steps. Click a swatch to copy its hex value; the outlined swatch is the step your input sits on.
Brand colours
Neutrals
Status colours
Preview
The same roles in both themes – this is the scheme in a real interface.
Which colour does what
The roles the preview above is built from. These are the exact names used in the export; click a swatch to copy its hex value.
| Role | Used for | Light | Dark |
|---|
Export
Ready to paste into your project.
Everything runs locally in your browser – nothing is uploaded.
How one colour becomes a scheme
It takes two separate steps, and it pays to keep them apart – most palettes fail precisely because they get mixed up.
First the hues. They follow a harmony rule: fixed angles on the colour wheel, measured from your base colour. This is classical colour theory, and it answers the question ofwhich colours go together.
Then the steps. Each of those colours is expanded into eleven steps from 50 (almost white) to 950 (almost black). What matters is that every colour follows the same lightness curve: only then is primary-600 exactly as dark asdanger-600, and only then can you swap one step for the same step of another colour without the layout falling apart.
The harmony rules at a glance
| Rule | Angles | Effect |
|---|---|---|
| Monochrome | always the same hue | Calm and coherent. Colours differ in chroma rather than hue – the safest choice when the brand has a single colour. |
| Analogous | ±30°, ±60° | Neighbouring hues. Feels natural and soft but carries little tension – a call to action barely stands out here. |
| Complementary | 180° | The opposite pole. Maximum contrast, ideal for "main colour plus signal colour". Quickly gets loud across large areas. |
| Split complementary | 150° and 210° | The two neighbours of the opposite pole instead of the pole itself. Keeps the tension but is far less harsh. |
| Triadic | 120°, 240° | Three evenly spaced hues. Lively and balanced; needs one clear lead colour, otherwise all three compete. |
| Tetradic | 60°, 180°, 240° | Two complementary pairs forming a rectangle. The richest rule – and the one most likely to turn restless. |
| Square | 90°, 180°, 270° | Four evenly spaced hues. Like the tetrad but symmetrical, and therefore a little more uniform. |
Why the steps are computed in OKLCH
HSL has a design flaw that bites exactly here: its "lightness" is a pure arithmetic value, not a perceived one. hsl(60 100% 50%) (a piercing yellow) andhsl(240 100% 50%) (a deep blue) share the same lightness value – the yellow dazzles, the blue is nearly black. A palette built on equal HSL steps is therefore visibly uneven, and its 500s are useless as an interchangeable set.
OKLCH (developed by Björn Ottosson in 2020, part of CSS Color Level 4 and supported by every current browser) fixes this: its L matches perceived lightness, and changing it does not shift the hue. That is exactly what the steps here rely on – they are produced by moving L alone along a fixed curve.
One consequence is visible at the ends: not every combination of lightness and chroma can be displayed on a screen. A saturated yellow at 5 % lightness simply does not exist. Rather than clipping the channels – which would distort the hue – chroma is reduced until the colour fits into sRGB again. That is why the scales run towards grey at both ends, and why 50 and 950 work well as background colours.
What else is in the scheme
Neutrals are not plain grey but carry a hint of the base colour – between 0.022 and 0.045 chroma in OKLCH. That is little enough to read as grey and enough to make surfaces and borders belong to the palette rather than sit beside it. For comparison: Tailwind's tinted slate sits at 0.046, its near-neutral zinc at 0.016. If you need pure grey, turn the tint off.
Status colours for success, warning, danger and info sit at fixed angles instead. Red for errors and green for success are learned meanings; an error message in teal would be harmonious but incomprehensible. All they take from your scheme is the chroma, so they do not look like foreign bodies.
The roles (--background, --foreground,--primary, --border, …) are the step that turns scales into a theme. A scale alone does not say which step is the page background and which is the text. For light and dark this mapping is not a mirror image: in dark mode the brand colour is taken one step lighter, because the same colour looks dull on a dark ground.
Keeping an eye on contrast
Every swatch shows its contrast ratio against the more legible of the two text colours on hover. The Web Content Accessibility Guidelines require 4.5:1 for body text (level AA) or 7:1 (AAA), and 3:1 for large text from 18 pt and for user interface components. As a rule of thumb for the generated scales: from step 600 upwards white text works, up to step 300 black text works; steps 400 and 500 are the grey area where it pays to check the number.
The export formats
| Format | Contains | Paste into |
|---|---|---|
| CSS variables | All scales as --color-primary-600 plus the roles for both themes | Any project without a framework |
| Tailwind v4 | A single @theme block | Straight into the stylesheet after @import "tailwindcss" – v4 no longer needs a config file |
| Tailwind v3 | theme.extend.colors with nested scales | tailwind.config.js |
| SCSS | Individual variables plus one map per scale | _colors.scss; the maps for @each loops |
| Less | Individual variables with @ | colors.less |
| shadcn/ui | The roles in oklch(), for :root and .dark | globals.css, replacing the existing colour block |
| Material UI | A createTheme() object with main/light/dark/contrastText | Your theme file |
Frequently asked questions
Why does my base colour look slightly different in the scheme?
Because the steps follow fixed lightness values and your input rarely lands exactly on one of them. The outlined swatch marks the step that comes closest. If you need the colour exactly, keep it as it is and let the scale supply only its surroundings.
Why aren't all colours identical under "monochrome"?
Because otherwise they would be. With an identical hue, chroma is the only thing left to distinguish them – the same hue, staggered in intensity. That is what makes a monochrome palette a palette.
Can I come back to a scheme?
Yes. "Copy link to this scheme" writes base colour, harmony, count and tint into the address – behind the #, which means that part is never sent to a server.
Is my input uploaded?
No. The entire computation is JavaScript in your browser; there is no server that could receive anything. The only things remembered are the harmony, count, tint and the export format you last used.
Related: the colour converter converts a single colour between HEX, RGB, HSL, OKLCH, Lab and CMYK and examines its contrast in detail.