Colors
The color names a dashboard.toml accepts, where each one goes, and the full palette to pick from.
Charts are gray until you ask for a color
Every data-viz widget — chart,
timeline,
gantt-chart,
treemap — renders in neutral grays by default,
and those grays adapt to light and dark mode on their own. A color only
appears when something in dashboard.toml asks for one.
That default is deliberate: a chart where every series is a different hue spends its color budget on decoration. Leaving colors unset and pinning only the one series that carries meaning ("late jobs are red") is what makes that one series read.
Asking the chat is usually faster than editing TOML
You don't have to write any of the TOML on this page by hand. On a project's
dashboard, ask the chat by name — "make the cost chart green-600", or
"blue-700 in light mode, blue-300 in dark". The names below are the
vocabulary it understands; click any swatch to copy one.
A color is a Tailwind name, never a hex
Wherever dashboard.toml takes a color, it takes one of two things:
- A name —
<family>-<shade>(green-600,neutral-400), orblack/white. Used as-is in both light and dark mode. - A
{ light, dark }pair of names —{ light = "blue-700", dark = "blue-300" }. Each theme gets its own, so the color stays readable on either background.
A hex value ("#16a34a") is not accepted, and neither is a name that
isn't in the palette below. There's no automatic light/dark flipping either —
if you want a different shade per theme, say both.
An unrecognized color is skipped, not reported
A widget with an invalid color still renders: the bad value is dropped and that series or group falls back to the default gray, rather than the whole widget failing. So a typo'd name or a hex looks like "my color didn't apply", with nothing in the error banner. Check the name against the palette below if a color silently doesn't take effect.
Where a color goes
There are two places, and which one a widget offers depends on how it colors things.
series[].color — one color per series
chart draws one line, bar or area per entry in
series (a legacy line-chart or bar-chart reads as a chart), so the color
belongs to the entry:
[[widgets]]
type = "chart"
id = "cost-trend"
title = "Cost over time"
variant = "line"
data_key = "timeseries"
x_key = "label"
series = [
{ key = "cost", label = "Cost", color = "green-600" },
{ key = "budget", label = "Budget", color = { light = "neutral-500", dark = "neutral-400" } },
]colors — pin specific groups
timeline,
gantt-chart and
treemap don't have a fixed list of series —
they color by whatever distinct values show up in the field named by
color_key. A colors table pins chosen values to chosen colors:
[[widgets]]
type = "timeline"
id = "schedule"
title = "Machine schedule"
items_key = "schedule"
color_key = "status"
[widgets.colors]
"Late job" = "red-600"
"Unassigned" = { light = "neutral-400", dark = "neutral-600" }Every value you don't pin keeps cycling through the default grays — and the cycle skips any color a pin already claimed, so a pinned group and an auto-colored group are never handed the same color.
colors needs color_key
colors keys are matched against the raw values of the field color_key
names, so a widget with no color_key has nothing to pin — every item is
drawn from the palette cycle instead.
A chart takes colors too, keyed differently: a
pie or donut matches its keys against each slice's x_key value, and a
chart with group_key matches them against the group values, so you can pin
the one slice or group that matters and leave the rest gray:
[[widgets]]
type = "chart"
id = "cost-share"
title = "Where the cost goes"
variant = "donut"
data_key = "cost_by_machine"
x_key = "machine"
series = [{ key = "cost", label = "Cost" }]
[widgets.colors]
"Machine 3" = "red-600"The default grays
With nothing pinned, groups are assigned these six in order of first appearance. Each is a light/dark pair, which is why a default chart keeps its contrast when you switch themes:
| # | Light mode | Dark mode |
|---|---|---|
| 1 | neutral-800 | neutral-200 |
| 2 | neutral-500 | neutral-500 |
| 3 | neutral-700 | neutral-300 |
| 4 | neutral-400 | neutral-600 |
| 5 | neutral-900 | neutral-100 |
| 6 | neutral-600 | neutral-400 |
Six entries means a widget with more than six distinct groups starts repeating grays. Pin colors past that point if the repetition is confusing.
The full palette
Every name below is valid anywhere dashboard.toml takes a color — 26
families at 11 shades each (50 through 950), plus black and white.
Click a swatch to copy its name, then paste it into the chat or your TOML.
| 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| slate | |||||||||||
| gray | |||||||||||
| zinc | |||||||||||
| neutral | |||||||||||
| stone | |||||||||||
| mauve | |||||||||||
| olive | |||||||||||
| mist | |||||||||||
| taupe | |||||||||||
| red | |||||||||||
| orange | |||||||||||
| amber | |||||||||||
| yellow | |||||||||||
| lime | |||||||||||
| green | |||||||||||
| emerald | |||||||||||
| teal | |||||||||||
| cyan | |||||||||||
| sky | |||||||||||
| blue | |||||||||||
| indigo | |||||||||||
| violet | |||||||||||
| purple | |||||||||||
| fuchsia | |||||||||||
| pink | |||||||||||
| rose | |||||||||||
| black | |||||||||||
| white | |||||||||||
Checking a color before you commit
harumi dashboard validate checks a real
dashboard.toml, including the structure of a series entry and a colors
table. Since an unrecognized color is dropped rather than raised, the surest
check on the color itself is the name: it must appear in the palette above,
exactly as spelled there.