# Colour

> Colour tells people which product they're in and what needs their attention. Each product keeps its own primary; neutrals and status colours stay shared.

## Product primaries

Each product defines its own primary in its `DESIGN.md`. Draw it from a Radix colour scale, so states, tints, and dark-mode variants are already defined. A surface that lives inside a host product uses the host's primary rather than carrying its own.

What stays shared across all products: **neutrals** (Radix `gray`/`slate`), **functional colours** (success/warning/danger from Radix `grass`/`amber`/`red`, COL-2), typography, illustration style, and spacing. A product changes its accent, never its character.

## The Radix scales

Each Radix colour ships as a 12-step scale with defined roles: backgrounds, component states, borders, solid fills, and text. Picking from Radix means every product's hover, pressed, and disabled states are consistent by construction.

*(interactive element omitted — view it on the page)*

Radix indigo — an example product primary at step 9.

*(interactive element omitted — view it on the page)*

Radix orange — a warmer example, primary at step 9.

## Shared neutrals

Neutrals stay shared across every product: `gray` for general UI, `slate` where a cooler tone reads better.

*(interactive element omitted — view it on the page)*

*(interactive element omitted — view it on the page)*

## Functional colours

Functional colours always come from the shared Radix scales: `grass` for success, `amber` for warning, and `red` for danger. Never pick one ad hoc (COL-2).

*(interactive element omitted — view it on the page)*

The warning text token is darkened past Radix amber-11 on purpose. Amber-11 caps at roughly 4.6:1 even on white, so it fails AA on the tinted warning background. The darkened value clears 6.1:1 instead.

## Semantic tokens

Tokens describe purpose, not appearance, so a colour can change without touching a single component.

| Token | Role |
| --- | --- |
| `--background` | The page canvas. |
| `--surface` | Panels and cards sitting on the page. |
| `--foreground` | Primary text ink. |
| `--muted-foreground` | Secondary text — darkened from zinc-500 to clear AA on the muted fill. |
| `--border` | Hairline dividers and default component borders. |
| `--muted` | Active fill and code background. |
| `--accent` | Hover fill. |
| `--border-strong` | Hover border. |
| `--prose-body` | Body text ink inside long-form content. |
| `--ring` | Focus ring colour. |

| Token | Role |
| --- | --- |
| `--success` | Success text — Radix grass-11. |
| `--success-9` | Success solid fill — Radix grass-9. |
| `--success-subtle` | Success badge background. |
| `--success-muted` | Success badge border. |
| `--warning` | Warning text — darkened past Radix amber-11 to clear AA on a tinted background. |
| `--warning-9` | Warning solid fill — Radix amber-9. |
| `--warning-subtle` | Warning badge background. |
| `--warning-muted` | Warning badge border. |
| `--danger` | Danger text — Radix red-11. |
| `--danger-9` | Danger solid fill — Radix red-9. |
| `--danger-subtle` | Danger badge background. |
| `--danger-muted` | Danger badge border. |

## Usage

```tsx
// Semantic Tailwind classes — the default
<div className="bg-surface text-foreground border border-border" />
<span className="text-success bg-success-subtle" />

// CSS-variable escape hatch, when no class fits
<div style={{ background: "var(--muted)" }} />
```

## Best practices

- Do: Use the product's own primary for primary actions and brand moments (COL-1).
- Do: Take success, warning, and danger colours from the shared Radix scales (COL-2).
- Do: Pair colour with a text label — never signal with colour alone.
- Don't: Hardcode a hex value in a component; use a semantic token instead (TOK-1).
- Don't: Use purple or violet gradients, cyan-on-dark, glow accents, or gradient text (SLP-1, SLP-2).

## Related

### Agent skill

- `/dx-harness:dx-design-polish`: Reviews the visual craft of a page: spacing, type, radius, colour, and shadow. Proposes ranked fixes.

[All skills](/harness/skills)

### In the catalogue

- [COL-1](/standards/catalog/col-1) (L1): Primary actions and brand moments use the product's own primary brand colour (or its ramp)
- [COL-2](/standards/catalog/col-2) (L1): Functional colours (success/warning/danger) come from the shared Radix Colors scales, never ad-hoc; small functional-colour text (≤12px chips/labels) uses the scale's step-12 on a tinted background so it clears AA (A11Y-1)
- [TOK-1](/standards/catalog/tok-1) (L1): UI code contains no raw colour values — only the colour tokens DESIGN.md defines (else the codebase's theme tokens, else shadcn's semantic tokens)
- [SLP-1](/standards/catalog/slp-1) (L1): No purple/violet gradient palettes, cyan-on-dark theming, or glow accents
