GitHub

Color

Two tiers: fixed primitive ramps (the raw palette) and intent-based semantic roles that components reference. Theme by overriding the semantic layer — primitives never move.

Brand color

The active theme's brand ramp — these semantic tokens update live when you switch themes.

Brand (current theme)
subtle
muted
border
fill
hover
text

Primitive ramps

Raw values. Never used directly in components — they exist so semantic roles can point at them.

Step usage

Each ramp follows the Radix scale convention. Quick reference:

StepsPurpose
1–2App and component backgrounds
3–5Interactive component backgrounds (hover, pressed)
6–8Borders and separators
9Solid fills — buttons, badges, overlays. Highest chroma in the scale.
10Hover state for a step-9 fill
11Low-contrast colored text on surfaces (outline buttons, links, labels)
12High-contrast text

Foreground text on step-9 fills: use white for most scales. Use a dark foreground (step 12 or --color-gray-12) only for the bright scales: Lime, Yellow, Amber, Sky, Mint — their step-9 is light enough that white text fails contrast.

Gray
1
2
3
4
5
6
7
8
9
10
11
12
Gray — dark
1
2
3
4
5
6
7
8
9
10
11
12
Grass — primary
1
2
3
4
5
6
7
8
9
10
11
12
Grass — dark
1
2
3
4
5
6
7
8
9
10
11
12
Blue
1
2
3
4
5
6
7
8
9
10
11
12
Blue — dark
1
2
3
4
5
6
7
8
9
10
11
12
Teal
1
2
3
4
5
6
7
8
9
10
11
12
Orange — accent
1
2
3
4
5
6
7
8
9
10
11
12
Copper — AI contexts
1
2
3
4
5
6
7
8
9
10
11
12
Lime — success
1
2
3
4
5
6
7
8
9
10
11
12
Lime — dark
1
2
3
4
5
6
7
8
9
10
11
12
Green
1
2
3
4
5
6
7
8
9
10
11
12
Red
1
2
3
4
5
6
7
8
9
10
11
12
Red — dark
1
2
3
4
5
6
7
8
9
10
11
12
Yellow
1
2
3
4
5
6
7
8
9
10
11
12
Yellow — dark
1
2
3
4
5
6
7
8
9
10
11
12
Gray alpha
1
2
3
4
5
6
7
8
9
10
11
12
Black alpha
1
2
3
4
5
6
7
8
9
10
11
12
White alpha
1
2
3
4
5
6
7
8
9
10
11
12

Semantic tokens

What components actually consume. Re-skinning a project = reassigning these.

Every name reads color → property → intention → variant → state, and the property is always one of background, content or border. So the token you want is guessable: a danger border is --color-border-utility-danger, never --color-danger-border.

--color-background-*

Fills and surfaces — the colour behind things.

--color-background The page canvas
--color-background-elevation-raised Cards, panels
--color-background-elevation-floating Dialogs, menus, popovers
--color-background-elevation-sunken Wells, inset areas
--color-background-default-knockout Dark chrome — top bars, nav
--color-background-brand Primary actions
--color-background-brand-subtle Brand-tinted sections
--color-background-brand-muted Chips, tags, filter pills
--color-background-brand-active Pressed brand fill
--color-background-utility-success Success fill
--color-background-utility-warning Warning fill
--color-background-utility-danger Danger fill
--color-background-utility-info Info fill
--color-background-disabled The fill of a disabled input, select, checkbox or dropzone

--color-content-*

Text, icons and SVG strokes — the colour of things sitting ON a background.

--color-content-default Body text
--color-content-default-secondary Supporting text — placeholders, timestamps, help text
--color-content-default-tertiary A third prominence level
--color-content-default-knockout Text on inverse backgrounds
--color-content-link Links
--color-content-brand Brand-coloured text
--color-content-utility-success Success text
--color-content-utility-warning Warning text
--color-content-utility-danger Danger text
--color-content-utility-info Info text
--color-content-disabled Disabled labels

--color-content-on-*

Foreground ON the matching solid fill. One per intention — the bright ramps (lime, yellow) need dark text where the rest take light, and hardcoding #fff is how that gets missed.

--color-content-on-brand On --color-background-brand
--color-content-on-brand-muted On --color-background-brand-muted
--color-content-on-utility-success On --color-background-utility-success
--color-content-on-utility-warning On --color-background-utility-warning
--color-content-on-utility-danger On --color-background-utility-danger
--color-content-on-utility-info On --color-background-utility-info

--color-border-*

Strokes and dividers.

--color-border Default border
--color-border-default-subtle Quiet dividers
--color-border-default-strong Emphasised border
--color-border-default-focus Focus ring
--color-border-brand Brand-tinted border
--color-border-utility-success Success border
--color-border-utility-warning Warning border
--color-border-utility-danger Danger border
--color-border-utility-info Info border
--color-border-disabled The border of a disabled input, select, checkbox or dropzone

Theming

A spoke project overrides semantic roles under a scope; the brand changes everywhere at once, components untouched:

[data-theme="beacon"] {
  --color-background-brand: #1f7a6d;
  --color-background-brand-hover: #155a50;
  --color-background-elevation-sunken: #f0f6f4;
}