A tonal palette keeps hue (H) and chroma (C) nearly fixed and splits only lightness (L) into 11 numbered steps — 50, 100, 200, … 900, 950. Lower numbers are lighter (50 is nearly white), higher numbers are darker (950 is nearly black) — that direction follows Tailwind CSS's convention.
Keeping the vividness from wobbling across steps is why this uses OKLCH's chroma (C) axis instead of HSL saturation. Try the same thing in HSL and the darkest steps (900s) usually look muddy; OKLCH keeps lightness and chroma independent, so that problem mostly goes away.
The demo below actually computes oklch(L% C H) fresh for every step. Chroma needs to taper down slightly at the extremes (50 and 950) to stay realistic — a color that is nearly white or nearly black simply cannot carry much chroma without the browser clamping it back into gamut.
When to use
Use it whenever a design-token system needs one brand hue expressed across many lightness steps, brand-50 through brand-950.