/color-scale
Generate a 10-step OKLCH color scale (steps 50–900) from any seed color. Accepts a hex value, a CSS named color, or a theme role name resolved from the project’s existing light.css. Output is a :root { … } CSS block with var(--color-<name>-N, <hex>) fallbacks plus a Markdown table of hex and OKLCH values per step.
Syntax
Section titled “Syntax”/color-scale <color> [--name=<name>] [--format=css|json|both]Arguments
Section titled “Arguments”| Argument | Required | Description |
|---|---|---|
color | Yes | Seed color as #rrggbb, CSS named color (red, cornflowerblue), or theme role name (background, primary, surface) |
--name | No | CSS variable prefix used in output (e.g. --color-<name>-50). Defaults to the role/color name, or scale for raw hex input. |
--format | No | Output format: css, json, or both (default: both) |
Examples
Section titled “Examples”Generate a scale from a hex color:
/color-scale "#4f46e5"Generate a scale from the project’s primary theme role:
/color-scale primaryGenerate a scale from a CSS named color with a custom variable name:
/color-scale cornflowerblue --name=blueOutput CSS only (ready to paste into a stylesheet):
/color-scale "#4f46e5" --name=brand --format=cssWorkflow
Section titled “Workflow”-
Resolve the seed color to hex. The command accepts three input forms:
- Hex (
#rrggbbor#rgb) — used directly. - Theme role name (
primary,background,surface, etc.) — looks up the project’slight.css, greps for--color-<role>:, and extracts the hex fallback from thevar(--color-<role>, <hex>)declaration. If no theme file is found, halts with: “No theme file found. Run /theme-create first or pass a hex value directly.” - CSS named color (
red,cornflowerblue,tomato, etc.) — resolved to hex using the W3C CSS Color 4 named-color table.
- Hex (
-
Run
generate_color_scale.py. Callsscripts/generate_color_scale.py <hex> --name=<name> --format=bothand captures stdout. On a non-zero exit code, prints the stderr message and halts. -
Display results. Output is presented in this order:
- CSS block — the
:root { … }block ready to paste or write to a file. - Scale table — a compact Markdown table of all 10 steps.
- CSS block — the
-
Write to file (optional). If you ask to save the output, the command writes to the path you specify. Otherwise it displays only — no files are written unless you explicitly request it.
Output format
Section titled “Output format”The default --format=both output contains two sections separated by a blank line — JSON first, then CSS:
{ "name": "primary", "seed": "#4f46e5", "seed_oklch": { "L": 0.4823, "C": 0.2108, "H": 264.05 }, "steps": [ { "step": 50, "hex": "#f5f3ff", "oklch": "oklch(0.965 0.0213 264.1)", "css_var": "--color-primary-50" }, ... { "step": 900, "hex": "#1e1b4b", "oklch": "oklch(0.141 0.0812 264.1)", "css_var": "--color-primary-900" } ]}
:root { --color-primary-50: var(--color-primary-50, #f5f3ff); --color-primary-100: var(--color-primary-100, #ede9fe); --color-primary-200: var(--color-primary-200, #ddd6fe); --color-primary-300: var(--color-primary-300, #c4b5fd); --color-primary-400: var(--color-primary-400, #a78bfa); --color-primary-500: var(--color-primary-500, #8b5cf6); --color-primary-600: var(--color-primary-600, #7c3aed); --color-primary-700: var(--color-primary-700, #6d28d9); --color-primary-800: var(--color-primary-800, #5b21b6); --color-primary-900: var(--color-primary-900, #4c1d95);}The displayed scale table:
| Step | Hex | OKLCH |
|---|---|---|
| 50 | #f5f3ff | oklch(0.965 0.0213 264.1) |
| 100 | #ede9fe | oklch(0.935 0.0427 264.1) |
| … | … | … |
| 900 | #1e1b4b | oklch(0.141 0.0812 264.1) |
Scale steps
Section titled “Scale steps”The 10 steps use perceptually distributed OKLCH lightness targets while preserving the seed’s chroma and hue:
| Step | Lightness target | Typical use |
|---|---|---|
| 50 | 0.970 | Near-white tint, backgrounds |
| 100 | 0.935 | Light surface |
| 200 | 0.875 | Hover surface |
| 300 | 0.785 | Subtle border |
| 400 | 0.670 | Disabled state |
| 500 | 0.550 | Mid-tone |
| 600 | 0.435 | Default interactive |
| 700 | 0.335 | Hover interactive |
| 800 | 0.235 | Active / pressed |
| 900 | 0.135 | Near-black, high contrast |
Colors that fall outside the sRGB gamut at a given lightness are clamped. The JSON output includes a clamped boolean and a reasons array per step so you can see where gamut clamping occurred.
CSS variable convention
Section titled “CSS variable convention”All output variables follow the var(--x, <fallback>) convention required by acss-kit. This means every variable is self-documenting — the fallback hex is the computed value at generation time, and the variable can be overridden at any :root scope without removing the safety net.
Error handling
Section titled “Error handling”| Situation | Action |
|---|---|
Theme role not found in light.css | Halt: "--color-<role> not found in <file>. Check the role name or pass a hex directly." |
| No theme file in the project | Halt: "No theme file found. Run /theme-create first or pass a hex value directly." |
| Invalid hex value | Halt: "<value>" is not a valid hex color. Use #rrggbb or #rgb. |
generate_color_scale.py exits non-zero | Print stderr and halt |
Backing script
Section titled “Backing script”/color-scale delegates to scripts/generate_color_scale.py. See the Python Scripts reference for the full CLI contract, JSON output shape, and exit codes.