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
Question 2
How many themes ship?
- Two (chosen)
- Several
Why Dense data picks it: Light and dark.
becauseQ4
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 · 3
radius.20.125rem · 2pxradius.00rem · 0pxradius.40.25rem · 4px - font.family · 2
font.family.ibm-plex-sans"IBM Plex Sans", system-ui, sans-seriffont.family.ibm-plex-mono"IBM Plex Mono", ui-monospace, monospace - color.slate.light · 8
color.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 · 3
color.violet.light.100#EEEDFEcolor.violet.light.700#3B31B0color.violet.light.600#4B3FD9 - color.black.light · 1
color.black.light.scrim#0000008C - color.blue.light · 3
color.blue.light.700#083C93color.blue.light.100#E1ECFFcolor.blue.light.600#0B4FC0 - color.green.light · 2
color.green.light.700#1F7A3Acolor.green.light.100#E3F4EA - color.amber.light · 2
color.amber.light.700#8A5600color.amber.light.100#FFF3D6 - color.red.light · 2
color.red.light.700#C42B2Bcolor.red.light.100#FDE7E7 - shadow · 2
shadow.none0px 0px 0px 0px #00000000shadow.overlay0px 8px 24px 0px #0D111729 - Decisions · 53
theme.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.