Open DS

Theming

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

View all 53 theming tokens ↓

The reasons this scheme answers from

  • R1Business and productRuns daily operations, one
  • R2Use scenariosAt a desk, all day
  • R3Human factorsPeople keep their place, they learn it and recognise it

Question 1

What can a theme change?

  • Mode only (chosen)
  • Mode and brand
  • Mode and contrast

Why Dense data picks it: One brand, so only the mode changes.

becauseR1

radius{radius.2} · {radius.0} · {radius.4}
type{font.family.ibm-plex-sans} · {font.family.ibm-plex-sans} · {font.family.ibm-plex-sans} · {font.family.ibm-plex-sans} · {font.family.ibm-plex-sans} · {font.family.ibm-plex-sans} · {font.family.ibm-plex-mono}
color{color.slate.light.50} · {color.slate.light.0} · {color.slate.light.0} · {color.slate.light.100} · {color.violet.light.100} · {color.slate.light.900} · {color.black.light.scrim} · {color.slate.light.900} · {color.slate.light.700} · {color.slate.light.600} · {color.slate.light.0} · {color.slate.light.0} · {color.violet.light.700} · {color.slate.light.200} · {color.slate.light.500} · {color.violet.light.600} · {color.violet.light.600} · {color.violet.light.700} · {color.slate.light.0} · {color.slate.light.100} · {color.blue.light.700} · {color.blue.light.100} · {color.green.light.700} · {color.green.light.100} · {color.amber.light.700} · {color.amber.light.100} · {color.red.light.700} · {color.red.light.100} · {color.violet.light.600} · {color.violet.light.100} · {color.blue.light.600} · {color.blue.light.100} · {color.green.light.700} · {color.green.light.100} · {color.amber.light.700} · {color.amber.light.100} · {color.slate.light.500} · {color.slate.light.100} · {color.slate.light.500} · {color.slate.light.100} · {color.slate.light.200}
elevation{shadow.none} · {shadow.overlay}

Question 2

How many themes ship?

  • Two (chosen)
  • Several

Why Dense data picks it: Light and dark.

becauseQ4

radius3
font family2
slate light8
violet light3
black light1
blue light3
green light2
amber light2
red light2
shadow2

Question 3

How are brands handled?

  • One brand (chosen)
  • Brands as modes

Why Dense data picks it: One product, one brand.

becauseR1

  • One brand
  • from radius
  • from font.family
  • from color.slate.light
  • from color.violet.light
  • from color.black.light
  • from color.blue.light
  • from color.green.light
  • from color.amber.light
  • from color.red.light
  • from shadow

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

Question 4

Which modes ship?

  • Light and dark (chosen)
  • Light, dark and high contrast

Why Dense data picks it: Light first, always; dark ships as standard for night shifts.

becauseR2

  • radius
    control
    → radius.2
    badge
    → radius.0
    container
    → radius.4
  • type
    display.font-family
    → font.family.ibm-plex-sans
    title.font-family
    → font.family.ibm-plex-sans
    heading.font-family
    → font.family.ibm-plex-sans
    body.font-family
    → font.family.ibm-plex-sans
    label.font-family
    → font.family.ibm-plex-sans
    caption.font-family
    → font.family.ibm-plex-sans
    data.font-family
    → font.family.ibm-plex-mono
  • color
    surface.canvas
    → color.slate.light.50
    surface.default
    → color.slate.light.0
    surface.raised
    → color.slate.light.0
    surface.sunken
    → color.slate.light.100
    surface.selected
    → color.violet.light.100
    surface.inverse
    → color.slate.light.900
    surface.scrim
    → color.black.light.scrim
    text.primary
    → color.slate.light.900
    text.secondary
    → color.slate.light.700
    text.muted
    → color.slate.light.600
    text.inverse
    → color.slate.light.0
    text.on-action
    → color.slate.light.0
    text.link
    → color.violet.light.700
    border.default
    → color.slate.light.200
    border.strong
    → color.slate.light.500
    border.focus
    → color.violet.light.600
    action.primary.@
    → color.violet.light.600
    action.primary.hover
    → color.violet.light.700
    action.secondary.@
    → color.slate.light.0
    action.secondary.hover
    → color.slate.light.100
    status.info.@
    → color.blue.light.700
    status.info.subtle
    → color.blue.light.100
    status.success.@
    → color.green.light.700
    status.success.subtle
    → color.green.light.100
    status.warning.@
    → color.amber.light.700
    status.warning.subtle
    → color.amber.light.100
    status.danger.@
    → color.red.light.700
    status.danger.subtle
    → color.red.light.100
    category.1.@
    → color.violet.light.600
    category.1.subtle
    → color.violet.light.100
    category.2.@
    → color.blue.light.600
    category.2.subtle
    → color.blue.light.100
    category.3.@
    → color.green.light.700
    category.3.subtle
    → color.green.light.100
    category.4.@
    → color.amber.light.700
    category.4.subtle
    → color.amber.light.100
    category.5.@
    → color.slate.light.500
    category.5.subtle
    → color.slate.light.100
    disabled.text
    → color.slate.light.500
    disabled.surface
    → color.slate.light.100
    disabled.border
    → color.slate.light.200
  • elevation
    card
    → shadow.none
    overlay
    → shadow.overlay

Question 5

What changes when the theme changes?

  • Colors only (chosen)
  • Colors, type and shape

Why Dense data picks it: A mode switch changes colors only, so layout never moves.

becauseR3

  • button
  • card
  • overlay

When to use

  • Someone switches to darkUse: The dark semantic mode. Not: A second palette in components. Only semantic colors change, so layout never moves.

All theming tokens

53 tokens · each decision and the primitive it points to

  • radius · 3radius.20.125rem · 2pxradius.00rem · 0pxradius.40.25rem · 4px
  • font.family · 2font.family.ibm-plex-sans"IBM Plex Sans", system-ui, sans-seriffont.family.ibm-plex-mono"IBM Plex Mono", ui-monospace, monospace
  • color.slate.light · 8color.slate.light.50#F7F8FAcolor.slate.light.0#FFFFFFcolor.slate.light.100#EEF1F5color.slate.light.900#161B23color.slate.light.700#3D4655color.slate.light.600#535D6Dcolor.slate.light.200#DDE2EAcolor.slate.light.500#6B7585
  • color.violet.light · 3color.violet.light.100#EEEDFEcolor.violet.light.700#3B31B0color.violet.light.600#4B3FD9
  • 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
  • shadow · 2shadow.none0px 0px 0px 0px #00000000shadow.overlay0px 8px 24px 0px #0D111729
  • Decisions · 53theme.radius.control{radius.2}theme.radius.badge{radius.0}theme.radius.container{radius.4}theme.type.display.font-family{font.family.ibm-plex-sans}theme.type.title.font-family{font.family.ibm-plex-sans}theme.type.heading.font-family{font.family.ibm-plex-sans}theme.type.body.font-family{font.family.ibm-plex-sans}theme.type.label.font-family{font.family.ibm-plex-sans}theme.type.caption.font-family{font.family.ibm-plex-sans}theme.type.data.font-family{font.family.ibm-plex-mono}theme.color.surface.canvas{color.slate.light.50}theme.color.surface.default{color.slate.light.0}theme.color.surface.raised{color.slate.light.0}theme.color.surface.sunken{color.slate.light.100}theme.color.surface.selected{color.violet.light.100}theme.color.surface.inverse{color.slate.light.900}theme.color.surface.scrim{color.black.light.scrim}theme.color.text.primary{color.slate.light.900}theme.color.text.secondary{color.slate.light.700}theme.color.text.muted{color.slate.light.600}theme.color.text.inverse{color.slate.light.0}theme.color.text.on-action{color.slate.light.0}theme.color.text.link{color.violet.light.700}theme.color.border.default{color.slate.light.200}theme.color.border.strong{color.slate.light.500}theme.color.border.focus{color.violet.light.600}theme.color.action.primary.@{color.violet.light.600}theme.color.action.primary.hover{color.violet.light.700}theme.color.action.secondary.@{color.slate.light.0}theme.color.action.secondary.hover{color.slate.light.100}theme.color.status.info.@{color.blue.light.700}theme.color.status.info.subtle{color.blue.light.100}theme.color.status.success.@{color.green.light.700}theme.color.status.success.subtle{color.green.light.100}theme.color.status.warning.@{color.amber.light.700}theme.color.status.warning.subtle{color.amber.light.100}theme.color.status.danger.@{color.red.light.700}theme.color.status.danger.subtle{color.red.light.100}theme.color.category.1.@{color.violet.light.600}theme.color.category.1.subtle{color.violet.light.100}theme.color.category.2.@{color.blue.light.600}theme.color.category.2.subtle{color.blue.light.100}theme.color.category.3.@{color.green.light.700}theme.color.category.3.subtle{color.green.light.100}theme.color.category.4.@{color.amber.light.700}theme.color.category.4.subtle{color.amber.light.100}theme.color.category.5.@{color.slate.light.500}theme.color.category.5.subtle{color.slate.light.100}theme.color.disabled.text{color.slate.light.500}theme.color.disabled.surface{color.slate.light.100}theme.color.disabled.border{color.slate.light.200}theme.elevation.card{shadow.none}theme.elevation.overlay{shadow.overlay}

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

Theming in Dense data: light and dark. Light first, always; dark ships as standard for night shifts. A mode switch changes colors only, so layout never moves.