Skip to content

All tools (41)

JSON 6
Time & Date 4
Encoding & Decoding 4
Generators 3
Text & Data 4
Logs & Debugging 1
Config & Infra 3
Security & Hashing 4
Color & Design 5
Numbers & Bits 3
Web & Markup 4

Nothing leaves the cave.

Nothing you paste ever leaves your device. There is no server to send it to.

How you can check →
DevToolsCave

    This tool runs entirely in your browser. Nothing you paste is uploaded.

    How you can check →

    Color Scale Generator

    Color & Design

    Turn one seed color into a 50-950 tint/shade ramp with even OKLCH lightness steps, an explicit chroma taper, and a contrast matrix — entirely in your browser.

    Seed color

    Any CSS color syntax — hex, rgb(), hsl(), oklch(), a named color. Hue and chroma come from this color; only lightness is re-targeted per step.

    The ramp

    Even OKLCH lightness steps, hue held fixed. "Mapped" means sRGB couldn't hold the target chroma at that lightness and this page reduced it in OKLCH to fit.

    Contrast matrix

    Row = text, column = background

    Green = passes AA normal text (≥ 4.5:1). A failing pair here is exactly what the contrast checker's repair is for.

    Export

    CSS custom properties
    Tailwind v4 @theme
    JSON

    Started from a color you're already converting? Use the color converter — its tint/shade preview links straight back here with the seed filled in.

    Why every step targets a fixed lightness, not the seed's own

    Step 500, and every other step, targets a fixed OKLCH lightness — 55% for 500, tapering to 98% at 50 and 14% at 950 — regardless of how light or dark the seed color you typed in is. Only hue and the seed's own chroma carry through unchanged. That's a deliberate choice: if 500 sat wherever the seed's own lightness happened to fall, a light seed and a dark seed would produce differently-shaped ramps, and "step 700" would stop meaning the same lightness from one color to the next. This is the same shape every mainstream token scale (Tailwind, Radix) uses, for the same reason.

    Why the chroma taper exists, and why it can't be avoided

    Constant chroma cannot survive near OKLCH lightness 0 or 1 — sRGB simply doesn't have the gamut to hold much saturation at near-white or near-black. A scale that doesn't taper chroma on purpose gets it tapered anyway, silently, by gamut mapping flattening the extreme steps into indistinguishable grey. This page tapers chroma explicitly as a fraction of the seed's own chroma — full strength around 500, falling off toward both ends — and then still runs every step through CSS Color 4 gamut mapping (chroma reduction in OKLCH, never per-channel RGB clipping, which shifts hue) and reports which steps needed it and by how much.

    Why OKLCH steps look even and HSL steps don't

    hsl(60 100% 50%) (yellow) and hsl(240 100% 50%) (blue) both claim 50% lightness, but their real WCAG relative luminances are 0.93 and 0.07 — an 8:1 contrast difference between two colors HSL calls equally light. A ramp built by walking HSL lightness inherits that lie: some hues visibly jump in brightness between steps while others barely move. OKLCH's lightness channel is built specifically to track perceived lightness, so stepping it evenly produces steps that actually read as evenly spaced, whatever the hue.

    What the contrast matrix is actually for

    A color scale exists to answer one question repeatedly: which step can sit on which other step and still be legible? The matrix runs every step of the ramp against every other step at WCAG AA and AAA, so that question is a lookup instead of round-tripping pairs through a separate contrast checker one at a time — the real workflow a design system's color scale gets used for.

    Common use cases

    • Turning one brand hex into a full Tailwind v4 @theme token scale
    • Picking a text/background pair from the same brand ramp that's guaranteed to pass AA
    • Checking which of a ramp's steps had to be gamut-mapped, and by how much chroma
    • Exporting the same scale as CSS custom properties or JSON for a non-Tailwind pipeline
    • Generating a passing tint or shade for a pair that failed in the contrast checker

    Frequently asked questions

    Why isn't step 500 always the seed color I typed in?
    Every step, 500 included, targets a fixed OKLCH lightness — 55% for 500 — rather than the seed's own lightness. That's what keeps the whole ramp a ramp: if 500 sat wherever the seed happened to be, a light seed and a dark seed would produce differently-shaped scales, and the 50-950 numbers would stop meaning the same lightness across colors. Hue and the seed's own chroma still drive every step; only the lightness targets are fixed.
    What does 'mapped' mean under a step, and why does it happen more at the ends?
    It means that step's target chroma didn't fit in sRGB at that lightness, so this page reduced chroma in OKLCH (never per-channel RGB clipping, which shifts hue) until it did, and reports exactly how much chroma was given up. sRGB simply can't hold much chroma very close to white or black, so steps 50, 100, 900 and 950 taper chroma on purpose and still get mapped more often than 500 — this page shows that rather than silently flattening those steps to grey.
    Why does the ramp use OKLCH lightness instead of HSL lightness?
    Even steps in HSL lightness don't look even — HSL's 'L' is a geometric average of the RGB channels, not a measure of how light a color actually looks, so an HSL-walked ramp visibly jumps in brightness through some hues and barely moves through others. OKLCH's lightness channel is built to track perceived lightness, so stepping it evenly produces steps that actually look evenly spaced.
    What is the contrast matrix actually for?
    It's the real question a design system gets asked: 'which of my ramp's steps can I put text in front of another step and still pass?' Rather than checking pairs one at a time in a separate contrast checker, this shows every step against every other step at once, so picking a text/background pair from the same brand ramp is a lookup instead of trial and error.
    Can I use this scale in Tailwind?
    Yes — the Tailwind output is a v4 `@theme` block defining `--color-<name>-<step>` custom properties, which Tailwind v4 automatically turns into utilities like `bg-<name>-500` and `text-<name>-700`. The plain CSS custom properties and JSON outputs cover everything else: a `:root` block for any CSS setup, or a JSON object for a JS design-token pipeline.