Tonal Categorical Palette¶
Single-hue categorical palettes for editorial / brand-restrained dashboards. Five hues ship in M2: blue, green, purple, orange, brown — each anchored on a category-10 slot so they coordinate with the default categorical system.
| Palette | Hue (OKLCH) | Anchor (slot 0) |
|---|---|---|
category-6-tonal-blue |
H ≈ 248.8° | #0375c4 |
category-6-tonal-green |
H ≈ 161.3° | #00875a |
category-6-tonal-purple |
H ≈ 319.1° | #9650a8 |
category-6-tonal-orange |
H ≈ 41° | #b74c1f |
category-6-tonal-brown |
H ≈ 64° (slots 0-3) / H ≈ 78° (slots 4-5) | #9a642b |
When to use¶
When a dashboard wants one hue throughout for editorial/brand reasons — "the all-blue dashboard," "the all-green dashboard." Tonal palettes are an option, not the default. The default categorical family is category-10 and stays so.
Reasonable fits: - Editorial / branded dashboards where chromatic restraint matters more than category count. - Small-multiples and KPI tiles where the color budget is tight. - Charts with direct labels or stable category order — the legend reads via labels, not by glance.
Poor fits:
- Many-slice pies, dense scatters, stacked bars with > 4 segments — the brief warns these need stronger discrimination than monochrome can provide.
- Charts that depend solely on color for category identity at small mark sizes.
- More than 6 categories. If you need 7+, use category-10.
Architecture: 4 strict-safe + 2 extended¶
Every tonal palette ships 6 stops with a layered contract:
| Slots | Role | CVD safety |
|---|---|---|
| 0–3 (core) | strict-safe | Leonardo ΔE ≥ 11 pairwise across normal/deuteranopia/protanopia/tritanopia. Color alone is sufficient. |
| 4–5 (extended) | form-redundant only | Below the Leonardo gate. Require dash / marker / pattern redundancy when used in a chart — not safe color-alone. |
The 6-stop cap is intentional. The research brief (ai_notes/considerations/DFT_TONAL_CATEGORICAL_PALETTE_2026.md) is explicit: monochrome categorical fails past 6 categories, regardless of how the palette is tuned. Past 4–5, English's color vocabulary saturates ("two blues that are 'just blue'"), and CVD simulation collapses adjacent stops in a single hue.
The math behind the 4/2 split: at fixed hue, 4 slots in the OKLCH L* range that passes WCAG and Leonardo simultaneously must span ~50 L* points (e.g. 25 → 75). Adding a 5th slot in that same band is below the gate; we ship it anyway, with the form-redundancy contract.
Slot semantics (consistent across all five hues)¶
Every tonal palette uses the same slot ordering and roles:
| Slot | Role | Typical L* |
|---|---|---|
| 0 | anchor / default single-series | ~55 |
| 1 | light tint | ~75 |
| 2 | dark saturated | ~40 |
| 3 | very dark | ~25 |
| 4 | mid dull (extended) | ~62 |
| 5 | pale (extended) | ~86 |
Order is non-monotonic by L* — the eye doesn't read the palette as a ramp. Slot 0 is the brightest "default leader" position; the palette alternates light/dark across slots 1–3.
Generation methodology¶
Authored in OKLCH per ai_notes/considerations/DFT_M2_PALETTE_DECISIONS_2026.md (rubric R1). Each candidate validated with:
scripts/palette_deltae_checker.py— Leonardo CVD ΔE ≥ 11 (primary gate).scripts/palette_scoring.py— Colorgorical-style Name Difference, Name Uniqueness, Pair Preference (secondary signals).- WCAG SC 1.4.11 contrast (3:1 for non-text) against both pure white and
cream-025(#FAF7F0) backgrounds.
Iteration history and per-candidate scoring are in ai_notes/palette_studio/tonal_session.html and ai_notes/palette_studio/tonal_session.py.
Brown ↔ editorial-cream bridge¶
category-6-tonal-brown differs from the others in one way: its extended slots (4–5) are hue-wobbled +14° from the brown anchor (H=64° → H=78°) to land in the same OKLCH region as the dft-creams scaffold (creams sit at H=80–87°).
The visible result: tonal-brown's lightest extended stops feel like an extension of the editorial-cream theme's chrome, not as separate "near-neutrals." A chart with category-6-tonal-brown on the editorial-cream theme reads as continuous with its surroundings — that's the editorial coherence we want for warm-canvas themes.
Side effect: slot 5 (#d8d0c3) has low contrast against cream-025 (~1.4:1). That's the cream bridge working as intended — the pale extended stop visually merges with the cream chrome. Use slot 5 only with form redundancy on cream backgrounds; the merge is the point.
Each palette¶
category-6-tonal-blue¶
| # | Hex | OKLCH | Reads as |
|---|---|---|---|
| 0 | #0375c4 |
L=55 C=0.15 | bluish |
| 1 | #81b3e5 |
L=75 C=0.09 | carolina blue |
| 2 | #004a7f |
L=40 C=0.11 | prussian blue |
| 3 | #002341 |
L=25 C=0.07 | marine |
| 4 | #6f89a3 |
L=62 C=0.05 | blue/grey (extended) |
| 5 | #c2d3e4 |
L=86 C=0.03 | light blue grey (extended) |
Leonardo core-4 min ΔE = 12.23.
category-6-tonal-green¶
| # | Hex | OKLCH | Reads as |
|---|---|---|---|
| 0 | #00875a |
L=55 C=0.12 | dark sea green |
| 1 | #78c09c |
L=75 C=0.09 | pale teal |
| 2 | #005638 |
L=40 C=0.09 | spruce |
| 3 | #002a19 |
L=25 C=0.06 | dark forest green |
| 4 | #6c907d |
L=62 C=0.05 | slate green (extended) |
| 5 | #c1d7cb |
L=86 C=0.03 | light grey (extended) |
Leonardo core-4 min ΔE = 11.71.
category-6-tonal-purple¶
| # | Hex | OKLCH | Reads as |
|---|---|---|---|
| 0 | #9650a8 |
L=55 C=0.15 | medium purple |
| 1 | #c79cd2 |
L=75 C=0.09 | pale purple |
| 2 | #642a73 |
L=40 C=0.13 | darkish purple |
| 3 | #301536 |
L=25 C=0.07 | eggplant |
| 4 | #947d9a |
L=62 C=0.05 | purpley grey (extended) |
| 5 | #dacbde |
L=86 C=0.03 | pale lavender (extended) |
Leonardo core-4 min ΔE = 12.88.
category-6-tonal-orange¶
| # | Hex | OKLCH | Reads as |
|---|---|---|---|
| 0 | #b74c1f |
L=55 C=0.15 | brick orange |
| 1 | #df9b82 |
L=75 C=0.09 | pinkish tan |
| 2 | #7b2900 |
L=40 C=0.12 | chestnut |
| 3 | #3c1303 |
L=25 C=0.07 | chocolate brown |
| 4 | #a17d6f |
L=62 C=0.05 | reddish grey (extended) |
| 5 | #e3cbc2 |
L=86 C=0.03 | pinkish grey (extended) |
Leonardo core-4 min ΔE = 13.05.
category-6-tonal-brown¶
| # | Hex | OKLCH | Reads as |
|---|---|---|---|
| 0 | #9a642b |
L=55 C=0.10 H=64° | sepia |
| 1 | #c9a687 |
L=75 C=0.06 H=63° | mushroom |
| 2 | #683b01 |
L=40 C=0.09 H=64° | brown |
| 3 | #321c04 |
L=25 C=0.05 H=65° | dark brown |
| 4 | #908472 |
L=62 C=0.03 H=78° | brown grey (extended; cream bridge) |
| 5 | #d8d0c3 |
L=86 C=0.02 H=80° | light grey (extended; cream bridge) |
Leonardo core-4 min ΔE = 12.49.
Heuristic for picking a tonal palette¶
If a reader has to identify a category by glancing at a legend, monochrome alone won't be enough.
If category identity comes from one or more of: direct labels, chart structure, repeated/stable order, dash style, marker shape, pattern fill — then a tonal palette is viable. Otherwise, use category-10.