Open DS

Color

Five questions every design system answers about color. These are Content first’s answers, and each one points back to the reasons that chose it.

View all 41 color tokens ↓

The reasons this scheme answers from

  • R1Human factorsAttention on the content, they see it fresh each time
  • R2Tasks and flowsRead start to end, rarely
  • R3BrandWarm, present

Question 1

Which color roles does it need?

  • Surface, text, action and status (chosen)
  • Those and brand accents

Why Content first picks it: Reading needs few color roles.

becauseR1

surface
text
border
action
status
category
disabled

Question 2

How many emphasis levels do actions need?

  • Two
  • Three (chosen)
  • Four

Why Content first picks it: Primary, secondary and a text link.

becauseR2

stone light8
navy light3
black light1
blue light3
green light2
amber light2
red light2

Question 3

How is the palette defined?

  • Neutrals and one brand ramp (chosen)
  • Shared neutrals, a ramp per brand

Why Content first picks it: Warm paper neutrals and one ink ramp.

becauseR3

  • Neutrals and one brand ramp
  • from color.stone.light
  • from color.navy.light
  • from color.black.light
  • from color.blue.light
  • from color.green.light
  • from color.amber.light
  • from color.red.light

Decisions point at primitives, so the rule lives in one place.

Question 4

How saturated is the palette?

  • Muted
  • Balanced (chosen)
  • Vivid

Why Content first picks it: A calm, balanced palette.

becauseR3

  • surface
    canvas
    → color.stone.light.50· dark → color.stone.dark.0
    default
    → color.stone.light.0· dark → color.stone.dark.50
    raised
    → color.stone.light.0· dark → color.stone.dark.100
    sunken
    → color.stone.light.100· dark → color.stone.dark.100
    selected
    → color.navy.light.100· dark → color.navy.dark.100
    inverse
    → color.stone.light.900· dark → color.stone.dark.900
    scrim
    → color.black.light.scrim· dark → color.black.dark.scrim
  • text
    primary
    → color.stone.light.900· dark → color.stone.dark.900
    secondary
    → color.stone.light.700· dark → color.stone.dark.500
    muted
    → color.stone.light.600· dark → color.stone.dark.400
    inverse
    → color.stone.light.0· dark → color.stone.dark.50
    on-action
    → color.stone.light.0· dark → color.stone.dark.0
    link
    → color.navy.light.700· dark → color.navy.dark.700
  • border
    default
    → color.stone.light.200· dark → color.stone.dark.100
    strong
    → color.stone.light.500· dark → color.stone.dark.300
    focus
    → color.navy.light.600· dark → color.navy.dark.700
  • action
    primary.@
    → color.navy.light.600· dark → color.navy.dark.700
    primary.hover
    → color.navy.light.700· dark → color.navy.dark.800
    secondary.@
    → color.stone.light.0· dark → color.stone.dark.50
    secondary.hover
    → color.stone.light.100· dark → color.stone.dark.100
  • status
    info.@
    → color.blue.light.700· dark → color.blue.dark.700
    info.subtle
    → color.blue.light.100· dark → color.blue.dark.100
    success.@
    → color.green.light.700· dark → color.green.dark.700
    success.subtle
    → color.green.light.100· dark → color.green.dark.100
    warning.@
    → color.amber.light.700· dark → color.amber.dark.700
    warning.subtle
    → color.amber.light.100· dark → color.amber.dark.100
    danger.@
    → color.red.light.700· dark → color.red.dark.700
    danger.subtle
    → color.red.light.100· dark → color.red.dark.100
  • category
    1.@
    → color.navy.light.600· dark → color.navy.dark.700
    1.subtle
    → color.navy.light.100· dark → color.navy.dark.100
    2.@
    → color.blue.light.600· dark → color.blue.dark.700
    2.subtle
    → color.blue.light.100· dark → color.blue.dark.100
    3.@
    → color.green.light.700· dark → color.green.dark.700
    3.subtle
    → color.green.light.100· dark → color.green.dark.100
    4.@
    → color.amber.light.700· dark → color.amber.dark.700
    4.subtle
    → color.amber.light.100· dark → color.amber.dark.100
    5.@
    → color.stone.light.500· dark → color.stone.dark.700
    5.subtle
    → color.stone.light.100· dark → color.stone.dark.100
  • disabled
    text
    → color.stone.light.500· dark → color.stone.dark.500
    surface
    → color.stone.light.100· dark → color.stone.dark.100
    border
    → color.stone.light.200· dark → color.stone.dark.200

Question 5

Where does color carry meaning first?

  • Status in tables
  • Links and actions (chosen)
  • Brand moments

Why Content first picks it: Color marks links inside the text.

becauseR2

  • button · 13 keys
  • input · 8 keys
  • control · 3 keys
  • badge · 10 keys
  • card · 2 keys
  • table · 3 keys
  • tabs · 3 keys
  • overlay · 4 keys

When to use

  • A selected row or itemUse: color.surface.selected. Not: Bold text only. A tint shows the choice clearly on warm paper.
  • An error messageUse: color.status.danger and a plain sentence. Not: Color alone. The sentence says what to fix; color only draws the eye.
  • A linkUse: color.text.link, underlined. Not: Color without underline. Readers expect links to be underlined inside text.
  • A statusUse: Badge pill with a word. Not: An icon alone. Status is rare; a word is clear.
  • The action that completes the taskUse: Button primary, one per section. Not: Two primaries side by side. One clear action per section.
  • An alternative or cancelUse: Button ghost as a text link. Not: A second boxed button. A link feels lighter and does not compete.
  • Delete or removeUse: Button secondary with the full verb, then confirm. Not: Button primary. Naming the verb and confirming prevents a mistake.

All color tokens

41 tokens · each decision and the primitive it points to

  • color.stone.light · 8color.stone.light.50#FFFDF8color.stone.light.0#FFFFFFcolor.stone.light.100#F6F2EAcolor.stone.light.900#1F1B16color.stone.light.700#4A4339color.stone.light.600#61594Dcolor.stone.light.200#E4DDD0color.stone.light.500#7A7062
  • color.navy.light · 3color.navy.light.100#E3EAF3color.navy.light.700#162C49color.navy.light.600#1E3A5F
  • color.black.light · 1color.black.light.scrim#0000008C
  • color.blue.light · 3color.blue.light.700#083C93color.blue.light.100#E1ECFFcolor.blue.light.600#0B4FC0
  • color.green.light · 2color.green.light.700#1F7A3Acolor.green.light.100#E3F4EA
  • color.amber.light · 2color.amber.light.700#8A5600color.amber.light.100#FFF3D6
  • color.red.light · 2color.red.light.700#C42B2Bcolor.red.light.100#FDE7E7
  • Decisions · 41color.surface.canvas{color.stone.light.50}color.surface.default{color.stone.light.0}color.surface.raised{color.stone.light.0}color.surface.sunken{color.stone.light.100}color.surface.selected{color.navy.light.100}color.surface.inverse{color.stone.light.900}color.surface.scrim{color.black.light.scrim}color.text.primary{color.stone.light.900}color.text.secondary{color.stone.light.700}color.text.muted{color.stone.light.600}color.text.inverse{color.stone.light.0}color.text.on-action{color.stone.light.0}color.text.link{color.navy.light.700}color.border.default{color.stone.light.200}color.border.strong{color.stone.light.500}color.border.focus{color.navy.light.600}color.action.primary.@{color.navy.light.600}color.action.primary.hover{color.navy.light.700}color.action.secondary.@{color.stone.light.0}color.action.secondary.hover{color.stone.light.100}color.status.info.@{color.blue.light.700}color.status.info.subtle{color.blue.light.100}color.status.success.@{color.green.light.700}color.status.success.subtle{color.green.light.100}color.status.warning.@{color.amber.light.700}color.status.warning.subtle{color.amber.light.100}color.status.danger.@{color.red.light.700}color.status.danger.subtle{color.red.light.100}color.category.1.@{color.navy.light.600}color.category.1.subtle{color.navy.light.100}color.category.2.@{color.blue.light.600}color.category.2.subtle{color.blue.light.100}color.category.3.@{color.green.light.700}color.category.3.subtle{color.green.light.100}color.category.4.@{color.amber.light.700}color.category.4.subtle{color.amber.light.100}color.category.5.@{color.stone.light.500}color.category.5.subtle{color.stone.light.100}color.disabled.text{color.stone.light.500}color.disabled.surface{color.stone.light.100}color.disabled.border{color.stone.light.200}

Decisions reference primitives, so changing one primitive updates every decision and component that uses it.

Color in Content first: balanced. A calm, balanced palette. Color marks links inside the text.