1 — Start with constraints
Good color systems start from a small set of rules, not from a mood board. Before you pick a hue, decide what the interface must do: read clearly, feel calm, and point the eye at one action.
- Pick one accent. Everything else is neutral.
- Square corners and flat surfaces read as deliberate. Rounded everything reads as a template.
- Write copy without emoji. Emoji date quickly and fight with your palette.
- Design in grayscale first. If the layout fails in grayscale, color will not save it.
2 — Hue, saturation, lightness
HSL is the easiest mental model for a color wheel. Hue is the angle (0–360 degrees), saturation is the purity, and lightness is how close the color is to black or white.
- Hue carries the emotion. Blue reads calm, red reads urgent, green reads success.
- Saturation carries the energy. A 90% saturated accent is loud; the same hue at 45% is a quiet neutral.
- Lightness carries hierarchy. Vary lightness to separate sections before adding a second hue.
A reliable accent for UI sits around 50–65% lightness and 55–90% saturation: bright enough to pop on a dark surface, dark enough for white text on top.
3 — Harmony and tone
Harmony is the relationship between hues. Choose it from the job the screen has to do, not from taste alone.
- Monochrome — one hue, many lightness steps. The safest choice for dashboards and reading.
- Analogous — neighbours on the wheel (within about 60 degrees). Cohesive and warm.
- Complementary — opposite hues (180 degrees). High contrast, good for a single call to action.
- Triadic — three hues 120 degrees apart. Lively but risky; keep two of them small.
- Tetradic — four hues in two opposite pairs. Best for editorial or playful work.
- Neutral — a desaturated accent over a gray base. Lets the layout carry the design.
4 — Name your tokens
A token is a name for a decision. Nobody should guess what --accent means: it is the color for links, focus rings, and the primary button. Map roles, not raw colors, and the theme can change underneath the component.
--accent— links, focus, primary button, active state.--background— the page. Usually the largest surface.--surface— cards, inputs, raised panels.--text— primary copy on background and surface.--muted— captions, helper text, secondary metadata.--border— hairlines and dividers.
One accent plus five neutrals is enough for most products. Add a second accent only when you have a real second action.
5 — Contrast and WCAG
Contrast is measured as a ratio from 1:1 to 21:1. WCAG asks for a minimum of 4.5:1 for normal text, 3:1 for large text (18px bold or 24px regular), and 3:1 for UI component edges.
- 7:1 or more — AAA. Comfortable for long reading.
- 4.5:1 or more — AA. The baseline for body text.
- 3:1 or more — AA Large. Headlines and icons only.
- Under 3:1 — fails. Do not ship text or controls at this ratio.
Never put white text on a mid-tone accent without checking. The wheel gives you the hue; the contrast badge tells you whether the pair is readable. If it fails, darken the accent or switch the label to near-black.
6 — Dark mode rules
Dark mode is not the light palette inverted. Invert it and everything turns muddy. Build a separate set of neutrals and keep the accent fixed so the brand reads the same.
- Use a near-black background (about 5–8% lightness), not pure black. Pure black causes smearing on OLED and harsh edges.
- Raise surfaces by lightness, not by shadow. Shadows are weak on dark backgrounds.
- Pull text down from pure white to around 92–94%. Full white vibrates against dark gray.
- Keep the accent the single bright element. If everything glows, nothing does.
- Reduce hue tinting in neutrals: 4–8% saturation is enough to feel cohesive.
7 — Type and spacing
Type and spacing do most of the work in a clean interface. Set them on a scale and stop eyeballing.
- Use a 4px or 8px spacing scale. Every margin and padding should be a step on it.
- Keep body text at 16px or larger, with a line height around 1.5–1.6.
- Limit the measure to 60–75 characters per line for comfortable reading.
- Use at most two type families: one for display, one for body or mono labels.
- Uppercase mono labels with wide letter-spacing read as system UI. Use them for metadata, not paragraphs.
8 — Buttons and states
A button is a promise. Make the primary action obvious, keep every state visible, and do not hide focus.
- Square corners (radius 0) when the brand asks for precision. Rounded corners when it asks for friendliness. Do not mix.
- Primary: accent background with readable text. Secondary: border only. Tertiary: text only.
- Every control needs hover, focus-visible, active, and disabled states.
- Focus rings are not decoration. A 2px accent outline with an offset is enough.
- Targets should be at least 44 by 44 pixels on touch.
9 — Accessibility checklist
- Body text contrast at 4.5:1 or better; large text at 3:1 or better.
- Never encode meaning with color alone. Pair color with a label or an icon plus text.
- Focus is always visible and keyboard order follows the reading order.
- Form fields have labels, not just placeholders.
- Motion respects
prefers-reduced-motion. - Text stays readable at 200% zoom.
10 — Ship the blueprint
A blueprint is the handoff. It should answer three questions without a meeting: what are the colors, where is each one used, and does it pass contrast.
The studio exports w-blueprint.md with a light and dark token table, a plain-CSS variables block, a WCAG table, and a JSON block. Hand it to a developer, paste it into a design tool, or give it to an AI agent as the single source of truth for the palette.
Then build the real thing: replace the placeholder copy, test the states you designed, and check the page in both modes on a phone. The blueprint is the plan, not the product.
Ready to try it? Open the studio and build a palette.