Principles
- 01Six categories or fewer per chart. Beyond six, the eye stops distinguishing hues. Group, summarize, or split into multiple charts.
- 02Reuse the order. The categorical palette has a fixed sequence beginning with blurple. The same series position lands the same color across every chart.
- 03Status colors keep their meaning.Red is failure; green is success. Don't use them in a categorical sequence where they'd imply judgement on the data.
- 04Don't place text on chart fills.The 600-weight saturated colors used in charts don't meet 4.5:1 against white. Labels live next to their data, not on top.
Single-color charts
When a chart pairs a focal series with reference data, use --chart-categorical-1 for the focal bars and --chart-neutral for everything the eye should skip past first — historical comparisons, the non-focal segment of a stacked bar, anything shown for context only. --chart-axis handles gridlines and axes.
Card transactions
2.055,00 kr
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Why neutral for the non-focal data
A second saturated hue would compete for attention. --chart-neutralreads as "this is reference, not the point" — useful for past-period comparisons and for the supporting segment of a stacked bar where only one part of the stack is the story.
Categorical palette
For up to eight unrelated series at the primary 600 weight. The order matters — always start at --chart-categorical-1 and go in sequence so a merchant's "Card" series stays the same color across every dashboard view.
1–8 · 600 weight
1
--color-blurple-600
2
--color-green-600
3
--color-purple-600
4
--color-pink-600
5
--color-orange-600
6
--color-yellow-600
7
--color-blue-600
8
--color-red-600
Payment types
123,456.78 €
- Card38%
- Apple Pay22%
- Google Pay14%
- MobilePay11%
- Klarna9%
- Cash6%
Beyond eight series
For dashboards with more than eight series, the palette continues at 800 weight (9–16) and 900 weight (17–24) in the same hue order. The same color in a deeper weight reads as a related variant — useful for stacked breakdowns.
9–16 · 800 weight
9
--color-blurple-800
10
--color-green-800
11
--color-purple-800
12
--color-pink-800
13
--color-orange-800
14
--color-yellow-800
15
--color-blue-800
16
--color-red-800
17–24 · 900 weight
17
--color-blurple-900
18
--color-green-900
19
--color-purple-900
20
--color-pink-900
21
--color-orange-900
22
--color-yellow-900
23
--color-blue-900
24
--color-red-900
Six is still the soft cap
The 24-step palette exists to support stacked / grouped charts where the same hue appears at different weights, not to encourage 24-series visualizations. If you need more than 8 distinguishable series in a single chart, the chart wants a redesign more than a new palette.
Status & severity
For charts that show outcomes — success/failure rates, severity buckets, SLA breaches — use the system status tokens directly. They mean the same thing in a chart as on a status pill.
Success
--color-background-success
Approved transactions, completed payouts, healthy services.
Warning
--color-background-warning
Pending decisions, near-threshold metrics, delayed batches.
Danger
--color-background-danger
Declined transactions, error rates, SLA breaches.
Information
--color-background-information
Neutral information, infrastructure status, links.
Discovery
--color-background-discovery
Beta surfaces, what's-new banners, first-time-seen content.
Currency & negative values
Flatpay's product is full of money, and money goes both ways. The system provides three numeric text tokens: --text-numeric-positive, --text-numeric-negative, and --text-numeric-voided for struck-through or refunded values. Always pair color with a sign character so meaning carries without color.
Accessibility in charts
- Always pair color with a second cue. A patterned fill, a marker shape, a label, or a leading icon. Color blindness affects roughly 8% of men.
- Use 1px borders or 2px gaps between adjacent fills to separate regions when the colors are perceptually close (e.g. blurple and purple, orange and red).
- Don't overlay text on chart fills.The 600-weight palette values don't meet 4.5:1 against white. Labels go on the chart background, in the legend, or in a tooltip.
- Test in monochrome. Print the chart in grayscale or apply a desaturation filter — if the data is still readable, the color is enhancement rather than load-bearing.
Token reference
css
/* Single color */
--chart-categorical-1 /* lead series — --color-blurple-600 */
--chart-neutral /* historical / inactive — --color-neutral-300 */
--chart-axis /* gridlines and axes — --color-neutral-400 */
/* Categorical 1–24 — fixed hue order at three weights */
--chart-categorical-1 … --chart-categorical-8 /* 600 weight: blurple, green, purple, pink, orange, yellow, blue, red */
--chart-categorical-9 … --chart-categorical-16 /* 800 weight: same hue order, deeper */
--chart-categorical-17 … --chart-categorical-24 /* 900 weight: same hue order, deepest */
/* Status / severity — semantic, not chart-only */
--background-success
--background-warning
--background-danger
--background-information
--background-discovery
/* Money — text tokens for tabular numerals */
--text-numeric-positive /* gains, credits */
--text-numeric-negative /* losses, fees, chargebacks */
--text-numeric-voided /* struck-through, refunded */
--text-numeric-primary /* default tabular text */
--text-numeric-secondary /* subdued tabular text */Sequential and divergent palettes
Sequential (e.g. heatmap green-to-dark) and divergent (e.g. red-blue centered on a midpoint) palettes aren't in the system yet. If you need one, document the intent in your prototype's CLAUDE.md and we'll fold it in here once we've seen the pattern twice.