3.0 KiB
Color craft rules
Universal color rules applied on top of the active DESIGN.md. The
design system supplies the palette tokens; this file enforces how to
use them.
Adapted from refero_skill (MIT). All examples reference Open Design's standard tokens (
--bg,--surface,--fg,--muted,--border,--accent).
Palette structure
A coherent palette has four layers. Plan all four before writing any CSS.
| Layer | Share of pixels | Tokens |
|---|---|---|
| Neutrals | 70–90% | --bg, --surface, --fg, --muted, --border |
| Accent (one) | 5–10% | --accent only — never invent a second accent |
| Semantic | 0–5% | --success, --warn, --danger |
| Effect | <1% | gradients, glows; rarely justified |
Accent discipline
The single biggest readability failure in AI-generated UIs is accent overuse. Hard caps:
- At most 2 visible uses of
--accentper screen. Typical pair: one eyebrow / chip + one primary CTA. Or one accent card + one tab pill. Pick a pair, not a flood. - Links count as accent; demote to
--fgunderline if you also have a CTA on the same screen. - Hover/focus rings count as accent. Ration accordingly.
Contrast minimums
Run these as gates, not goals:
| Pair | Minimum |
|---|---|
| Body text (≤16 px) on background | 4.5:1 |
| Large text (>18 px or 14 px bold) | 3:1 |
| UI components against adjacent surfaces | 3:1 |
When the brand color clashes (low-contrast indigo on light background is
common), darken the accent to a 600-level shade for text use; reserve
the brand-bright variant for fills only.
Dark themes
Avoid pure black and pure white — both cause vibration and eye strain.
| Token | Dark theme | Light theme |
|---|---|---|
| Background | #0f0f0f (not #000) |
#fafafa (not #fff) |
| Foreground | #f0f0f0 (not #fff) |
#111111 (not #000) |
On dark surfaces, prefer semi-transparent white borders over solid
dark borders — a 1px rgba(255,255,255,0.08) reads as structure
without adding visual noise.
Semantic color naming
Always name tokens by purpose, never by hue:
/* good */
--accent: #2f6feb;
--success: #17a34a;
/* bad — locks you out of theming */
--blue-500: #2f6feb;
--green-500: #17a34a;
Anti-defaults
- Indigo
#6366f1(Tailwindindigo-500) is the most reliable AI-slop tell. The activeDESIGN.mdprovides--accent; use it. If the brief truly needs indigo, make the user say so explicitly. If yourDESIGN.mdencodes indigo as--accent, that is intentional — the linter only flags hardcoded hex, sovar(--accent)uses are unaffected even when the resolved color happens to be#6366f1. - Two-stop "trust" gradient (purple → blue, blue → cyan, etc.) on a hero is the second most reliable tell. A flat surface + one type-driven hierarchy beats it every time.
- Decorative gradients with no functional purpose. Gradients should separate hierarchies (header → body, primary CTA → secondary), not decorate empty space.