Я пропустил дизайн-токены в 2020. Миграция в 2023 заняла 6 месяцев

Я начинал дизайн-систему с захардкоженными значениями, чтобы выпустить быстрее. Через три года переход на семантические токены занял больше полугода. Что бы я сделал в первый день.

Знак hydroburner из меди с зелёной патиной на чёрном фоне

В середине 2020 года я пришёл в B2B/B2C SaaS-команду единственным продуктовым дизайнером. UI-кит в Figma имел мало общего с продакшеном. Я начал с аудита: прошёл продукт экран за экраном и собрал самые частые контролы в один файл Figma, со скриншотами и заметками.

В аудите нашлись до 3 вариаций одного и того же контрола, hover, focus и error стейты, написанные отдельно для каждого раздела, и захардкоженные цвета в CSS, которые блокировали любую тёмную тему.

Одна кнопка Save changes в трёх версиях из трёх разделов продукта: радиус 8, радиус 4 и пилюля, три чуть разных синих заливки и разные правила hover и focus
Файл аудита: три версии одного контрола. Схема находки

Почему я начал без токенов

Я был единственным дизайнером, а продукт продолжал выходить. Дизайн-система, которая останавливает релизы на квартал, не строится, поэтому я собирал компоненты внутри живой работы над фичами, и каждая новая фича становилась пилотом для них.

Токены замедлили бы первую версию. Я отложил их осознанно и оставил хардкод, понимая, что это дизайн-долг. Система дошла до продакшена быстрее, а счёт я взял на себя на потом.

Где долг дал о себе знать

Первый звонок прозвучал в 2021 году. Фирменный синий жил в коде тремя чуть разными значениями: #2F5BD8, #3A63E0 и #2A52C9. Никто не замечал, пока клиент не попросил показать тёмную тему. Я поменял основной цвет в стилях Figma руками и отправил фронтенд-лиду список мест, которые надо поправить. Их было около 140, и через 3 релиза несколько кнопок всё ещё оставались синими по-старому.

Миграцию на Variables я оценил в 2 месяца. Ушло больше 6, потому что каждый компонент приходилось руками переводить с сырого значения на роль, а каждый такой перевод требовал проверки в коде.

Таймлайн дизайн-долга: середина 2020 компоненты с захардкоженными значениями осознанно, 2021–2022 всё больше сырых значений с каждым новым компонентом, 2023 Figma Variables и миграция больше 6 месяцев
Как рос долг, схематично

Счёт: 2023

В 2023 году Figma выпустила Variables. Я собрал компоненты заново и разметил 300+ переменных, это стало версией 2.0 системы. Я провёл воркшопы с фронтенд-лидом, чтобы структура токенов совпала с обновлённым стеком.

Главным изменением стал семантический слой. Компоненты перестали ссылаться на примитив вроде blue-500. Они ссылаются на роль, например button-color/primary/default, а роль разворачивается в базовое значение вроде blue-800. Тёмная тема и white-label делаются в несколько кликов.

Три панели слева направо: компонент Button, роль button-color/primary/default и примитив blue-800, в который она разрешается
Схема, не скриншот Figma: как кнопка получает свой цвет
Таблицы семантических токенов в тёмной теме: группы цветовых токенов с их значениями
Версия 2.0: семантические цветовые токены в тёмной теме

Миграция заняла больше 6 месяцев. Мы совместили её с визуальным обновлением пользовательского дашборда, поэтому я ещё и перерисовал навигацию и вынес сайдбары за основной холст, и работа с токенами с редизайном слились в один проект.

Что я получил:

  • Тёмная тема стала возможной. Технически она готова, но ещё не раскатана.
  • Стилевое изменение проходит через весь продукт из переменных Figma.
  • Дизайн и разработка используют одни и те же названия.
  • Код читается без справочника: button-color/primary/default говорит, что это.

Что бы я сделал в первый день

В ретроспективе кейса я писал, что внедрил бы токены с самого начала. Я и сейчас так думаю. ИИ-инструменты тоже могли бы сильно сократить миграцию.

Если у вас те же условия, один дизайнер и живые релизы, вот минимум, который я бы настроил до первого компонента.

  1. Называть стили по роли с первого дня: text-primary и surface-raised вместо gray-900 и gray-100. Роль, которую назвал сегодня, это токен, который не придётся придумывать потом.
  2. Привязывать компоненты только к ролям. Примитив внутри компонента это баг.
  3. Хранить сырые значения в одном месте: один набор цветов, одна шкала отступов, один список радиусов. В моей системе база отступов 4px для компонентов и 8px для блоков раскладки, а цвета это 5 семантических групп по 10 оттенков.
  4. Записать триггер. Долг без даты не гасится. Мой триггер был релиз Variables. Ваш может быть вторым брендом, запросом на тёмную тему или командой из трёх дизайнеров вместо одного.
  5. Разделить миграцию и редизайн. Я их совместил, и проект вырос вдвое. Если визуальное обновление ждать не может, лучше планировать два релиза с двумя наборами критериев приёмки.
  6. Подключить линтер, когда команда растёт. После 200 компонентов поиск отвязанных стилей руками занимал часы раз в две недели. Я собрал AxoLinter, плагин для Figma, который находит значения мимо токенов и показывает покрытие токенами в процентах. Как он работает, есть в проекте AxoLinter.
Вкладка Checker в AxoLinter до и после Fix All: покрытие токенами растёт с 41% до 93%, захардкоженные заливка, радиус и отступ становятся привязанными токенами
AxoLinter: покрытие токенами в процентах. Иллюстративные числа для схемы

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

Следующая заметка

Все заметки
19 октября 2026 г. · Делаю, ИИ и агентыКак сделан этот сайт: Astro, один файл токенов и агент, который идёт по брифу