Skip to content

Foundations · @csdr/theme

Colour palettes

Three swappable palettes — default (PatternFly), landscape, goap — on PatternFly’s token contract: ramps, roles, validated chart sets, and every component rendered in the palette you are viewing.

Import
palette: goap # report frontmatter · PUBLIC_CSDR_PALETTE=landscape · <SiteLayout palette="goap">
Use on
reports · landing · docs · tools

PatternFly default default

PatternFly 6's own palette, unchanged. The reference implementation: with this palette the generator must reproduce today's build exactly.

Brand family
blue — links, focus ring, primary buttons, masthead
Role remaps
none (PatternFly defaults: brand blue · info purple · warning yellow · danger red-orange · success green)
Provenance
@patternfly/patternfly base/tokens/tokens-palette.scss (pinned in pnpm-workspace.yaml catalog)
Select it
Report: palette: default in frontmatter · Site: PUBLIC_CSDR_PALETTE=default · Page: <SiteLayout palette="default">

Ramps

Nine PatternFly families at PatternFly's steps (grays 10–95). The step is the promise: 10–20 tints, 30 dark-mode text and links, 40 dark-mode UI, 50 light-mode interactive, 60 text on white (≥ 4.5:1 in every family), 70–80 emphasis. Base and semantic tokens (--pf-t--global--*) resolve to these; components never touch them directly.

bluebrand
10
#e0f0ff
20
#b9dafc
30
#92c5f9
40
#4394e5
50
#0066cc
60
#004d99
70
#003366
80
#032142
tealcustom
10
#daf2f2
20
#b9e5e5
30
#9ad8d8
40
#63bdbd
50
#37a3a3
60
#147878
70
#004d4d
80
#003333
greensuccess
10
#e9f7df
20
#d1f1bb
30
#afdc8f
40
#87bb62
50
#63993d
60
#3d7317
70
#204d00
80
#183301
yellowwarning
10
#fff4cc
20
#ffe072
30
#ffcc17
40
#dca614
50
#b98412
60
#96640f
70
#73480b
80
#54330b
orange
10
#ffe8cc
20
#fccb8f
30
#f8ae54
40
#f5921b
50
#ca6c0f
60
#9e4a06
70
#732e00
80
#4d1f00
red-orangedanger
10
#ffe3d9
20
#fbbea8
30
#f89b78
40
#f4784a
50
#f0561d
60
#b1380b
70
#731f00
80
#4c1405
red
05
#fef0f0
10
#fce3e3
20
#fbc5c5
30
#f9a8a8
40
#f56e6e
50
#ee0000
60
#a60000
70
#5f0000
80
#3f0000
purpleinfo
10
#ece6ff
20
#d0c5f4
30
#b6a6e9
40
#876fd4
50
#5e40be
60
#3d2785
70
#21134d
80
#1b0d33
gray
10
#f2f2f2
20
#e0e0e0
30
#c7c7c7
40
#a3a3a3
45
#8c8c8c
50
#707070
60
#4d4d4d
70
#383838
80
#292929
90
#1f1f1f
95
#151515

Step contract

Contrast ratios the generator enforces on every family (pnpm check:palette). Brand-50 must reach 4.5:1 because it is the link and primary-button colour; other families need 3:1 at 50.

Family50 on white60 on white70 on white30 on dark40 on dark10 vs white
blue 5.57 8.33 12.61 8.02 4.58 1.16
green 3.41 5.73 9.89 9.32 6.45 1.11
orange 3.71 6.11 9.91 7.74 6.24 1.19
purple 7.11 11.49 16.6 6.66 3.64 1.21
red 4.53 8.01 14.13 7.76 5.08 1.22
red-orange 3.47 6.1 10.91 6.89 5.29 1.22
teal 3.03 5.27 9.68 9.14 6.61 1.17
yellow 3.3 5.09 7.89 9.63 6.59 1.1

Role tokens

  • link on white (brand-50): 5.57:1 (needs 4.5:1)
  • link on secondary surface (brand-50 on gray-10): 4.97:1 (needs 4.5:1)
  • brand text (brand-60) on white: 8.33:1 (needs 4.5:1)
  • white on brand (brand-50): 5.57:1 (needs 4.5:1)
  • dark link (brand-20) on dark surface: 10.04:1 (needs 4.5:1)
  • dark brand (brand-30) on dark surface: 8.02:1 (needs 4.5:1)
  • body text (gray-95) on white: 18.26:1 (needs 7:1)
  • subtle text (gray-60) on white: 8.45:1 (needs 4.5:1)
  • danger text on white: 6.1:1 (needs 4.5:1)
  • success text on white: 5.73:1 (needs 4.5:1)
  • warning text on white: 5.09:1 (needs 4.5:1)
  • info text on white: 11.49:1 (needs 4.5:1)

Chart sets

Categorical colours are a separate parameter from UI colours: muted brand hues fall under the chart chroma floor and read as grey in a series, so each palette carries a "data-grade" set derived from the same hues and validated (lightness band, chroma floor ≥ 0.10, adjacent CVD ΔE ≥ 8, normal-vision ΔE ≥ 15, ≥ 3:1 vs surface). Assigned in fixed order, never cycled; status colours are reserved and never used for series.

Light surface — 5 primary slots, 1 with secondary encoding

  • 1 blue
    #0066cc
  • 2 orange
    #ca6c0f
  • 3 purple
    #5e40be
  • 4 green
    #3d7317
  • 5 yellow
    #b98412
  • 6 teal
    #147878
  • lightness band — all inside L 0.43–0.77
  • chroma floor — all ≥ 0.1
  • CVD separation (adjacent) — worst #3d7317↔#b98412 ΔE 10.1 (protan); target ≥ 8, floor 6
  • normal-vision floor — worst #3d7317↔#b98412 ΔE 19.6; floor 15
  • contrast vs surface — all ≥ 3:1 on #ffffff
  • All-pairs clean (scatter, maps, small multiples) up to 2 slots.

Sequential 7

Diverging

Status

  • good
  • warning
  • serious
  • critical

Dark surface — 4 primary slots, 2 with secondary encoding

  • 1 blue
    #4394e5
  • 2 orange
    #ca6c0f
  • 3 purple
    #876fd4
  • 4 green
    #63993d
  • 5 yellow
    #b98412
  • 6 teal
    #37a3a3
  • lightness band — all inside L 0.48–0.67
  • chroma floor — all ≥ 0.1
  • CVD separation (adjacent) — worst #876fd4↔#63993d ΔE 23.1 (deutan); target ≥ 8, floor 6
  • normal-vision floor — worst #ca6c0f↔#876fd4 ΔE 26.4; floor 15
  • contrast vs surface — all ≥ 3:1 on #292929
  • All-pairs clean (scatter, maps, small multiples) up to 2 slots.

Sequential 7

Diverging

Status

  • good
  • warning
  • serious
  • critical

Six series, this palette (build-time SVG)

View data
yearNorth (index)South (index)East (index)West (index)Central (index)Islands (index)
201912851036
20201497845
202113116964
202216109756

Download data (CSV)Download chart (SVG)

Figure 1.Illustrative index by region — six categorical slots in fixed order.
View data
yearNorthSouthEastWestCentralIslands
201912851036
20201497845
202113116964
202216109756

Download data (CSV)Download chart (SVG)

Code
<LineChart data={rows} x="year" y="value" series="region" alt="…" />   {/* colours follow the page's palette */}

Components in this palette

Everything below is the ordinary component rendered on a page stamped data-palette="default" — nothing is styled specially for this page.

Brand and status

A text link
TopicRegionPublicationInsightEventAuthor

Info alert:Data updated 5 August 2026

Success alert:Build passed

Warning alert:Provisional values for the current year

Danger alert:Checksum mismatch in bundle noaa-mlo-co2

Code
<Button variant="primary">Download PDF</Button>  <Button variant="secondary">Cite</Button>  <Button variant="link">Read more</Button>

Editorial

Latest monthly mean

431.1ppm

+2.4 vs a year earlier

Growth, 1960s

0.9ppm/yr

Growth, 2010s

2.5ppm/yr

Code
<Callout kind="key-finding" title="…">…</Callout>  <StatTile tone="good" … />

The other palettes

Adding or changing a palette

  1. Edit or add packages/theme/palettes/<id>.json: nine families as hue + chroma (with optional pins for exact brand hexes), optional extensions, roles, and the chart sets.
  2. Run pnpm palette:build. It generates the CSS palette layer, the chart values and this page's report — and refuses to write if a contract, role or chart check fails.
  3. pnpm check (which runs check:palette) fails on any drift between the JSON and the generated files, so hexes never get hand-edited downstream.
  4. Look at it here and in the report preview; then pnpm test for the axe/VR matrix. See Theme → Palettes and D13.