Colors
The system is warm throughout: cream surfaces, warm ink instead of black, a warm dark instead of blue-black, and one brand colour, coral, used sparingly. Components use only the semantic tokens below, which point at the palette; the dark theme changes where they point and leaves the palette alone (see Themes).
The values in the tables are read from the token files when this site builds.
Surfaces
Section titled “Surfaces”Three surface modes alternate down a page: the cream canvas, the cream card and the dark surface. No two neighbouring bands use the same one. Cream cards are set apart from the canvas by their fill, not by a border or a shadow. The dark surface is for emphasis: a product mockup, a comparison, the footer. In the dark theme it stays one step above the canvas, so a dark card still stands out.
| Token | Light | Dark | Description |
|---|---|---|---|
--surface-canvassurface.canvas | #faf9f5Points to --cream-50 | #181715Points to --night-900 | The page floor. |
--surface-softsurface.soft | #f5f0e8Points to --cream-100 | #1f1e1bPoints to --night-850 | A soft band one step above the canvas. |
--surface-cardsurface.card | #efe9dePoints to --cream-200 | #252320Points to --night-800 | Cards on the canvas. |
--surface-cream-strongsurface.cream-strong | #e8e0d2Points to --cream-300 | #2b2925 | The strongest cream, for emphasis inside cards. |
--surface-darksurface.dark | #181715Points to --night-900 | #2b2925 | The emphasis surface: dark cards, code windows, the footer. |
--surface-dark-softsurface.dark-soft | #1f1e1bPoints to --night-850 | #322f2a | One step above the dark surface, such as code inside a dark card. |
--surface-dark-elevatedsurface.dark-elevated | #252320Points to --night-800 | #393631 | Raised elements on dark surfaces. |
--surface-blur-creamsurface.blur-cream | rgb(250 249 245 / 72%) | rgb(24 23 21 / 72%) | Translucent cream behind a 12px backdrop blur, such as the scrolled top bar. |
--surface-blur-darksurface.blur-dark | rgb(24 23 21 / 72%) | — | Translucent dark behind a 12px backdrop blur. |
--surface-blur-cream-opaquesurface.blur-cream-opaque | rgb(250 249 245 / 94%) | rgb(24 23 21 / 94%) | Near-opaque cream for when the blur is not supported. |
--surface-blur-dark-opaquesurface.blur-dark-opaque | rgb(24 23 21 / 94%) | — | Near-opaque dark for when the blur is not supported. |
Text is warm ink, never pure black, and the text on dark surfaces is cream-tinted, never pure white. The cream text colours go on the cream surfaces and the on-dark ones on the dark surfaces; the specimen above shows each pairing. Links are coral.
| Token | Light | Dark | Description |
|---|---|---|---|
--text-inktext.ink | #141413Points to --ink-900 | #faf9f5Points to --cream-50 | Headlines and the strongest text. |
--text-body-strongtext.body-strong | #252523Points to --ink-800 | #f5f0e8Points to --cream-100 | Emphasized body text. |
--text-bodytext.body | #3d3d3aPoints to --ink-700 | #e8e0d2Points to --cream-300 | Running text. |
--text-mutedtext.muted | #6c6a64Points to --ink-500 | #a09d96Points to --ink-300 | Secondary text such as dates and metadata. |
--text-muted-softtext.muted-soft | #8e8b82Points to --ink-400 | #7f7c74 | The quietest text: hints and micro-labels. |
--text-on-darktext.on-dark | #faf9f5Points to --cream-50 | — | Text on dark surfaces. Cream-tinted, never pure white. |
--text-on-dark-softtext.on-dark-soft | #a09d96Points to --ink-300 | — | Secondary text on dark surfaces. |
--text-linktext.link | #d97757Points to --coral-500 | — | Inline links. |
Coral is the brand voltage. On a single element it is scarce: one primary button, a link, the focus ring. It is generous only as a whole surface, such as a full-width callout. Nothing in between: no coral borders or coral headings. Pressed, coral darkens; disabled, it flattens to the hairline colour with a muted label. Coral is the same in both themes.
| Token | Light | Dark | Description |
|---|---|---|---|
--color-primarycolor.primary | #d97757Points to --coral-500 | — | Primary buttons, full-bleed callouts and CTA surfaces. Scarce on individual elements. |
--color-primary-activecolor.primary-active | #a9583ePoints to --coral-700 | — | Primary fill while pressed, and link hover. |
--color-primary-disabledcolor.primary-disabled | #e6dfd8Points to --cream-500 | #3a3833 | Primary fill when disabled. |
--color-on-primarycolor.on-primary | #ffffffPoints to --white | — | Text and icons on the primary fill. |
--focus-ringfocus-ring | rgb(217 119 87 / 15%) | — | Halo around a focused input, drawn as a 3px box-shadow. |
Accents, status and markers
Section titled “Accents, status and markers”Teal and amber appear only as small marks: a status dot, a category badge. The status colours say success, warning and error, as a dot or a short label, never as a whole surface. Markers highlight text with an opaque tint, the accent already mixed into the surface beneath, so highlighted text keeps full contrast and two markers that touch do not darken each other.
| Token | Light | Dark | Description |
|---|---|---|---|
--accent-tealaccent.teal | #5db8a6Points to --teal-400 | — | |
--accent-amberaccent.amber | #e8a55aPoints to --amber-400 | — | |
--status-successstatus.success | #5db872Points to --green-500 | — | |
--status-warningstatus.warning | #d4a017Points to --gold-500 | — | |
--status-errorstatus.error | #c64545Points to --red-500 | — | |
--marker-coralmarker.coral | #f4e2d9 | #4d352bPoints to --marker-coral-on-dark | |
--marker-tealmarker.teal | #deede7 | #2e453fPoints to --marker-teal-on-dark | |
--marker-ambermarker.amber | #f7ead9 | #52412cPoints to --marker-amber-on-dark | |
--marker-redmarker.red | #f1d9d5 | #492826Points to --marker-red-on-dark | |
--marker-coral-on-darkmarker.coral-on-dark | #422c24 | #4d352b | |
--marker-teal-on-darkmarker.teal-on-dark | #273a35 | #2e453f | |
--marker-amber-on-darkmarker.amber-on-dark | #463624 | #52412c | |
--marker-red-on-darkmarker.red-on-dark | #3e2120 | #492826 |
Hairlines
Section titled “Hairlines”Borders are hairlines in a cream tone, so a border reads as one step of elevation, not as an ink line. The soft hairline divides content inside one card or band.
| Token | Light | Dark | Description |
|---|---|---|---|
--hairlinehairline | #e6dfd8Points to --cream-500 | #35332f | Borders. They read as one elevation step, not as ink lines. |
--hairline-softhairline-soft | #ebe6dfPoints to --cream-400 | #2a2823 | Fainter borders inside cards. |
--hairline-on-darkhairline-on-dark | #31302c | #43413b | Borders on dark surfaces. |
Palette
Section titled “Palette”The raw colours the semantic tokens point at. Use the semantic tokens in components; the palette is for defining them.
| Token | Value | Description |
|---|---|---|
--cream-50cream.50 | #faf9f5 | |
--cream-100cream.100 | #f5f0e8 | |
--cream-200cream.200 | #efe9de | |
--cream-300cream.300 | #e8e0d2 | |
--cream-400cream.400 | #ebe6df | |
--cream-500cream.500 | #e6dfd8 | |
--ink-300ink.300 | #a09d96 | |
--ink-400ink.400 | #8e8b82 | |
--ink-500ink.500 | #6c6a64 | |
--ink-700ink.700 | #3d3d3a | |
--ink-800ink.800 | #252523 | |
--ink-900ink.900 | #141413 | |
--night-800night.800 | #252320 | |
--night-850night.850 | #1f1e1b | |
--night-900night.900 | #181715 | |
--coral-500coral.500 | #d97757 | |
--coral-700coral.700 | #a9583e | |
--teal-400teal.400 | #5db8a6 | |
--amber-400amber.400 | #e8a55a | |
--green-500green.500 | #5db872 | |
--gold-500gold.500 | #d4a017 | |
--red-500red.500 | #c64545 | |
--whitewhite | #ffffff |