Open DS

Naming

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

View all 71 naming tokens ↓

The reasons this scheme answers from

  • R1Team and deliveryA small team, every month

Question 1

What gets a name?

  • Tokens
  • Tokens and component keys (chosen)

Why Dense data picks it: Components get their own keys.

becauseR1

button{color.action.primary.@} · {color.action.primary.hover} · {color.text.on-action} · {color.action.secondary.@} · {color.action.secondary.hover} · {color.text.primary} · {color.border.strong} · {color.surface.sunken} · {color.text.link} · {size.control.default} · {space.inset.control-x} · {radius.control} · {type.label.font-size} · {type.label.font-weight} · {color.border.focus} · {size.icon} · {color.disabled.surface} · {color.disabled.text} · {color.disabled.border}
input{color.surface.default} · {color.border.strong} · {color.border.focus} · {color.text.primary} · {color.text.muted} · {size.control.default} · {space.inset.control-x} · {radius.control} · {type.body.font-size} · {color.disabled.surface} · {color.disabled.border} · {color.disabled.text}
control{color.action.primary.@} · {color.border.strong} · {color.surface.default} · {radius.badge}
badge{radius.badge} · {space.gap.tight} · {type.caption.font-size} · {color.surface.sunken} · {color.text.secondary} · {color.status.success.subtle} · {color.status.success.@} · {color.status.warning.subtle} · {color.status.warning.@} · {color.status.danger.subtle} · {color.status.danger.@} · {color.status.info.subtle} · {color.status.info.@}
card{color.surface.default} · {color.border.default} · {radius.container} · {space.inset.container} · {elevation.card}
table{color.surface.sunken} · {size.row} · {space.inset.cell-x} · {color.border.default} · {color.surface.selected} · {type.data.font-size}
tabs{color.action.primary.@} · {color.text.secondary} · {color.text.primary}
overlay{color.surface.raised} · {radius.container} · {elevation.overlay} · {color.surface.scrim} · {size.control.default}
tooltip{color.surface.inverse} · {color.text.inverse}
transition{motion.duration.feedback} · {motion.easing.standard}

Question 2

How many token tiers?

  • Two
  • Three (chosen)

Why Dense data picks it: Primitives, semantics and component keys.

becauseR1

action primary2
color text6
action secondary2
color border3
color surface6
size control1
space inset3
radius3
type label2
size2
color disabled3
type body1
space gap1
type caption1
status success2
status warning2
status danger2
status info2
elevation2
type data1
motion duration1
motion easing1

Question 3

How are decisions named?

  • By role (chosen)
  • By component

Why Dense data picks it: Role names survive a redesign.

becauseR1

  • By role
  • from color.action.primary
  • from color.text
  • from color.action.secondary
  • from color.border
  • from color.surface
  • from size.control
  • from space.inset
  • from radius
  • from type.label
  • from size
  • from color.disabled
  • from type.body
  • from space.gap
  • from type.caption
  • from color.status.success
  • from color.status.warning
  • from color.status.danger
  • from color.status.info
  • from elevation
  • from type.data
  • from motion.duration
  • from motion.easing

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

Question 4

How are names written?

  • Lowercase words in paths (chosen)
  • camelCase

Why Dense data picks it: Lowercase paths read the same in CSS, JSON and Figma.

becauseR1

  • button
    primary.background.@
    → color.action.primary.@
    primary.background.hover
    → color.action.primary.hover
    primary.label
    → color.text.on-action
    secondary.background.@
    → color.action.secondary.@
    secondary.background.hover
    → color.action.secondary.hover
    secondary.label
    → color.text.primary
    secondary.border
    → color.border.strong
    ghost.background-hover
    → color.surface.sunken
    ghost.label
    → color.text.link
    height
    → size.control.default
    padding-x
    → space.inset.control-x
    radius
    → radius.control
    font-size
    → type.label.font-size
    font-weight
    → type.label.font-weight
    focus-ring
    → color.border.focus
    icon-size
    → size.icon
    disabled.background
    → color.disabled.surface
    disabled.label
    → color.disabled.text
    disabled.border
    → color.disabled.border
  • input
    background
    → color.surface.default
    border.@
    → color.border.strong
    border.focus
    → color.border.focus
    text
    → color.text.primary
    placeholder
    → color.text.muted
    height
    → size.control.default
    padding-x
    → space.inset.control-x
    radius
    → radius.control
    font-size
    → type.body.font-size
    disabled.background
    → color.disabled.surface
    disabled.border
    → color.disabled.border
    disabled.text
    → color.disabled.text
  • control
    checked
    → color.action.primary.@
    track
    → color.border.strong
    thumb
    → color.surface.default
    radius
    → radius.badge
  • badge
    radius
    → radius.badge
    padding-x
    → space.gap.tight
    font-size
    → type.caption.font-size
    neutral.background
    → color.surface.sunken
    neutral.label
    → color.text.secondary
    success.background
    → color.status.success.subtle
    success.label
    → color.status.success.@
    warning.background
    → color.status.warning.subtle
    warning.label
    → color.status.warning.@
    danger.background
    → color.status.danger.subtle
    danger.label
    → color.status.danger.@
    info.background
    → color.status.info.subtle
    info.label
    → color.status.info.@
  • card
    background
    → color.surface.default
    border
    → color.border.default
    radius
    → radius.container
    padding
    → space.inset.container
    shadow
    → elevation.card
  • table
    header-background
    → color.surface.sunken
    row-height
    → size.row
    cell-padding-x
    → space.inset.cell-x
    row-border
    → color.border.default
    row-selected
    → color.surface.selected
    font-size
    → type.data.font-size
  • tabs
    indicator
    → color.action.primary.@
    label.@
    → color.text.secondary
    label.active
    → color.text.primary
  • overlay
    background
    → color.surface.raised
    radius
    → radius.container
    shadow
    → elevation.overlay
    scrim
    → color.surface.scrim
    item-height
    → size.control.default
  • tooltip
    background
    → color.surface.inverse
    label
    → color.text.inverse
  • transition
    duration
    → motion.duration.feedback
    easing
    → motion.easing.standard

Question 5

What do components read?

  • Component keys (chosen)
  • Semantic tokens

Why Dense data picks it: A component API keeps changes local.

becauseR1

  • button
  • input
  • control
  • badge
  • card
  • table
  • tabs
  • overlay
  • transition

When to use

  • A value with no tokenUse: The closest semantic token, then ask for a new one. Not: A raw value in the component. Raw values break dark mode and the next redesign.

All naming tokens

71 tokens · each decision and the primitive it points to

  • color.action.primary · 2color.action.primary.@#4B3FD9color.action.primary.hover#3B31B0
  • color.text · 6color.text.on-action#FFFFFFcolor.text.primary#161B23color.text.link#3B31B0color.text.muted#535D6Dcolor.text.secondary#3D4655color.text.inverse#FFFFFF
  • color.action.secondary · 2color.action.secondary.@#FFFFFFcolor.action.secondary.hover#EEF1F5
  • color.border · 3color.border.strong#6B7585color.border.focus#4B3FD9color.border.default#DDE2EA
  • color.surface · 6color.surface.sunken#EEF1F5color.surface.default#FFFFFFcolor.surface.selected#EEEDFEcolor.surface.raised#FFFFFFcolor.surface.scrim#0000008Ccolor.surface.inverse#161B23
  • size.control · 1size.control.default2rem · 32px
  • space.inset · 3space.inset.control-x0.75rem · 12pxspace.inset.container1rem · 16pxspace.inset.cell-x0.75rem · 12px
  • radius · 3radius.control0.125rem · 2pxradius.badge0rem · 0pxradius.container0.25rem · 4px
  • type.label · 2type.label.font-size0.75rem · 12pxtype.label.font-weight500
  • size · 3size.control.default2rem · 32pxsize.icon1rem · 16pxsize.row2rem · 32px
  • color.disabled · 3color.disabled.surface#EEF1F5color.disabled.text#6B7585color.disabled.border#DDE2EA
  • type.body · 1type.body.font-size0.875rem · 14px
  • space.gap · 1space.gap.tight0.25rem · 4px
  • type.caption · 1type.caption.font-size0.75rem · 12px
  • color.status.success · 2color.status.success.subtle#E3F4EAcolor.status.success.@#1F7A3A
  • color.status.warning · 2color.status.warning.subtle#FFF3D6color.status.warning.@#8A5600
  • color.status.danger · 2color.status.danger.subtle#FDE7E7color.status.danger.@#C42B2B
  • color.status.info · 2color.status.info.subtle#E1ECFFcolor.status.info.@#083C93
  • elevation · 2elevation.card0px 0px 0px 0px #00000000elevation.overlay0px 8px 24px 0px #0D111729
  • type.data · 1type.data.font-size0.8125rem · 13px
  • motion.duration · 1motion.duration.feedback120ms
  • motion.easing · 1motion.easing.standardcubic-bezier(0.2, 0, 0, 1)
  • Decisions · 71component.button.primary.background.@{color.action.primary.@}component.button.primary.background.hover{color.action.primary.hover}component.button.primary.label{color.text.on-action}component.button.secondary.background.@{color.action.secondary.@}component.button.secondary.background.hover{color.action.secondary.hover}component.button.secondary.label{color.text.primary}component.button.secondary.border{color.border.strong}component.button.ghost.background-hover{color.surface.sunken}component.button.ghost.label{color.text.link}component.button.height{size.control.default}component.button.padding-x{space.inset.control-x}component.button.radius{radius.control}component.button.font-size{type.label.font-size}component.button.font-weight{type.label.font-weight}component.button.focus-ring{color.border.focus}component.button.icon-size{size.icon}component.button.disabled.background{color.disabled.surface}component.button.disabled.label{color.disabled.text}component.button.disabled.border{color.disabled.border}component.input.background{color.surface.default}component.input.border.@{color.border.strong}component.input.border.focus{color.border.focus}component.input.text{color.text.primary}component.input.placeholder{color.text.muted}component.input.height{size.control.default}component.input.padding-x{space.inset.control-x}component.input.radius{radius.control}component.input.font-size{type.body.font-size}component.input.disabled.background{color.disabled.surface}component.input.disabled.border{color.disabled.border}component.input.disabled.text{color.disabled.text}component.control.checked{color.action.primary.@}component.control.track{color.border.strong}component.control.thumb{color.surface.default}component.control.radius{radius.badge}component.badge.radius{radius.badge}component.badge.padding-x{space.gap.tight}component.badge.font-size{type.caption.font-size}component.badge.neutral.background{color.surface.sunken}component.badge.neutral.label{color.text.secondary}component.badge.success.background{color.status.success.subtle}component.badge.success.label{color.status.success.@}component.badge.warning.background{color.status.warning.subtle}component.badge.warning.label{color.status.warning.@}component.badge.danger.background{color.status.danger.subtle}component.badge.danger.label{color.status.danger.@}component.badge.info.background{color.status.info.subtle}component.badge.info.label{color.status.info.@}component.card.background{color.surface.default}component.card.border{color.border.default}component.card.radius{radius.container}component.card.padding{space.inset.container}component.card.shadow{elevation.card}component.table.header-background{color.surface.sunken}component.table.row-height{size.row}component.table.cell-padding-x{space.inset.cell-x}component.table.row-border{color.border.default}component.table.row-selected{color.surface.selected}component.table.font-size{type.data.font-size}component.tabs.indicator{color.action.primary.@}component.tabs.label.@{color.text.secondary}component.tabs.label.active{color.text.primary}component.overlay.background{color.surface.raised}component.overlay.radius{radius.container}component.overlay.shadow{elevation.overlay}component.overlay.scrim{color.surface.scrim}component.overlay.item-height{size.control.default}component.tooltip.background{color.surface.inverse}component.tooltip.label{color.text.inverse}component.transition.duration{motion.duration.feedback}component.transition.easing{motion.easing.standard}

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

Naming in Dense data: lowercase words in paths. Lowercase paths read the same in CSS, JSON and Figma. A component API keeps changes local.