Design system · Pigment
The system colors.li is built from.
Warm achromatic chrome so the palette is the only color, ink for actions, the brand green as the single accent, and a mono-led instrument voice. Every token, state and rule below is the live value — this page is styled from the same tokens it documents.
01 — Foundations
Color tokens
Components must reference a semantic token, never a raw hex. Status colors are semantic only and must not be reused as the accent.
Warm paper — page ground
Cards, inputs, raised chrome
Warm ink — primary text
Hover / chips / fills
Secondary text, eyebrows
Hairlines, dividers
Ink — solid CTAs
Brand green — the one accent
Errors (semantic only)
Dark theme redefines each token (paper → #131210, ink → #F4F2EC, green → #63C23A). Toggle the theme in the header — every element here follows.
02 — Foundations
Type & scale
Inter carries text and display for a warm voice; JetBrains Mono is the instrument face — eyebrows, data, hex codes, the keycap. Headings set -0.02em tracking with balanced wrapping.
03 — Signatures
The parts that make it ours
Keycap
The physical spacebar affordance for generate. Depresses on press.
SpaceLive thread
The one chrome element that wears the current palette.
Checkerboard
Transparency backing behind colors with alpha.
04 — Components
Components & states
Every interactive component defines default, hover, focus-visible, active, disabled and — where it applies — loading and error. Focus is a 2px accent outline at 2px offset, sitewide.
Button
Ink for the primary action; a bordered secondary for everything else. Hover me, then tab to me.
| State | Visual rule | Behaviour |
|---|---|---|
| default | bg-primary / text-primary-foreground | Real <button>; idle. |
| hover | bg-primary/90, 150ms | Pointer only — never the sole cue. |
| focus-visible | 2px accent outline, 2px offset | Must show on keyboard focus. |
| active | pressed feedback under 150ms | Enter / Space activate. |
| disabled | opacity 45%, not-allowed | disabled or aria-disabled. |
| loading | label hidden, spinner, width locked | aria-busy; frozen under reduced-motion. |
| error | adjacent message in danger | Announced via aria-live; never color-only. |
Touch: hit target must be ≥44×44px. Icon-only buttons must carry an aria-label.
Link
- A link navigates, a button acts — never swap them for styling.
- Link text must describe its destination — never "click here" alone.
- Underline on hover carries a non-color cue; long URLs wrap, never force sideways scroll.
Input
Label always visible and associated. Focus lifts the border to accent; error uses aria-invalid + a message that explains the fix.
Mobile inputs step to ≥16px to prevent iOS zoom. Validate on blur/submit, not first keystroke.
List & empty state
- Teal & Sand 5 colors
- Sunset Coral 4 colors
- Deep Marine 6 colors
Empty states are designed, never a blank box — a sentence plus the primary next action.
Navigation
Current item marked with aria-current="page", not color alone. Below 640px the site nav collapses to a disclosure with a ≥44px target.
05 — Testable criteria
Accessibility
Target WCAG 2.2 AA. Each check is pass/fail in a PR — by keyboard, a contrast tool, or the a11y tree.
| Criterion | Test | Pass |
|---|---|---|
| Text contrast (1.4.3) | Sample each text/background token pair | ≥4.5:1 body, ≥3:1 large |
| Non-text contrast (1.4.11) | Input borders, focus rings, control edges | ≥3:1 |
| Focus visible (2.4.7) | Tab the whole page | Accent ring on every stop |
| Target size (2.5.8) | Measure hit areas | ≥24px; ≥44px on touch |
| Keyboard (2.1.1) | Unplug the mouse, finish every flow | No trap, all reachable |
| Color not sole cue (1.4.1) | Greyscale the page | State & current still read |
| Reduced motion (2.3.3) | OS reduce-motion on, reload | Thread / keycap / spinners still |
06 — Voice
Content & tone
Fast, honest, plain. A control says what it does; the confirmation echoes it. No fake numbers, no apologies.
Do
- Name actions by outcome — Generate · Copy hex · Save
- Echo success in the same words — "Save" → "Saved"
- Errors explain the fix — "Name must be 3–40 characters"
Don't
- Vague labels — Submit · OK
- Apologetic vagueness — "Oops! Something went wrong."
- Non-descriptive links — "Click here", "Read more"
07 — Ship gate
QA checklist
Tick before a component merges — any unchecked item is a blocker.
colors.li · Pigment design system · this page is built from the tokens it documents.