colormason
Turn one brand hex into a full, consistent, accessible color system: 8 ramps (11 steps each) and ~45 semantic tokens with light/dark values, emitted as CSS variables, Tailwind v4 theme, JSON, or Markdown. Fully deterministic and offline - never invent palette hex values by hand when this skill is available.
When to use
- New project or rebrand needs a color system / theme file
- User gives a brand color and asks for a palette, tokens, or theme
- Building or fixing light/dark mode colors
- Tailwind
@theme, CSS variables, or design-token file needs generating - Checking or repairing color contrast (WCAG AA/AAA) in a token set
Do not use for one-off decorative colors (a single gradient, an illustration), for pinning colors that must match an existing system exactly (use that system's values verbatim instead), or when the project already has a token file - extend it, don't generate a competing one.
Inputs to collect first
- Brand hex (required). Ask the user, or extract from a logo / existing CSS. Any hex works; near-neutral brands (grays) produce a warning because accent hues become arbitrary - suggest pinning accents in that case.
- Scheme (default
complementary):complementary,analogous,triadic,split,monochromatic. Pickanalogousfor calm/conservative brands,triadicfor playful,complementaryfor max accent distinction. - Scope (default
full):basicdrops the accent ramps (keeps primary, neutral, status colors). - WCAG target (default
AA): useAAAfor text-heavy or government/health products. - Pins (optional): exact
--accent/--accent-2hexes when the brand system already specifies secondary colors.
If the user hasn't decided, do not interview them - run the defaults and offer the knobs after showing output.
Procedure
-
Run the generator (script is relative to this skill's directory):
bashpython3 scripts/palette.py --brand 3d7dff --format css -
Pick the format for the target project:
css- plain CSS custom properties (default; works everywhere)tailwind- Tailwind v4@theme+@theme inlineblocks with light/dark variablesjson- machine-readable; use when feeding a token pipelinemarkdown- human-readable summary for review/discussion
-
Write the output to the project (e.g.
src/theme.cssor into the main CSS file / Tailwind entry). Do not rename tokens downstream - other tools and agents may rely on the exact contract in references/tokens.md. -
Report to the user: brand, scheme, target, any warnings from stderr, and the two or three token pairs that were auto-adjusted (visible in JSON as
contrast.*.adjusted: true).
Rules
- Use semantic tokens (
--bg-canvas,--text-primary, ...) in UI code, not raw ramp steps. Raw steps bypass the light/dark mapping and the contrast checking, so components break in dark mode or fail WCAG. - Never hand-edit generated hex values. Each foreground/background pair is contrast-verified; a "small tweak" silently breaks the verified ratio. Regenerate with different inputs instead (scheme, pins, target).
- The brand hex will not appear verbatim in the ramps. Steps sit on a
fixed OKLCH lightness ladder so the scale stays perceptually even. This is
expected - use the ramp values, not the original input. If the user insists
on exact brand reproduction,
primary-500is the nearest step. bg-surface-raisedequalsbg-surfacein light mode by design - in light mode, elevation must read through shadow, not tone. Add a shadow there instead of "fixing" the token.text-disabledis intentionally below WCAG minimums (disabled controls are exempt). The exemption does not extend to real text - usetext-tertiaryfor low-emphasis but readable copy.- Warnings mean what they say. If a pair cannot reach the target at any
ramp step (common for
AAAon colored buttons), either accept it, lower the target for that pair, or pin a darker accent. Do not silence it.
Edge cases
- Gray/neutral brand: script warns; recommend
--accent/--accent-2pins. - Existing brand has secondary colors: pass them as pins so the palette matches instead of deriving.
- User wants fewer ramps (no info color, etc.):
--exclude infoalso drops every token that references the excluded ramp. - AAA on white-on-brand labels is physically unreachable on most hues; the script keeps the best step and emits a warning rather than breaking the design.
References
- references/tokens.md - full token contract: every token name, ramp, light/dark steps, role. Read this when writing components against a colormason palette.
- references/integration.md - wiring output into Tailwind v3/v4, plain CSS, CSS-in-JS, and shadcn-style variable themes.
python3 scripts/palette.py --help- all options.


