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
Australian landscape landscape
Eucalypt, ochre, red earth, wattle, billabong blue, saltbush, jacaranda and sandstone neutrals — moderate chroma so the palette reads as country, not as a highlighter set. Ramps are generated onto PatternFly's step curve; every contrast promise per step holds.
- Brand family
green— links, focus ring, primary buttons, masthead- Role remaps
brand → greeninfo → blue- Provenance
- Designed for csdr-project (D13). Working names; tune hues on /design/palette within the gates.
- Select it
- Report:
palette: landscapein frontmatter · Site:PUBLIC_CSDR_PALETTE=landscape· Page:<SiteLayout palette="landscape">
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#e4eff9
#c2dbf1
#a2c7e7
#73a6d2
#3573a4
#316288
#1e3f59
#152a3b
tealcustom#e4f0ef
#c4dedb
#a4cbc8
#74ada9
#4a8e8a
#326864
#1f4340
#152c2b
greenbrand#e6f0e8
#c8dfcb
#aacdb0
#7eae87
#427a4f
#3d6947
#26442c
#1a2d1e
yellowwarning#f6ecd9
#ead5ab
#ddbe7d
#c59931
#a07a15
#765805
#4c3803
#342501
orange#fbe9dd
#f5cfb4
#ecb58c
#d88d50
#bd670d
#8c4900
#5b2e01
#3d1f05
red-orangedanger#ffe7e1
#fccabd
#f6ae9b
#e48169
#ca593d
#963e29
#622718
#411a11
red#fff0ef
#fee7e6
#fdc8c7
#faa9a8
#e97b7d
#ce5057
#99373d
#652226
#43181a
purple#efebf6
#ddd2eb
#cabadf
#ac95c7
#8d73ac
#67527f
#423452
#2c2337
gray#f5f2ee
#e2e0dc
#c9c7c3
#a5a39f
#8e8c88
#72706c
#4f4d4a
#3a3835
#2b2926
#211f1c
#171512
brownextension#f4ebe7
#e5d3ca
#d6bcae
#bc9885
#9e7660
#745544
#4b362b
#32241d
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.
| Family | 50 on white | 60 on white | 70 on white | 30 on dark | 40 on dark | 10 vs white |
|---|---|---|---|---|---|---|
| blue | ✓ 5.07 | ✓ 6.5 | ✓ 10.99 | ✓ 8.22 | ✓ 5.62 | ✓ 1.17 |
| green | ✓ 5.09 | ✓ 6.34 | ✓ 10.79 | ✓ 8.36 | ✓ 5.74 | ✓ 1.17 |
| orange | ✓ 4.11 | ✓ 6.84 | ✓ 11.44 | ✓ 8 | ✓ 5.44 | ✓ 1.18 |
| purple | ✓ 4.05 | ✓ 6.8 | ✓ 11.38 | ✓ 8.04 | ✓ 5.46 | ✓ 1.17 |
| red | ✓ 4.28 | ✓ 7.07 | ✓ 11.6 | ✓ 7.83 | ✓ 5.26 | ✓ 1.18 |
| red-orange | ✓ 4.19 | ✓ 6.96 | ✓ 11.52 | ✓ 7.93 | ✓ 5.29 | ✓ 1.18 |
| teal | ✓ 3.8 | ✓ 6.36 | ✓ 10.85 | ✓ 8.28 | ✓ 5.75 | ✓ 1.17 |
| yellow | ✓ 3.97 | ✓ 6.63 | ✓ 11.2 | ✓ 8.13 | ✓ 5.52 | ✓ 1.17 |
Role tokens
- ✓ link on white (brand-50): 5.09:1 (needs 4.5:1)
- ✓ link on secondary surface (brand-50 on gray-10): 4.56:1 (needs 4.5:1)
- ✓ brand text (brand-60) on white: 6.34:1 (needs 4.5:1)
- ✓ white on brand (brand-50): 5.09:1 (needs 4.5:1)
- ✓ dark link (brand-20) on dark surface: 10.3:1 (needs 4.5:1)
- ✓ dark brand (brand-30) on dark surface: 8.36:1 (needs 4.5:1)
- ✓ body text (gray-95) on white: 18.22:1 (needs 7:1)
- ✓ subtle text (gray-60) on white: 8.42:1 (needs 4.5:1)
- ✓ danger text on white: 6.96:1 (needs 4.5:1)
- ✓ success text on white: 6.34:1 (needs 4.5:1)
- ✓ warning text on white: 6.63:1 (needs 4.5:1)
- ✓ info text on white: 6.5:1 (needs 4.5:1)
- ✓ white on info (info-50): 5.07:1 (needs 4.5:1)
- ✓ info text (info-50) on white: 5.07: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
- ✓ lightness band — all inside L 0.43–0.77
- ✓ chroma floor — all ≥ 0.1
- ✓ CVD separation (adjacent) — worst #8b4b06↔#209993 ΔE 17.6 (deutan); target ≥ 8, floor 6
- ✓ normal-vision floor — worst #8d6d01↔#3e8cc9 ΔE 23.8; 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
Dark surface — 6 primary slots
- ✓ lightness band — all inside L 0.48–0.67
- ✓ chroma floor — all ≥ 0.1
- ✓ CVD separation (adjacent) — worst #ce710c↔#018d87 ΔE 12.9 (protan); target ≥ 8, floor 6
- ✓ normal-vision floor — worst #448c56↔#987aca ΔE 23.1; floor 15
- ✓ contrast vs surface — all ≥ 3:1 on #2b2926
- All-pairs clean (scatter, maps, small multiples) up to 2 slots.
Sequential 7
Diverging
Status
Six series, this palette (build-time SVG)
View data
| year | North (index) | South (index) | East (index) | West (index) | Central (index) | Islands (index) |
|---|---|---|---|---|---|---|
| 2019 | 12 | 8 | 5 | 10 | 3 | 6 |
| 2020 | 14 | 9 | 7 | 8 | 4 | 5 |
| 2021 | 13 | 11 | 6 | 9 | 6 | 4 |
| 2022 | 16 | 10 | 9 | 7 | 5 | 6 |
View data
| year | North | South | East | West | Central | Islands |
|---|---|---|---|---|---|---|
| 2019 | 12 | 8 | 5 | 10 | 3 | 6 |
| 2020 | 14 | 9 | 7 | 8 | 4 | 5 |
| 2021 | 13 | 11 | 6 | 9 | 6 | 4 |
| 2022 | 16 | 10 | 9 | 7 | 5 | 6 |
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="landscape" — nothing is styled specially for this page.
Brand and status
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
- Edit or add
packages/theme/palettes/<id>.json: nine families ashue+chroma(with optionalpins for exact brand hexes), optionalextensions,roles, and the chart sets. - 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. pnpm check(which runscheck:palette) fails on any drift between the JSON and the generated files, so hexes never get hand-edited downstream.- Look at it here and in the report preview; then
pnpm testfor the axe/VR matrix. See Theme → Palettes and D13.