Designing a semantic token vocabulary
A minimal semantic color token vocabulary for a product design system: (1) Surface tokens — background colors for page, card, elevated, and overlay surfaces (--surface-page, --surface-raised, --surface-overlay). (2) Text tokens — foreground colors for primary text, secondary text, disabled text, inverse text, and link text. (3) Border tokens — border colors for default, hover, focus, and error states. (4) Action tokens — colors for interactive elements across states: default, hover, pressed, disabled. Covers background, foreground, and border. (5) Status tokens — semantic colors for error, warning, success, and info states. Covers background tint, text, and border for each status. (6) Brand tokens — colors for any brand-specific uses that do not fit action or status roles: highlight accents, marketing callouts, illustration palette. This vocabulary of 25-40 semantic tokens is sufficient for most product interfaces; more granularity is needed only when building highly customizable component libraries.
Naming conventions that scale across dark and light mode
Naming tokens in a multi-theme system introduces a specific challenge: semantic names should not encode the current value's visual appearance, because the value changes by theme. A token named --text-dark-primary breaks in dark mode (the primary text is now light, not dark). The correct approach: name tokens by semantic role and let the theme override the value. --text-primary is the primary text color in every theme; its value is near-black in light mode and near-white in dark mode. The naming pattern should be noun (what the token applies to) + modifier (which variant or state). Avoid encoding visual properties (dark, light, warm, cool) in semantic token names at the tier-2 level. The exception: tier-1 global tokens should and must encode visual properties, since their purpose is to describe the full value inventory precisely.
Managing token evolution over time
Design system tokens evolve: brands rebrand, products enter dark mode, components get added. A naming convention that does not anticipate evolution creates migration problems. Best practices for sustainable token naming: (1) Use a namespace prefix for all system tokens (--ds-, --brand-, or the product name) to prevent collision with third-party CSS. (2) Avoid version numbers in token names (--color-v2-action-primary) — versioning belongs in documentation, not names. (3) Keep a token changelog as part of design system release notes, documenting added, renamed, deprecated, and removed tokens. (4) Use a deprecation pattern: before removing a token, add the old name as an alias pointing to the new name for at least one major version, with a documentation notice. (5) Consider an automated linting pass that warns when deprecated tokens are used in component code. Each of these practices reduces the migration cost when the system necessarily changes.
Translating color tokens into CSS, Figma, and JSON
Design tokens exist simultaneously in multiple environments: CSS custom properties for web, Figma variables for design tools, and JSON for toolchain portability. The naming translation across formats is non-trivial. CSS custom properties use kebab-case with double-dash prefix: --color-action-primary. Figma variables use a path/group structure: Color/Action/Primary (the slash is the Figma group separator). JSON uses dot-notation or nested objects: color.action.primary. The W3C Design Tokens format specifies a JSON schema that can be compiled to all three formats by tools like Style Dictionary and Theo. If you are building a token system that needs to work across design and development environments, adopting the W3C format early — or using a token management tool (Tokens Studio for Figma, Supernova, Specify) that handles the translation — prevents the divergence that happens when designers maintain one set of names and engineers maintain a different set.