Skip to content

Foundations

Colour

A white ground, a near-black mark, three rule weights, and status.

The system is monochrome. The ground is paper-white, the mark is near-black, and the only chroma left in the file is status — which is bound to state and never to brand. What used to be carried by hue is carried by weight, by rule, and by reversal.

There are two text steps and nothing lighter. The floor is --ink-3-aa, which clears WCAG AA on white at 6.7:1; every step above it is darker. A tint that would sit below that line is not a colour choice available to this system.

Dark mode is a value swap on the same names, not a second palette. That is why a component never reads a primitive directly: it reads a semantic alias, and the alias re-resolves on its own when the mode attribute flips.

Colour tokens

Colour tokens tokens
TokenValueDarkNotes
--paper#ffffff#0d0d0d
--paper-2#f7f7f5#161616
--barvar(--stone)var(--stone)
--bar-2var(--stone)var(--stone)
--ink#101010#f4f4f2Two text steps and nothing lighter. --ink-3-aa is the floor — it clears AA on white at 6.7:1, and every step above it is darker. --ink-3 is the same weight expressed as alpha, for rules and washes that must sit over a photograph as well as over paper.
--ink-2#4a4a4a#b4b4b0
--ink-3rgba(16, 16, 16, 0.55)rgba(244, 244, 242, 0.55)
--ink-3-aa#5c5c5c#9a9a96
--forest#3a3a3a#c9c9c5The second editorial voice is not a hue — it is one more neutral step, sitting between --ink and --ink-2, so a byline separates from body copy without introducing colour.
--mistvar(--stone)var(--stone)
--stone#f2f1ee#1f1f1f
--clayvar(--ink)var(--ink)Monochrome collapses the pointer onto the mark: the accent IS ink. What used to be carried by hue is now carried by weight, rule and reversal — an ink pill, an ink underline, an ink-filled plate.
--clay-inkvar(--clay)var(--clay)
--feature-surface#262626#1a1a1aThe one reversed plate, and the one place the ramp needs a tenth step. Set to var(--ink) it was the page's darkest possible mark used as a field, which on a white page reads as a hole punched through it rather than as a panel. Two steps lighter keeps the reversal — 15.1:1 for paper-white type on it — and matches the dark side.
--on-featurevar(--paper)var(--ink)
--on-photovar(--paper)#fbfbfa
--photo-caption-surfacevar(--ink)var(--paper)
--photo-shadow0 1px 6px rgb(0 0 0 / 0.72)0 1px 6px rgb(0 0 0 / 0.72)
--rule#edebe6rgba(244, 244, 242, 0.14)Three rule weights, because a monochrome page has no colour left to separate one band from the next: hairline, edge, and hard.
--rule-2#dbdbd6rgba(244, 244, 242, 0.26)
--rule-hardvar(--ink)var(--ink)
--redvar(--clay)var(--clay)Historic role names, kept so a consumer written against the previous palette keeps resolving. Their hue is now ink; the role remains "the single editorial pointer".
--red-inkvar(--clay)var(--clay)
--red-softrgba(16, 16, 16, 0.07)rgba(244, 244, 242, 0.12)
--on-redvar(--paper)var(--paper)
--ok#3d6b34#84b47b─── Status ─── the only chroma in the system, and it is bound to state.
--ok-softrgba(61, 107, 52, 0.13)rgba(132, 180, 123, 0.16)
--warn#8a5a00#d9a55d
--warn-softrgba(138, 90, 0, 0.13)rgba(217, 165, 93, 0.16)
--danger#a83214#ee8b68
--danger-softrgba(168, 50, 20, 0.14)rgba(238, 139, 104, 0.16)
--scrimcolor-mix(in srgb, var(--ink) 62%, transparent)color-mix(in srgb, #000 72%, transparent)
--backgroundvar(--paper)same─── Surfaces ───────────────────────────────────────────────────────────
--background-elevatedvar(--paper-2)same
--code-backgroundvar(--bar)same
--nav-backgroundvar(--paper)same
--card-backgroundvar(--paper)sameKept as an alias rather than removed: the White Reset retired the card surface, so an elevated variant has nothing left to point at. Consumers written against it keep resolving, on paper.
--foregroundvar(--ink)same─── Text ───────────────────────────────────────────────────────────────
--foreground-mutedvar(--ink-2)same
--on-dark#fbfbfasameText sitting on a PHOTOGRAPH — a hero, a lightbox, a scrim. A photograph is a dark ground in BOTH themes, so this must not follow the paper/ink swap: as var(--paper) it inverted to near-black in dark mode, which is how headings disappeared into their own images. A literal, not var(--ink).
--brand-plate#ffffffsameThe ground under a THIRD-PARTY brand mark, and for the same reason: a foreign logo is drawn against one fixed backdrop and shipped flat, with no light-ink sibling. A plate that followed the swap erased it in dark mode. Not for our own marks, which are authored against the theme.
--border-colorvar(--rule-2)same─── Lines ──────────────────────────────────────────────────────────────
--border-subtlevar(--rule)same
--accentvar(--red)same─── Accent ─── one pointer, and in a monochrome system it is ink. ──────
--accent-hovervar(--red-ink)same
--accent-mutedvar(--red-soft)same
--accent-washvar(--red-soft)same
--accent-foregroundvar(--on-red)same
--accent-on-darkvar(--red)same
--accent-on-mutedvar(--red-ink)sameAccent text sitting on an accent-muted panel, which --accent cannot do: it clears AA on paper by 4.58:1, and any tint of itself underneath pushes it below 4.5. This names the situation so the choice is not left to whoever writes the next panel.
--successvar(--ok)same─── Status ─── bound to state, never to brand. ─────────────────────────
--success-washvar(--ok-soft)same
--warningvar(--warn)same
--warning-washvar(--warn-soft)same
--danger-washvar(--danger-soft)same
--infovar(--ink-2)same
--info-washvar(--red-soft)same
--photo-scrim#101010sameThe photo scrim is always dark by design, so it takes the ink literal rather than the semantic token (which inverts).
--overlayvar(--scrim)same

Depth

Three of these resolve to nothing on purpose. A box-shadow in this system is never blurred; --lift is the hard ink offset that replaces the elevation ramp.

Depth tokens
TokenValueDarkNotes
--shadow-offsetvar(--clay)var(--clay)
--shadow-colortransparentsame─── Depth ──────────────────────────────────────────────────────────── Law 2 — a box-shadow is never blurred. The system has no elevation ramp; depth is a hard offset in ink, applied per component. These three resolve to nothing on purpose, so a component ported from a shadowed system stays flat instead of drawing a blur the White Reset does not have. Reach for --lift instead, which is the offset idiom expressed once.
--shadow-smnonesame
--shadownonesame
--shadow-lgnonesame
--lift3px 3px 0 0 var(--shadow-offset)sameThe one depth cue the system does have: a hard 3px ink offset, no blur. Used by a plate that must read as sitting above the page.
--lift-sm2px 2px 0 0 var(--shadow-offset)same
--disabled-opacity0.5same

Focus

Focus tokens
TokenValueDarkNotes
--focus-on-featurevar(--on-feature)var(--on-feature)
--focusvar(--red)same─── Focus ───
--focus-w2pxsame
--focus-off3pxsame
--ringvar(--focus)same─── Focus + motion ─── the site's long-lived names onto the primitives.
--ring-offsetvar(--focus-off)same