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

Global Ocean Accounts Partnership goap

The Partnership palette (greens/teals, blues, sand, greys) pinned verbatim into PatternFly's steps, plus the status hues and chart set a UI needs. Where a documented pairing fails WCAG AA the palette uses the neighbouring step of the same hue — see the sign-off issue.

Brand family
teal — links, focus ring, primary buttons, masthead
Role remaps
brand → teal info → blue
Provenance
SustainableDevelopmentReform/CSDR-GOAP-Design-System@ebcf73c — goap/tokens.css, CSDR-GOAP-Style-Guide.md §3.4. Sign-off: CSDR-GOAP-Design-System#1.
Select it
Report: palette: goap in frontmatter · Site: PUBLIC_CSDR_PALETTE=goap · Page: <SiteLayout palette="goap">

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.

blueinfo
10
#e2f0f5
20
#aed1d8
30
#9dcadd
40
#51a5bb
50
#217794
60
#25667c
70
#164151
80
#2a3f58
tealbrand
10
#e2f1f0
20
#bfdfde
30
#9ccdcc
40
#67afae
50
#167b7b
60
#0a5455
70
#134444
80
#19383b
greensuccess
10
#e2f2e9
20
#bee1cf
30
#9bd0b6
40
#66b390
50
#3b9c7b
60
#1f6d4e
70
#124632
80
#0e2f21
yellowwarning
10
#f5ecdc
20
#e9d5b1
30
#dcbe88
40
#c39948
50
#a57807
60
#77570b
70
#4f3700
80
#352402
orange
10
#f9f5f0
20
#e5d5c3
30
#d6bea3
40
#b59e81
50
#9e794d
60
#745735
70
#4b3821
80
#322516
red-orangedanger
10
#fee8e2
20
#facbbf
30
#f3af9e
40
#e0846d
50
#c55d43
60
#92412d
70
#60291b
80
#401c13
red
05
#fef0ef
10
#fee7e5
20
#fdc9c6
30
#f7aba8
40
#e57e7c
50
#ca5557
60
#963b3d
70
#622526
80
#421919
purple
10
#eeebf5
20
#dad4e8
30
#c6bdda
40
#a699c1
50
#8777a5
60
#625679
70
#3f374f
80
#2a2434
gray
10
#f3f2f0
20
#e3e3e3
30
#c8c7c5
40
#a4a3a1
45
#8d8c8a
50
#727272
60
#4e4d4b
70
#393836
80
#2a2927
90
#30302f
95
#161514

Pinned brand hexes

Brand colours are pinned verbatim into the step they belong to; the generator reports how far each sits from the step's lightness so fidelity costs are visible.

Family · stepHexOKLCH LStep targetΔ L
gray-20 #E3E3E30.9160.907+0.009
gray-50 #7272720.5520.545+0.007
gray-90 #30302F0.3090.239+0.07
blue-20 #AED1D80.8380.88-0.043
blue-40 #51A5BB0.6780.707-0.029
blue-80 #2A3F580.3620.275+0.087
green-50 #3B9C7B0.6260.601+0.025
orange-10 #F9F5F00.9720.946+0.026
orange-40 #B59E810.7120.707+0.005
teal-60 #0A54550.4060.479-0.073
teal-80 #19383B0.3180.275+0.043

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.08 6.42 11 8.26 5.16 1.17
green 3.37 6.26 10.78 8.38 5.83 1.16
orange 3.97 6.65 11.13 8.14 5.66 1.09
purple 4.03 6.72 11.23 8.1 5.51 1.18
red 4.24 7.02 11.59 7.86 5.27 1.18
red-orange 4.18 6.96 11.47 7.92 5.33 1.18
teal 5.06 8.71 10.84 8.33 5.76 1.16
yellow 3.97 6.66 11.18 8.15 5.52 1.17

Role tokens

  • link on white (brand-50): 5.06:1 (needs 4.5:1)
  • link on secondary surface (brand-50 on gray-10): 4.52:1 (needs 4.5:1)
  • brand text (brand-60) on white: 8.71:1 (needs 4.5:1)
  • white on brand (brand-50): 5.06:1 (needs 4.5:1)
  • dark link (brand-20) on dark surface: 10.27:1 (needs 4.5:1)
  • dark brand (brand-30) on dark surface: 8.33:1 (needs 4.5:1)
  • body text (gray-95) on white: 18.24:1 (needs 7:1)
  • subtle text (gray-60) on white: 8.44:1 (needs 4.5:1)
  • danger text on white: 6.96:1 (needs 4.5:1)
  • success text on white: 6.26:1 (needs 4.5:1)
  • warning text on white: 6.66:1 (needs 4.5:1)
  • info text on white: 6.42:1 (needs 4.5:1)
  • white on info (info-50): 5.08:1 (needs 4.5:1)
  • info text (info-50) on white: 5.08: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 — 6 primary slots

  • 1 teal green
    #159999
  • 2 terracotta
    #9d381f
  • 3 light green
    #2b9c71
  • 4 slate-violet
    #634f95
  • 5 amber
    #aa7e18
  • 6 ocean blue
    #027d9f
  • lightness band — all inside L 0.43–0.77
  • chroma floor — all ≥ 0.1
  • CVD separation (adjacent) — worst #9d381f↔#2b9c71 ΔE 14.1 (deutan); target ≥ 8, floor 6
  • normal-vision floor — worst #aa7e18↔#027d9f ΔE 22.5; 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 — 6 primary slots

  • 1 teal green
    #219f9f
  • 2 terracotta
    #be563d
  • 3 ocean blue
    #1987a8
  • 4 amber
    #b38309
  • 5 slate-violet
    #7f6cb4
  • 6 light green
    #33a377
  • lightness band — all inside L 0.48–0.67
  • chroma floor — all ≥ 0.1
  • CVD separation (adjacent) — worst #219f9f↔#be563d ΔE 13.1 (deutan); target ≥ 8, floor 6
  • normal-vision floor — worst #7f6cb4↔#33a377 ΔE 21.9; floor 15
  • contrast vs surface — all ≥ 3:1 on #2a2927
  • 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="goap" — 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.