Why color names matter in design systems
A color name is a contract between designers and developers — and between the present system and its future maintainers. When a designer says 'use Ocean Blue' and a developer writes '--color-blue-600', they are either describing the same thing or a future support ticket. Well-named colors reduce ambiguity, prevent inconsistency, and make design systems refactorable. A system where every color reference is by hex value is a system that cannot safely evolve.
Primitive vs semantic naming tiers
The two-tier model separates what a color is (primitive) from what it does (semantic). Primitives name the color itself: blue-100, blue-300, blue-500, blue-700. Semantics name the role: interactive-default, interactive-hover, text-secondary, surface-elevated. A button's background uses the semantic token '--interactive-default'; the token resolves to blue-500 in light mode and blue-300 in dark mode. The component never needs to know — and when you want to change the brand blue to teal, you change one primitive assignment, and every semantic reference updates automatically.
Poetic names and emotional alignment
Poetic color names — the kind used in paint systems (Farrow & Ball's 'Elephant's Breath'), fashion, and fine art — serve a different purpose: emotional alignment. When a brand calls their primary blue 'Horizon', every decision made about that color is filtered through what Horizon communicates — open, optimistic, slightly cool, expansive. Naming a color changes how teams use it. In large design organizations, shared poetic vocabulary helps maintain visual consistency without rigid specification enforcement, because teams self-select toward the named color's character.
CSS custom property naming conventions
For CSS design tokens, naming conventions should encode hierarchy and role: '--color-{primitive}-{step}' for raw values, '--color-{semantic-role}' for function. Common semantic categories: text (primary, secondary, disabled, inverse), surface (default, elevated, overlay, inset), border (default, strong, focus), and interactive (default, hover, active, disabled). Always use kebab-case and avoid encoding specific hex values in token names — '--color-blue-500' is fine; '--color-1a2b3c' is not, because it breaks as soon as the value changes.
Naming pitfalls to avoid
Three common color naming mistakes: using ordinal numbers without context ('color1', 'color2' — meaningless after six months), encoding current hex values in token names ('blue-1a72cf' — breaks on every palette update), and mixing semantic and primitive tiers without clear separation (calling a button background 'primary-blue' mixes intent and description). The cleanest systems have a strict rule: primitives are in one file/section and are never referenced directly in component code — everything goes through semantics.