Foundations
Colour, type, shape, motion
app/globals.css at build time. Nothing here is transcribed by hand, so the documentation cannot drift from what the product actually ships.The brand palette
Four hues, taken from the delegatecomputer.com mark. They are fixed — everything else in the system is derived from them or from the warm neutral axis they sit on.
teal
#13b3c9
oklch(0.7038 0.1195 210.51)
Primary. Fills, focus, the first dot.
green
#4ab776
oklch(0.6996 0.1387 154.26)
Success. Completed delegations, healthy state.
amber
#f5b520
oklch(0.8114 0.161 81.67)
Warning. Needs attention, not yet failing.
red
#ca2231
oklch(0.5429 0.2004 23.43)
Destructive and error. Used sparingly.
The raw hues cannot carry text on paper.
Teal reaches only 2.4:1 against #fbfaf7, amber 1.8:1. They are fill and decoration colours. Where a brand hue has to carry text or a focus ring, the system uses --brand-teal-deep (#007d8d, 4.7:1) instead.
Semantic tokens
Build surfaces from these, never from a raw hex or a Tailwind palette class. The chip follows the active theme; the two hex values below it are the resolved colour in each.
Surface
The stack of planes a page is built from. Paper at the bottom, cards lifted a hair above it.
--background
- light
- #fbfaf7
- dark
- #12110e
--card
- light
- #fefefc
- dark
- #1b1a17
--popover
- light
- #fefefc
- dark
- #1b1a17
--muted
- light
- #f2f0ec
- dark
- #252420
--accent
- light
- #eceae5
- dark
- #2e2c28
--secondary
- light
- #f2f0ec
- dark
- #252420
Content
Everything that carries text. Each of these is contrast-checked against the surface it sits on.
--foreground
- light
- #1f1e1b
- dark
- #f1f0ed
--card-foreground
- light
- #1f1e1b
- dark
- #f1f0ed
--muted-foreground
- light
- #6e6c65
- dark
- #a5a39b
--link
- light
- #007d8d
- dark
- #3ac0d5
Intent
The four brand dots, promoted to meaning. Never the only signal — always paired with a label or icon.
--primary
- light
- #13b3c9
- dark
- #3ac0d5
--success
- light
- #4ab776
- dark
- #59c482
--warning
- light
- #f5b520
- dark
- #fdbf3a
--destructive
- light
- #ca2231
- dark
- #e9464b
--info
- light
- #13b3c9
- dark
- #3ac0d5
Chrome
Edges and focus. The ring is a deepened teal because the brand teal cannot reach 3:1 on paper.
--border
- light
- #e1e0db
- dark
- #302f2b
--input
- light
- #e1e0db
- dark
- #302f2b
--ring
- light
- #007d8d
- dark
- #3ac0d5
Charts
The brand dots reordered for hue separation, with red held back so a series never reads as an error.
--chart-1
- light
- #13b3c9
- dark
- #3ac0d5
--chart-2
- light
- #f5b520
- dark
- #fdbf3a
--chart-3
- light
- #4ab776
- dark
- #59c482
--chart-4
- light
- #ca2231
- dark
- #e9464b
--chart-5
- light
- #6e6c65
- dark
- #a5a39b
Contrast contract
38 of 38 checks pass. These are not aspirations — the same numbers are asserted by pnpm check:contrast, which exits non-zero on failure and runs in CI.
Light
| Pairing | Measured | Required | What it protects |
|---|---|---|---|
| foreground on background | 15.97:1passes | 4.5:1 | body text on the page |
| muted-foreground on background | 5.05:1passes | 4.5:1 | secondary text on the page |
| card-foreground on card | 16.48:1passes | 4.5:1 | body text on a card |
| muted-foreground on card | 5.22:1passes | 4.5:1 | secondary text on a card |
| popover-foreground on popover | 16.48:1passes | 4.5:1 | text in a popover |
| primary-foreground on primary | 6.60:1passes | 4.5:1 | label on a primary button |
| secondary-foreground on secondary | 14.67:1passes | 4.5:1 | label on a secondary button |
| accent-foreground on accent | 13.90:1passes | 4.5:1 | label on an accent surface |
| destructive-foreground on destructive | 5.32:1passes | 4.5:1 | label on a destructive fill |
| success-foreground on success | 6.61:1passes | 4.5:1 | label on a success fill |
| warning-foreground on warning | 9.14:1passes | 4.5:1 | label on a warning fill |
| info-foreground on info | 6.60:1passes | 4.5:1 | label on an info fill |
| sidebar-foreground on sidebar | 15.33:1passes | 4.5:1 | text in the sidebar |
| sidebar-primary-foreground on sidebar-primary | 6.60:1passes | 4.5:1 | sidebar primary label |
| link on background | 4.66:1passes | 4.5:1 | link text on the page |
| link on card | 4.81:1passes | 4.5:1 | link text on a card |
| border on background | 1.27:1passes | 1.2:1 | a border must be visible against the page |
| ring on background | 4.66:1passes | 3.0:1 | the focus ring must be visible — WCAG 2.4.11 |
| primary on background | 2.42:1passes | 1.4:1 | primary fill must separate from the page |
Dark
| Pairing | Measured | Required | What it protects |
|---|---|---|---|
| foreground on background | 16.55:1passes | 4.5:1 | body text on the page |
| muted-foreground on background | 7.47:1passes | 4.5:1 | secondary text on the page |
| card-foreground on card | 15.26:1passes | 4.5:1 | body text on a card |
| muted-foreground on card | 6.89:1passes | 4.5:1 | secondary text on a card |
| popover-foreground on popover | 15.26:1passes | 4.5:1 | text in a popover |
| primary-foreground on primary | 8.67:1passes | 4.5:1 | label on a primary button |
| secondary-foreground on secondary | 13.63:1passes | 4.5:1 | label on a secondary button |
| accent-foreground on accent | 12.17:1passes | 4.5:1 | label on an accent surface |
| destructive-foreground on destructive | 4.89:1passes | 4.5:1 | label on a destructive fill |
| success-foreground on success | 8.66:1passes | 4.5:1 | label on a success fill |
| warning-foreground on warning | 11.40:1passes | 4.5:1 | label on a warning fill |
| info-foreground on info | 8.67:1passes | 4.5:1 | label on an info fill |
| sidebar-foreground on sidebar | 15.26:1passes | 4.5:1 | text in the sidebar |
| sidebar-primary-foreground on sidebar-primary | 8.67:1passes | 4.5:1 | sidebar primary label |
| link on background | 8.67:1passes | 4.5:1 | link text on the page |
| link on card | 7.99:1passes | 4.5:1 | link text on a card |
| border on background | 1.41:1passes | 1.2:1 | a border must be visible against the page |
| ring on background | 8.67:1passes | 3.0:1 | the focus ring must be visible — WCAG 2.4.11 |
| primary on background | 8.67:1passes | 1.4:1 | primary fill must separate from the page |
Typography
Geist for interface text, Geist Mono for tokens, code, IDs and anything numeric. Display sizes carry -0.02em tracking — the same tightening the entry page uses on its wordmark.
Tabular numerals are applied automatically inside tables and to anything marked .tabular, so figures do not jitter as they update.
Shape and elevation
Radius is 0.75rem at the base, softer than stock shadcn's 0.625rem — the extra 2px is what makes the system read warm rather than technical. Shadows are ink-hued, never neutral black.
sm
0.45rem
md
0.60rem
lg
0.75rem
xl
1.05rem
2xl
1.35rem
xs
sm
md
lg
Motion
One easing curve, one entrance. The rise is lifted verbatim from the entry page and is the most recognisable thing the system does.
- --ease-rise
- cubic-bezier(0.2, 0.7, 0.3, 1)
- — every entrance and expansion
- --duration-fast
- 120ms
- — hover, colour changes
- --duration-base
- 220ms
- — popovers, sheets, accordions
- --duration-rise
- 700ms
- — page-level entrances only
- --stagger-step
- 140ms
- — delay between cascade items
prefers-reduced-motion: reduce disables the cascade and collapses every animation and transition globally — the same guard the entry page ships.