Color

The full spectrum palette and how to reference it.

Colour ships as CSS custom properties from @base-org/bds-tokens. Components read those properties, so a palette change propagates everywhere without touching component code.

@import '@base-org/bds-tokens/tokens/spectrum.css';

Spectrum

Eleven hues, each running from 0 (lightest) to 100 (darkest) across thirteen steps, plus a standalone brand colour. 50–60 is the usable mid-range for interactive fills. Every swatch below is a token — its name is --bds-{hue}-{step} and the class is bg-bds-{hue}-{step} — and the value shown is the light-mode reference.

Blue

0f5f8ff
5d3e1ff
10b0caff
1592b6ff
2073a2ff
304684ff
40266eff
50105eff
600052ff
70004beb
80003ec1
90002982
10000184d

Teal

0f0feff
5bcf6fd
1088edfb
155de2f8
2033d5f4
3000bceb
4000a9dd
500093cb
60007bb3
70006195
80004774
90002f53
100001b33

Green

0f5fffb
5cbf5e3
10a3ebcd
1583e0ba
2065d6a7
303cc28a
4022ad73
50129961
60098551
70047043
80025332
90003923
100001f12

Chartreuse

0f5fffa
5ddfbe8
10c6f7d1
15b0f2b6
209fee9b
3089df75
407fd057
5056b340
60359730
70237a2b
80195d29
90114023
100071a11

Yellow

0fffcf1
5fff4c0
10fff091
15ffea64
20ffe436
30f7d21a
40ebba00
50cf9700
60ae7100
70884c00
80603000
903a1400
1001b0600

Orange

0fffaf5
5fee8d2
10fdd5b0
15fbc293
20f9ae76
30f48c4c
40ed702f
50e1591b
60cf470e
70b53606
80912702
90641a00
100330d00

Red

0fff5f6
5fee1e4
10fdced2
15fbbabf
20f9a6ad
30f47f88
40ed5966
50e13947
60cf202f
70b50f1d
80910510
90640109
100330004

Pink

0fff5ff
5fde4fd
10fbd4fa
15f8c3f5
20f4b2f0
30eb8fe3
40dd6ed1
50cb51bb
60b33aa2
70952785
80741a66
90531148
100330a2c

Purple

0fbf7ff
5f4e8ff
10edd9ff
15e6c9ff
20deb8ff
30cd99fd
40bc7bfb
509d6bf2
608a55e9
707743d7
805a30ad
90361b6b
100190d33

Indigo

0f6f7ff
5e6e8ff
10d6dafe
15c6ccfd
20b5bdfd
3094a1fb
407487f7
50596ff2
60425be9
702f4ad7
801f36ad
9011206b
100080f33

Gray

0ffffff
5f8f8f8
10efefef
15dadada
20c4c4c4
30b8b8b8
409a9a9a
506f6f6f
605e5e5e
70525252
803a3a3a
90262626
100111111

Brand

Brand0052ff

Usage

Do

Reference tokens by name — bg-bds-blue-60, var(--bds-gray-20) — so the value follows the palette and responds to dark mode.

Don't

Hard-code a hex value, even one copied from this page. It will not follow the ramp when the palette is retuned, and it will not switch for dark mode.

Steps

The thirteen steps are 0, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100. The gap is intentional: the scale is finer at the light end, where small lightness changes read as distinct surfaces, and coarser at the dark end.

Semantic tokens

Semantic tokens name a role and resolve to one spectrum step per theme. Use them for the surfaces, text, and hairlines that make up a page; reach for a spectrum step directly only when a role does not fit, such as a status colour. The name is --bds-{token} and the class is bg-bds-{token}, text-bds-{token}, or border-bds-{token}.

TokenRoleLightDark
bg-primaryPage and card backgroundgray-0 #ffffffgray-0 #111111
bg-secondaryRaised or grouped surfaces: secondary buttons, input fillsgray-10 #efefefgray-10 #3a3a3a
bg-inverseInverted fillsgray-100 #111111gray-100 #ffffff
fg-primaryBody text and iconsgray-80 #3a3a3agray-80 #efefef
fg-mutedSecondary text and placeholdersgray-50 #6f6f6fgray-50 #b8b8b8
fg-inverseText on an inverted fillgray-0 #ffffffgray-0 #111111
fg-on-brandText and icons on a brand fillgray-0 #ffffffgray-100 #ffffff
border-defaultHairlines and ringsgray-10 #efefefgray-10 #3a3a3a
brandBase Blue, for the wordmark and brand accentsblue-60 #0052ffblue-40 #266eff

The grays mirror between themes, so most tokens alias the same step in both; brand and fg-on-brand are the exceptions. Base Blue stays saturated in dark mode, so text on it stays white: pair bg-bds-brand with text-bds-fg-on-brand rather than text-bds-fg-inverse, which turns near-black in dark mode. In JS, getSemanticColor('brand', 'dark') from @base-org/bds-tokens returns the hex value.

Dark mode

The spectrum stylesheet redefines every custom property under .dark, so the same token name resolves correctly in both themes. Components never branch on theme themselves — bg-bds-gray-5 is a light surface in light mode and a dark surface in dark mode, from one class.

Guidelines

Defaults for using tokens and colour in BDS components and product UI. See the Guidelines overview for how to apply them.

Design tokens

  • Have components consume tokens (colour, spacing, radius, shadow, motion, type scale) — never hardcoded values.
  • Reference semantic tokens (--color-text-secondary), never primitives (--blue-500) — the primitive is the raw value, the token is how it's used.
  • Name tokens by purpose, not by raw value or one screen's use case (--color-accent-solid / --radius-card, not --blue-button / --8px).
  • Follow a tiered system: primitive → semantic → component-level override only when a component truly needs a one-off.
  • Add a token only once a component needs it; remove unused tokens. This applies to colour steps, the spacing scale, radii, shadows, and motion durations and easings alike.
  • Keep Figma variables and code tokens in sync — one source of truth, no drift.

Colour

  • Reserve accent for the brand colour; don't let primary mean both brand and body text.
  • Measure contrast against the background directly behind the element. fg-muted passes 4.5:1 on bg-primary and gray-5 but not on bg-secondary in light mode (4.37:1); use gray-60 for muted text there.
  • Use a separate palette for dark mode, not an inversion of the light-mode palette.
  • Choose one theme-switching mechanism (prefers-color-scheme or a .dark class), never both.
  • Be intentional about gradient colour blending: in oklab (even brightness), in oklch (vivid midtones), or in srgb (muted midtones).