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.