Skip to content
Foundations

Colour

One indigo accent does the interactive work; everything else is a calm neutral. Status colour never encodes planning content.

The accent

Exactly one. Indigo was chosen because it collides with no status hue and no zone hue on the map. A second accent is a design change, not a styling choice.

Selected5
The accent forks between fill and text. --gd-accent is the fill; --gd-accent-ink is the only member that may carry type — and in the dark they are different hues, because #4740DB on charcoal is 1.9:1 and cannot be a link colour.
accent
--gd-accent#4740DB#5F57E3

filled primary buttons, the selected tab rule, the focus ring AA-nontext on --gd-surface

--gd-accent-hover#362FBF#6D66E8

hover on a filled accent surface

--gd-accent-pressed#2F2AA3#4740DB

pressed

--gd-accent-ink#362FBF#A9A4F2

accent TEXT on a light ground — links, ghost buttons, the active contents item, and the label of a latched control on `accent-wash`. The accent proper is 1.9:1 on charcoal and cannot be a link colour in the dark, which is why this forks from `accent` AA on --gd-surfaceAA on --gd-accent-wash

--gd-accent-wash#EEF0FF#3B3866

the accent surface — selected rows, count badges, accent chips

--gd-accent-wash-soft#F7F7FD#1C1B2E

the softest accent ground, for editorial callouts where the full wash shouts

--gd-accent-tintrgba(71, 64, 219, .25)rgba(140, 134, 240, .3)

the border of an accent-washed thing

--gd-accent-ringrgba(71, 64, 219, .14)rgba(140, 134, 240, .22)

a soft accent halo — the selected parcel's glow on the map, and emphasis behind a chosen thing. NOT a focus indicator: focus is `border-focus-ring` everywhere, because a 14%-alpha wash cannot carry WCAG 1.4.11's 3:1

Ink ladder

Six steps, and each one names the smallest thing it may paint. The chrome is achromatic on purpose: the map already carries a council's zone cartography, so every hue spent on chrome is a hue taken away from something that means something.

ink
--gd-ink#292A2E#F2F2F4

headlines and primary text AA on --gd-surface

--gd-ink-body#3D4047#C9CBD2

body copy — the readable default for prose AA on --gd-surface

--gd-ink-secondary#5C6068#9A9EA8

supporting sentences beneath a title AA on --gd-surface

--gd-ink-muted#6B6E75#8A8E96

eyebrows, captions, hints, units — the smallest type that still carries meaning, so it must still clear AA AA on --gd-surface

--gd-ink-faint#8A8E96#74777F

LARGE type and non-text marks only (≥18.66px, or ≥14px bold). Never prose — see the header note AA-large on --gd-surface

--gd-ink-placeholder#9A9EA8#5C606B

a disabled control's label, or a placeholder that only repeats its visible label. Fails AA by design and may carry nothing a user needs

--gd-ink-inverse#FFFFFF#F2F2F4

text on `surface-inverse` AA on --gd-surface-inverse

--gd-ink-on-solid#FFFFFF#101116

text on `surface-solid` — the neutral CTA's label AA on --gd-surface-solid

--gd-ink-on-accent#FFFFFF#FFFFFF

text on a filled accent surface — white in both themes AA on --gd-accent

--gd-ink-on-accent-body#E9E8FB#ECEBFC

body copy on a filled accent band (white at 88%, composited) AA on --gd-accent

--gd-ink-on-accent-muted#CBCAF5#DCDAF9

LARGE type (≥18.66px, or ≥14px bold) and non-text marks on an accent band — the floor of the ladder (white at 72% / 78%, composited) AA-large on --gd-accent

Surfaces & lines

Hover and pressed are SURFACE changes, not shadow changes. A list row darkens; it does not lift. That keeps rows quiet in a long list and stops a panel shimmering as the pointer crosses it.

surface
--gd-surface#FFFFFF#17181E

the default ground for cards, panels and rows

--gd-surface-page#F4F4F2#101116

the page behind everything — warm off-white in the light, the lowest charcoal in the dark

--gd-surface-subtle#FBFBFC#1D1F26

table headers and glyph-tile grounds: a surface that is not quite the card it sits on

--gd-surface-sunken#F4F4F7#101116

recessed groups — segmented tracks, icon tiles, layer lists. Sunken is the one people get wrong: a GROUP of things is recessed, not raised

--gd-surface-hover#FAFAFB#24262E

pointer over a row. Hover is a SURFACE change, never a shadow change — a list that lifts under the pointer shimmers

--gd-surface-pressed#F4F4F7#2B2D36

the moment of the click

--gd-surface-selected#EEF0FF#3B3866

the chosen row or option

--gd-surface-disabled#F0F1F4#212329

an inert control's fill

--gd-surface-inverse#14151A#24262E

toasts, code blocks, the ink CTA band — a surface that is dark in BOTH themes

--gd-surface-solid#14151A#F2F2F4

the neutral high-emphasis CTA fill — near-black on a light page, near-white on a dark one. NOT `surface-inverse`, which stays dark in both

--gd-surface-map#F0EEE9#22242B

the basemap ground. Deliberately not black in the dark, so parcel strokes and overlay fills keep the relationship to their ground that they have in daylight

--gd-surface-scrimrgba(20, 21, 26, 0.42)rgba(0, 0, 0, 0.55)

the dimmer behind modal surfaces — dialog, drawer, palette. Deeper in the dark, because 42% charcoal over a charcoal page barely reads as a veil

--gd-surface-on-accentrgba(255, 255, 255, .10)rgba(255, 255, 255, .10)

a card or row sitting ON a filled accent band

--gd-surface-on-accent-strongrgba(255, 255, 255, .16)rgba(255, 255, 255, .16)

a chip on a filled accent band — one step up from the card it sits in

line
--gd-line#E8E9ED#2B2D36

THE border — cards, inputs, panels

--gd-line-hairline#F0F1F4#212329

a divider INSIDE a container that already has a border

--gd-line-soft#ECEEF1#212329

the second line weight — nested rules, tracks

--gd-line-strong#D7D8DD#3A3D48

a firmer boundary, and every dashed edge (upload zones, clear-space diagrams)

--gd-line-hover#C9CCD2#454955

border under the pointer

--gd-line-on-accentrgba(255, 255, 255, .18)rgba(255, 255, 255, .18)

the border of a card sitting on a filled accent band

--gd-line-on-accent-hairlinergba(255, 255, 255, .05)rgba(255, 255, 255, .05)

the survey grid drawn over a filled accent band — the faintest mark the system has

--gd-line-control#8A8E96#6E7280

a boundary that IS the control — an unchecked box, an off switch track. WCAG 1.4.11 applies and the design's #E0E1E6 is 1.2:1 here: an off switch drawn in it is invisible until it is already on, so you cannot tell the control exists. The same call v1 made for `--track`, for the same reason. Honest caveat: iOS and Material ship light tracks too and the knob's shadow is SOME affordance — 3:1 is the defensible reading, not the only one AA-nontext on --gd-surface

Divergences from the design file

Two, both deliberate, both about contrast. They are recorded here because a divergence nobody can find is indistinguishable from a mistake.

Caution: Eyebrows and captions were darkened

The design sets them in #8A8E96, which is 3.29:1 on white — under AA for text that is not large, and eyebrows are 10–11px. They take --gd-ink-muted (#6B6E75, 5.11:1) instead, and #8A8E96 survives as --gd-ink-faint, restricted to large text and non-text marks. If a label needs to recede, reduce its size or weight — not its contrast.

Caution: The off switch track was darkened

The design's #E0E1E6 is 1.2:1 against the surface. An off switch drawn in it is invisible until it is already on, so you cannot tell the control is there — which WCAG 1.4.11 does not allow for something that is the control. --gd-line-control is 3.29:1. Honest caveat: iOS and Material ship light tracks too, and the knob's shadow is some affordance — 3:1 is the defensible reading, not the only one.

A third value was promoted rather than diverged from: caution's #C9A21A is 2.41:1 on white, so the caution solid is the darker #A8850F the design already uses for its filled tile. #C9A21A survives only as a callout's left rule, where the heading ink beside it carries the meaning.

Navigate

Esc