Zellio.io

CSS Theme Generator

Turn one brand colour into full light and dark themes with OKLCH ramps.

Processed locally — nothing is uploaded

About CSS Theme Generator

Ramps are built in OKLCH rather than HSL because OKLCH lightness is perceptual: the 300 step of a blue and the 300 step of a yellow look equally light, where HSL would make one glaring and the other muddy. Your exact colour lands in the ramp unchanged at the step nearest its lightness, so the swatch in the brand guide is the swatch in the code.

Pick a primary colour and, optionally, an accent, and the generator builds three eleven-step ramps — primary, accent and a neutral tinted towards the primary — then assembles them into a light theme and a dark theme with named tokens: background, surface, border, text, muted text, primary and its hover state, and the text colour that sits on each filled colour. The preview draws a card, a button, a link and an input in whichever theme is selected, and four contrast checks under it report whether the text in that theme reads.

The ramps follow the same shape as Tailwind's own palettes, running from a 50 that is nearly white to a 950 that is nearly black, with the most saturated steps in the middle. Chroma is not held constant along the ramp: the pale and dark ends are pulled towards grey, because a tint that keeps full saturation looks dyed and a shade that keeps it looks muddy. A muted base colour produces a muted ramp rather than being forced vivid, so the character of the colour you chose survives.

The neutral is derived from the primary's hue with a small amount of chroma. Pure greys next to a coloured brand look detached, as though the interface and the branding came from different projects; a neutral that leans a few degrees towards the primary reads as belonging to it. You can override it with any hex value if the brand has its own grey.

Text on a filled colour is chosen by measurement, not convention. For each filled token the generator compares white against the ramp's darkest step and uses whichever gives the higher contrast, so a light accent gets dark text and a deep primary gets white without you having to notice. The CSS export writes both themes — a :root block, a data-theme attribute block, and a prefers-color-scheme media query guarded so an explicit choice still wins — which is the pattern that behaves correctly for the three states a visitor can be in.

Learn how this works

Frequently asked questions

Why do the ramp steps not match the numbers in my design tool?

Step numbers are conventions, not measurements: every tool places 500 somewhere slightly different. Here the steps are lightness targets in OKLCH, and the colour you entered is placed at whichever step is nearest its own lightness, unchanged. If your brand colour is dark it may land at 700; that is the generator telling you the truth about the colour rather than relabelling it.

What is OKLCH and why not HSL?

OKLCH describes a colour by perceived lightness, chroma and hue. HSL's lightness is a formula over the RGB channels and does not match what the eye sees — HSL yellow at 50% is far lighter than HSL blue at 50%. Ramps built in HSL therefore look uneven; ramps built in OKLCH step evenly, which is what makes a palette look designed.

Can I use the exported CSS with Tailwind?

Yes, and the Tailwind export is the shorter route: it emits a theme.extend.colors block with the three ramps nested by step, so classes like bg-primary-600 work immediately. The CSS variables export suits any framework, and can be referenced from Tailwind through its arbitrary-value syntax if you prefer one source of truth.

The dark theme's primary looks lighter than the light theme's. Is that right?

Yes. A filled colour that reads well on white is too dark on a near-black background, so the dark theme uses a lighter step of the same ramp — 400 against 600 — and hovers go lighter still rather than darker. The contrast checks under the preview confirm the choice for your colours.

Is anything sent to a server?

No. Everything runs locally in your browser using standard web APIs — your text, files and inputs are never uploaded to a server, so the tool works even offline once the page has loaded.

Is it free?

Completely. There is no sign-up, no account, no watermark and no usage limit. The tool is supported by unobtrusive ads, not by selling or processing your data.

Pro Tips

  • Start from the colour in your logo, not a colour you like — the ramp will contain it exactly, and everything else derives from it.
  • Check the dark preview before you commit. Brands chosen on white frequently have a primary that vanishes against a dark surface until it is lifted a step.
  • Keep the accent genuinely different in hue from the primary; a second blue reads as a mistake, not an accent.
  • Copy a single ramp with the button beside it when you only need the shades, and the full export when you need the theme tokens too.
  • If the derived neutral looks too warm or cool, override it with a grey a few points towards the opposite hue rather than a pure #888 — pure grey is what makes interfaces look unfinished.

Common Use Cases

  • Setting up the colour tokens for a new product before any component is built, with light and dark handled from day one.
  • Turning a single approved brand colour into the tints and shades a component library needs for hover, focus, borders and backgrounds.
  • Adding a dark mode to an existing site by generating a palette that keeps the current primary.
  • Producing a Tailwind config for a client project from the two colours on their business card.
  • Checking whether a proposed rebrand colour can carry an accessible button label in both themes before the designers commit to it.

How It Compares

Tailwind's UI Colors generator and Radix Colors produce excellent ramps, and Radix in particular has thought harder about dark-mode pairing than a generator can; Realtime Colors previews a whole page rather than one card. What none of them combines is OKLCH ramps that keep your exact colour, a derived tinted neutral, both themes with the correct three-state CSS, and contrast checks on the result — in one place, without an account.

Related tools