Design systems like Tailwind use 11-step PaletteRx Palette">shade scales (50, 100, 200 through 900, 950) for each color. Your PaletteRx palette provides the base colors. Generating the full shade scale from those bases requires a systematic approach to lightness manipulation.
The HSL Approach
The simplest technique: keep the hue (H) and saturation (S) constant and vary only lightness (L). Your PaletteRx primary at its original lightness becomes the 500 or 600 step. Lighter steps increase L progressively. Darker steps decrease L. This is fast and simple but produces uneven perceptual steps because HSL lightness is not perceptually uniform.
The OKLCH Approach
OKLCH is a perceptually uniform color space, meaning equal changes in its lightness value produce equal perceived changes in brightness. Shade scales generated in OKLCH look more evenly distributed than those generated in HSL. The technique: convert your base to OKLCH, fix the hue and chroma, and step the lightness evenly from near-white (L: 0.97) to near-black (L: 0.15).
Saturation Adjustment
In practice, the best shade scales also adjust saturation across the scale. Very light tints (50, 100) benefit from slightly higher saturation to avoid looking gray. Very dark shades (800, 900) benefit from slightly lower saturation to avoid feeling electric. The adjustment is subtle (5 to 10% variation) but noticeable.
Using CSS color-mix()
Modern CSS can generate shade variants without pre-computing: --primary-light: color-mix(in oklch, var(--color-primary) 30%, white); This blends your PaletteRx base color with white in the OKLCH space, producing a perceptually accurate light tint. You can generate an entire shade scale this way.
When to Pre-Compute vs. Generate
Pre-compute (store as explicit hex values) when you need exact control or when framework compatibility requires it. Generate with color-mix() when you want dynamic scales that update automatically when the base color changes. PaletteRx's exports give you pre-computed bases; CSS color-mix() lets you derive scales from them at runtime.