Nommer les tokens de couleur : brand-600 ou blue-600
Deux fichiers de tokens affrontent le même changement de marque. Dans le
premier, la palette était nommée par teinte — blue-600 référencé dans des
centaines de fichiers. La marque vire au sarcelle, et chaque option est
mauvaise : garder le nom, et blue-600 stocke maintenant une couleur
sarcelle, mentant à chaque futur lecteur ; le renommer, et il faut toucher
chaque référence dans la base de code. Dans le second fichier, la même
couleur était nommée brand-600. Le changement de marque tient en une seule
modification — la valeur change, le nom continue de dire la vérité, rien en
aval ne bouge.
Le nommage des tokens de couleur fonctionne en couches — jusqu’à trois. La
couche primitive nomme la place d’une couleur dans la palette (brand-600) ;
la couche sémantique nomme les rôles de l’interface (background,
text-primary, accent) et pointe vers les primitives ; la couche de
composant, optionnelle (button-bg), n’existe que là où un composant a
réellement besoin de se détacher de la sémantique. Au niveau primitif,
brand-600 l’emporte sur blue-600 pour une palette mono-marque parce
qu’il nomme le rôle que joue une couleur, pas la teinte qu’elle a par hasard
— même si les noms de teinte restent un choix défendable pour les palettes
brutes multi-teintes. Ce que le nombre lui-même signifie — la position
d’échelle derrière le 600 — est traité dans notre
color scales guide ; cet article porte sur les mots
placés devant.
Faut-il nommer les primitives brand-600 ou blue-600 ?
Les deux positions méritent d’être défendues honnêtement.
L’argument pour brand-600 : le fait stable d’une primitive, c’est sa
position dans la palette de ce produit-ci, pas sa longueur d’onde. La
palette a une teinte principale, un ensemble de neutres, peut-être une
secondaire — ce sont des rôles, et ils survivent à chaque événement de la
vie de la palette. La teinte est la propriété volatile : les changements de
marque la modifient, et le scénario d’ouverture montre ce que le nom
blue-600 coûte quand cela arrive. Personne qui consomme une palette
mono-marque n’a jamais eu besoin de savoir que la couleur de marque est
bleue ; il avait besoin de savoir que c’est la couleur de marque. Les
groupes de palette de Scale Composer sont nommés exactement sur ce principe —
Brand, Secondaries, Neutral, Functional — les rôles d’abord, les teintes
nulle part.
L’argument pour blue-600 : dans un système multi-teintes, il se peut
qu’il n’y ait aucun rôle à nommer. Une palette brute qui livre vingt teintes
comme matériau polyvalent — la position de Tailwind — n’a pas de « brand »
parmi elles ; la teinte est le seul nom honnête qu’une telle palette peut
offrir, et blue-600 y est parfaitement juste. La même logique vaut pour
les jeux de couleurs de graphiques catégoriels, où six teintes sont des
pairs sans hiérarchie à encoder.
La règle empirique en découle proprement : si la palette appartient à une
seule marque, nommez les primitives par rôle ; si c’est une boîte de crayons
au service de plusieurs maîtres, nommez-les par teinte. La plupart des design
systems de produit sont du premier type et héritent des noms du second en
copiant les conventions d’un framework — c’est ainsi que blue-600 finit par
mentir après un changement de marque que personne n’avait prévu.
Qu’apporte la couche sémantique ?
De l’indirection porteuse de sens. Les tokens sémantiques nomment des rôles
— background, surface, border, text-primary, text-secondary,
accent, les couleurs d’état interactif — et chacun pointe vers une
primitive. Les composants consomment des tokens sémantiques et ne touchent
jamais directement aux primitives.
Le gain, c’est que le sens et la valeur deviennent modifiables
indépendamment. Un composant écrit contre text-primary fonctionne sur
n’importe quel thème, parce que le nom promet un rôle, pas une valeur ; un
composant écrit contre brand-900 a codé en dur une hypothèse sur quel
palier remplit ce rôle aujourd’hui. C’est aussi dans cette couche que
l’accessibilité vit naturellement : un rôle comme « texte principal sur
cette surface » porte une exigence de contraste, donc le token qui nomme le
rôle est le bon endroit pour l’imposer. Scale Composer dérive de cette façon
environ dix-sept rôles sémantiques par surface — chaque rôle pointant vers un
scale step, vérifié contre les
planchers WCAG (4,5:1 pour le texte courant, 7:1 pour le niveau plus strict)
avec l’APCA affichée à côté. Le système de tokens de Material Design
documente la même architecture en couches — reference, system et component
tokens dans son
design tokens overview
— sous d’autres noms de couches.
Voyez les couches sur une vraie palette dans Scale Composer — les rampes primitives groupées par rôle, les rôles sémantiques d’une surface pointant vers elles, et le panneau d’export emportant les deux couches en DTCG, CSS, Tailwind ou Figma Variables.

Quand une couche de composant mérite-t-elle sa place ?
Rarement — et c’est la conception de cette couche, pas sa faiblesse. Un token
de composant comme button-bg est justifié quand un composant doit se
détacher de la couche sémantique : le site marketing repointe accent vers
une teinte secondaire, mais le bouton principal doit rester sur la couleur de
marque — alors button-bg cesse de suivre accent et s’épingle à la
primitive de marque. C’est un vrai découplage, et le token l’enregistre.
Sans une telle divergence, un token de composant est de l’indirection sans
sens : button-bg → accent → brand-600, trois noms pour une seule valeur
qui ne varie jamais indépendamment. Multiplié à l’échelle d’une bibliothèque
de composants, cela produit les jeux de tokens que personne n’arrive à
parcourir. Un réglage par défaut raisonnable : introduire le token de
composant quand l’exception apparaît, pas avant.
Qu’est-ce que les couches vous apportent quand les choses changent ?
Trois scénarios, avec la couleur de départ bleue #2563eb —
oklch(0.546 0.215 262.9) — tenant lieu de marque.
Changement de marque. La palette se re-dérive d’une couleur de départ
sarcelle. Les primitives gardent leurs noms et échangent leurs valeurs —
brand-600 ne stocke plus ≈#3E65B5, mais c’est toujours
le 600 de la rampe de marque. La
couche sémantique, qui pointe vers des noms plutôt que des valeurs, ne change
pas du tout. Les composants ne remarquent rien.
Mode sombre.
Les noms sémantiques gardent leur sens pendant que leurs cibles bougent :
accent pointe vers brand-600 (≈#3E65B5) sur le thème clair et vers un
palier plus clair comme brand-300 (≈#71AEFF) sur le thème sombre, où un
fond sombre exige un accent plus clair pour le contraste. Les valeurs
proviennent même de rampes différentes — une palette sombre dérivée est
générée avec sa propre courbe de luminosité et un renfort de chroma d’environ
20 % — et pourtant un composant dit toujours simplement accent.
Une primitive, plusieurs rôles. Le même brand-600 peut servir de texte
accent sur une surface et de remplissage de bouton au repos sur une autre.
Une seule valeur stockée, plusieurs sens — et les sens vivent dans la couche
sémantique, ce qui est toute la raison de son existence. Aplatissez les
couches, et chacun de ces changements devient un rechercher-remplacer à
travers les composants.
Le nommage est aussi la partie d’un système de tokens qui survit à l’outil qui l’a créé : les noms choisis ici sont ce que chaque export emporte dans le code et les fichiers de design, avec le hex à côté de l’OKLCH. Et le chemin de migration fonctionne dans les deux sens. Importez votre fichier de tokens existant et renommez une couche — chargez un fichier DTCG, renommez les primitives nommées par teinte en noms de rôle, et ré-exportez ; l’aller-retour préserve les sections que vous n’avez pas touchées, si bien qu’un nettoyage de nommage coûte exactement les tokens qu’il renomme.