# Токены — это роли, а не цвета

> Почему токен, названный ролью, живёт дольше названного значением, что ломается в день смены цвета бренда и где правило заканчивается.

- Page: https://granularity.tech/ru/blog/tokens-are-roles
- Last reviewed: 2026-09-03

Любая дизайн-система приходит к одной развилке, обычно на второй неделе.
Палитра есть. Назвать токен `--blue-500` — или назвать его `--primary`?

Это не вопрос вкуса, и цена неверной ветки платится не в день выбора. Она
платится в день, когда просят тёмную тему, или бренд становится зелёным, или
дизайнеру нужно узнать, какой из одиннадцати серых — тот, что для рамок.

## Ломается не выбор, а переименование

Назовите токен значением — и значение записано дважды: в имени и в объявлении.
В первый день они согласны. Согласие кончается при первой смене значения.

```css
/* Первый день: честно. */
--blue-500: #4f46e5;

/* Четвёртый месяц: бренд теперь зелёный. */
--blue-500: #16a34a;
```

Никто его не переименует. Переименование означает правку каждого места
использования, а места использования — это ровно то, чего не хотелось трогать:
ради этого токен и заводили. И теперь код говорит «синий», а имеет в виду
«зелёный», и каждый новый человек читает имя и ему верит.

У роли такой поломки нет, потому что роль — не утверждение о значении:

```css
--gr-primary: #16a34a;
```

Переименовывать нечего. Токен всё это время говорил «цвет основного действия»,
и цвет основного действия изменился — ровно то, ради чего токены существуют.

## Роли ходят парами, и в этом весь смысл

Сильный довод за роли не в именовании, а в том, что роль позволяет объявить
**отношение**, которого палитра выразить не может.

Цветовой токен сам по себе не говорит, что кладётся поверх него. Пара ролей —
говорит:

```css
--gr-primary: #4f46e5;
--gr-primary-fg: #ffffff;
```

У каждой поверхности есть передний план, и пара — это контракт: *красите этим —
пишете тем*. Контракт можно проверить. Портал проверяет 18 пар токенов в обеих
темах на каждой сборке, и считает их функцией самой библиотеки, а не своей
копией формулы: две реализации одного правила однажды разойдутся, и в день, когда
это случится, никто не заметит.

С `--blue-500` проверять нечего. Есть синий и надежда.

## Три слоя

Плоский список тоже не выживает. Здесь токены — три группы с тремя разными
задачами: 104 токена фундамента и 94 ролевых токена. Звучит много, пока не
видно, зачем слои:

1. **Фундамент.** Сырые шкалы: палитра, отступы, радиусы, кегли. Они **названы
   значениями**, и это правильно: `--gr-slate-500` — факт о цвете, а не решение
   об интерфейсе.
2. **Роли.** Из чего сделан интерфейс: `--gr-bg`, `--gr-fg`, `--gr-primary`,
   `--gr-danger` — и у каждой свой передний план. Роли ссылаются на фундамент.
   Приложение видит только этот слой.
3. **Производные.** Состояния, посчитанные от ролей: hover, active, disabled,
   кольцо фокуса. Считаются формулой, а не глазом, чтобы новый цвет бренда давал
   верный hover без чьего-либо выбора.

Слои и делают правдой «переименовывать нечего». Ребрендинг переписывает первый
слой и часть второго. Третий следует по построению, а компоненты — которые
называли только роли — не меняются вовсе.

## Где правило заканчивается

Два честных ограничения: правило без них — лозунг.

**Роли не выживают, когда их слишком мало.** Если всё `--gr-primary`, вы
построили не систему ролей, а одну переменную. Признак — компонент, которому
приходится локально перебивать токен, чтобы выглядеть верно: этот перебой и есть
роль, которую не назвали. Эти ролевые токены лежат в 8 группах, и их число
росло, а не падало, по мере того как компоненты становились честнее.

**Покомпонентные токены — не провал ролевого слоя.** Максимальная ширина панели
дропдауна не роль: ни у чего больше в интерфейсе нет о ней мнения. Загнав её в
глобальный слой, вы превратите глобальный слой в ящик со всяким. Правило уже,
чем кажется: *глобальные токены — это роли*. Локальным разрешено быть
конкретными, и называться они должны по компоненту, которому принадлежат.

## Проверка

Чтобы понять, роли ли ваши токены, не читайте их. Сделайте другое:
**переименуйте цвет бренда в уме и посчитайте вранье.**

Возьмите `--blue-500` и представьте, что бренд позеленел. Каждое вхождение слова
«blue» в коде — ложь, с которой вы согласились жить. Возьмите `--gr-primary` и
сделайте то же. Считать нечего.

В этом весь довод, и на любой дизайн-системе он выполняется за десять секунд —
включая ту, которая у вас уже есть.
