Foundations / Colour system

Colour system

145 colours from one Figma collection, in two modes. Dark is the :root default; light is opt-in with data-mode='light' on <html>.

How the palette is built

One primitive ramp, everything else on top

Only the neutral ramp holds raw greys. Every neutral-derived token — text, surfaces, borders, the secondary button — is declared as a reference into it, exactly as Figma declares it. The ramp inverts between modes, so one unchanged declaration paints two colours:

:root,
[data-mode='dark'] {
  --neutral-900: #f9f9f9;
  --text-typical: var(--neutral-900);
}

[data-mode='light'] {
  --neutral-900: #333333;
  --text-typical: var(--neutral-900);
}

The chips below are filled with the token itself rather than a copy of its value, so toggling the theme in the header repaints them. Printed values have their references resolved per mode, dark first — a swatch reading #f9f9f9 / #333333 is one declaration, not two. Colours Figma stores as literals stay literals here even where two of them happen to match today, so a future divergence cannot hide behind an alias.

Neutral ramp

12 tokens · the primitives

The index counts distance from the surface, not lightness: 900 is the furthest from the page and therefore the text colour in both modes. Base --neutral is the nearest surface — white in light, near-black in dark. Retint these and everything aliased to them moves.

neutral
#313131 / #ffffff
neutral-50
#1e1e1e / #f9f9f9
neutral-100
#222222 / #f3f3f3
neutral-200
#282828 / #ebebeb
neutral-300
#373737 / #dddddd
neutral-400
#4c4c4c / #cdcdcd
neutral-500
#7c7c7c / #9a9a9a
neutral-600
#aaaaaa / #858484
neutral-700
#d7d3d3 / #626262
neutral-800
#ececec / #454545
neutral-900
#f9f9f9 / #333333
neutral-backdrop
#00000080

Text

4 tokens

--text-inverse is the label on a solid fill and is near-white in both modes, which is why it is the only one of the four that does not simply follow the ramp.

text-typical
#f9f9f9 / #333333
text-additional
#d7d3d3 / #626262
text-disabled
#7c7c7c / #9a9a9a
text-inverse
#f9f9f9 / #ffffff

Surface

6 tokens

Depth 0 is the nearest surface — a card — and Depth 3 the deepest, which is the page behind it. The order is the same in both modes even though the greys invert.

surface-depth-0
#313131 / #ffffff
surface-depth-1
#282828 / #f9f9f9
surface-depth-2
#222222 / #f3f3f3
surface-depth-3
#1e1e1e / #ebebeb
surface-inactive
#373737 / #ebebeb
surface-disabled
#7c7c7c / #9a9a9a

Border

4 tokens

border-lighter
#222222 / #f3f3f3
border-light
#4c4c4c / #ebebeb
border-default
#7c7c7c / #dddddd
border-strong
#aaaaaa / #9a9a9a

Button

17 tokens

Five families, each with a hover and a pressed value; Button is the only group Figma ships full interaction states for. --button-inactive is not consumed — ALPHA renders a disabled button at 45% opacity rather than swapping its fill.

button-neutral-surface
#313131 / #ffffff
button-secondary
#373737 / #f9f9f9
button-secondary-hover
#4c4c4c / #f3f3f3
button-secondary-pressed
#7c7c7c / #ebebeb
button-inactive
#373737 / #ebebeb
button-primary
#562ff0 / #482be9
button-primary-hover
#9372f5 / #7751f3
button-primary-pressed
#2e23e0
button-success
#28aa00 / #1b9b00
button-success-hover
#72c361 / #50b73c
button-success-pressed
#008a00 / #007900
button-warning
#ff9700 / #fc8b00
button-warning-hover
#ffb64d / #ffa626
button-warning-pressed
#f67b01 / #f06a01
button-danger
#f53635 / #e62b34
button-danger-hover
#e56e72 / #f04a50
button-danger-pressed
#d4202e / #c71627

Primary and status

12 tokens

The brand indigo and the three status hues, for anything that is not a button — a focus ring, a badge, an inline message.

primary
#562ff0 / #482be9
primary-hover
#9372f5 / #7751f3
primary-pressed
#2e23e0
status-success
#28aa00 / #1b9b00
status-success-hover
#72c361 / #50b73c
status-success-pressed
#008a00 / #007900
status-warning
#ff9700 / #fc8b00
status-warning-hover
#ffb64d / #ffa626
status-warning-pressed
#f67b01 / #f06a01
status-danger
#f53635 / #e62b34
status-danger-hover
#e56e72 / #f04a50
status-danger-pressed
#d4202e / #c71627

Tooltip

6 tokens

ALPHA ships no tooltip component. These are here because the Figma collection is complete, not because the component is — build one against your own markup for now.

tooltip-text
#f9f9f9 / #ffffff
tooltip-text-translucent
#ffffff80
tooltip-background
#373737 / #333333
tooltip-text-inverse
#313131 / #333333
tooltip-background-inverted
#f9f9f9 / #ffffff
tooltip-background-additional
#7c7c7c / #9a9a9a

Charts

32 tokens · 16 series

Sixteen categorical series in order, each with a hover. Figma names them after a hue; the name here is the ordinal, because that is what a chart indexes by — and because the hue is not reliable: four of the sixteen are a different colour from the Vivid hue they share a name with, which is why the two groups are declared independently.

chart-1
#562ff0 / #482be9
chart-1-hover
#9372f5 / #7751f3
chart-2
#ff9700 / #fc8b00
chart-2-hover
#ffb64d / #ffa626
chart-3
#00c1d4 / #00b1c1
chart-3-hover
#4fd4e0 / #28cbd9
chart-4
#d000e4 / #be00df
chart-4-hover
#e260ee / #d92ce9
chart-5
#00ca69 / #00ba5d
chart-5-hover
#16de97 / #00d57e
chart-6
#e65726 / #db5122
chart-6-hover
#eb8765 / #e86e45
chart-7
#669adf / #5e8cd1
chart-7-hover
#85b7e9 / #72a8e4
chart-8
#85492b / #794025
chart-8-hover
#b37d62 / #9c6246
chart-9
#dc9746 / #d78d41
chart-9-hover
#e6b46a / #e1a552
chart-10
#b7d332 / #acc22b
chart-10-hover
#cce170 / #c1da51
chart-11
#e4c61e / #d5b61c
chart-11-hover
#e9ce45 / #e4c61e
chart-12
#1f9691 / #1d8984
chart-12-hover
#54b6b4 / #33a6a3
chart-13
#28aa00 / #1b9b00
chart-13-hover
#72c361 / #50b73c
chart-14
#9525c9 / #8623c3
chart-14-hover
#b568da / #a547d2
chart-15
#b600a4 / #a8009f
chart-15-hover
#c323b0
chart-16
#fb0078 / #e90075
chart-16-hover
#fb0078 / #fa3c8f

Vivid

39 tokens · 13 hues

Base, hover and pressed for each hue, for surfaces that need to be told apart rather than ranked.

vivid-lilac
#9525c9 / #8623c3
vivid-lilac-hover
#b568da / #a547d2
vivid-lilac-pressed
#7020bb / #5b1db3
vivid-orchid
#cf56be / #a8009f
vivid-orchid-hover
#cf56be / #c323b0
vivid-orchid-pressed
#950099 / #850093
vivid-violet
#d000e4 / #be00df
vivid-violet-hover
#e260ee / #d92ce9
vivid-violet-pressed
#a700d9 / #9300d5
vivid-ruby
#fb0078 / #e90075
vivid-ruby-hover
#fa63a5 / #fa3c8f
vivid-ruby-pressed
#d2016f / #bc006a
vivid-aqua
#00c1d4 / #00b1c1
vivid-aqua-hover
#4fd4e0 / #28cbd9
vivid-aqua-pressed
#029ca7 / #03878f
vivid-emerald
#00ca69 / #00ba5d
vivid-emerald-hover
#16de97 / #00d57e
vivid-emerald-pressed
#00a750 / #009544
vivid-olive
#b7d332 / #acc22b
vivid-olive-hover
#c1da51 / #b7d332
vivid-olive-pressed
#9cac23 / #8c951b
vivid-teal
#1f9691 / #1d8984
vivid-teal-hover
#54b6b4 / #33a6a3
vivid-teal-pressed
#1a7973 / #196963
vivid-brick
#e65726 / #db5122
vivid-brick-hover
#eb8765 / #e86e45
vivid-brick-pressed
#ce4b1e / #c0451b
vivid-chocolate
#85492b / #794025
vivid-chocolate-hover
#b37d62 / #9c6246
vivid-chocolate-pressed
#69341c
vivid-caramel
#dc9746 / #d78d41
vivid-caramel-hover
#e6b46a / #e1a552
vivid-caramel-pressed
#cf803c / #c77438
vivid-cornflower
#669adf / #5e8cd1
vivid-cornflower-hover
#85b7e9 / #72a8e4
vivid-cornflower-pressed
#557abe / #4d6aab
vivid-mustard
#e4c61e / #d5b61c
vivid-mustard-hover
#e9ce45 / #e4c61e
vivid-mustard-pressed
#c1a116 / #ac8b12

Aquarelle

9 tokens

Pale washes for tinted backgrounds — the ghost destructive button hovers onto --aquarelle-red. They are opaque and tuned against Depth 0, so on any other surface they read as a patch rather than a tint.

aquarelle-graphics-blue
#2b3746 / #f1f7ff
aquarelle-graphics-blue-hover
#364963 / #dbebff
aquarelle-primary-inactive
#292b3d / #ebedff
aquarelle-red
#3d2929 / #feefef
aquarelle-orange
#3d3729 / #fff4d9
aquarelle-paper
#504230 / #f4efe8
aquarelle-green
#2f3d29 / #e9fde0
aquarelle-lilac
#3c3050 / #f0e7ff
aquarelle-lilac-medium
#30293d / #f8f5fe

Indigo

4 tokens

Brand constants, and the only colours identical in both modes.

indigo-300
#a4a4bc
indigo-500
#303046
indigo-700
#262638
indigo-900
#04041c

Theming

Retinting is the supported way to theme ALPHA — override a token, never a component class. Override it in the same two-block shape the package uses: a bare :root rule comes later in the cascade at equal specificity, so it would land on both modes at once.

:root,
[data-mode='dark'] {
  --primary: #0f766e;
}

[data-mode='light'] {
  --primary: #0d6157;
}

Because the semantics alias into the ramp, retinting --neutral-900 alone moves --text-typical, --text-inverse, --tooltip-text and --tooltip-background-inverted with it.

These names are not namespaced — --primary and --chart-1 are ordinary global custom properties, so they match the Figma hand-off exactly and collide with an application that already defines them. If yours does, rename it or scope ALPHA to a subtree.