Татьяна Леонова Все проекты
Личный проектДизайн-системаFigma VariablesДизайн → код2026

Одна дизайн-система для магазина, CRM и кода

Ольга делает серьги из стекла lampwork и натуральных камней. Магазин я сначала собрала прототипом на Lovable, перенесла на свой сервер и взялась за редизайн: быстро нашла стиль черновиками, проверила их в коде на живом сайте, а когда направление утвердили — за неделю собрала из него одну систему для магазина, CRM и кода.

Роль

Дизайнер: правила, токены, компоненты; код пишет ИИ-агент

Срок

1–7 октября 2026 · неделя от утверждённого черновика до системы в коде

Масштаб

5 коллекций · 83 переменные · 39 текстовых стилей · 75 компонентов

Стек

Figma Variables · React 19 · Tailwind 4 · TanStack Start · ИИ-агент

Главная магазина в окне браузера с подписями: bg/cream, Site / Hero Tag, Site/Display/Hero 160/136, Hero Italic → accent/moss, Site / Button Primary L, Site / Chat Widget

Главная магазина (v5) — под каждым элементом стиль, переменная или компонент. Визуально почти та же, что и v3; изменилось всё внутри.

Задача

Сначала найти стиль, потом закрепить системой

Первые варианты я собирала быстро, без стилей и переменных: важнее было за несколько итераций найти образ и посмотреть его в коде на живом сайте. Когда Ольга выбрала направление — v3, 1 октября, — черновик стал исходником для системы.

Лето 2026

Прототип магазина на Lovable

23 августа

Свой репозиторий, затем свой сервер

Сентябрь

Черновики редизайна v1–v3, проверка в коде на сайте

1 октября

Ольга утвердила направление v3

1–7 октября

Правила, токены, компоненты, перенос в код

Черновик v3 · с чего начиналась систематизация
Тексты на текстовых стилях0 из 190
Заливки через переменные1 из 247
Цвета, заданные HEX вручную13
Разных размеров шрифта26 · от 10 до 432 px
Отступов вне сетки 4 px42
Экземпляров компонентов2 из 353 слоёв

Это не ошибки, а цена скорости на этапе поиска: черновики меняются целиком, и закреплять их раньше времени нет смысла. Подсчёт — скриптом по всем слоям фрейма «Landing — Redesign v3».

Что требовалось от системы
  1. Один бренд — две задачи

    Сайт — витрина с журнальной типографикой. CRM — ежедневный рабочий инструмент Ольги, где важнее плотность и понятные статусы.

  2. Тёмный раздел без второго набора

    Натуральные камни показываем на тёмном фоне — теми же компонентами, что и стекло.

  3. Макет = код

    Код пишет ИИ-агент. Он должен брать готовый компонент и токен по имени, а не рисовать элемент заново.

  4. Состояния, которых не было

    Резерв, «нашла хозяйку», пустая корзина, ошибка формы, пару купили, пока оформляли заказ.

Правила

Сначала ограничения, потом токены

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

Одна чётная шкала шрифтов

Размеры — только из шкалы 12 · 14 · 16 · 20 · 24 · 28 · 32 · 40 · 48 · 64 · 80 · 160, без дробных. Интерлиньяж задан в пикселях и тоже кратен 4.

Всё кратно 4

Отступы, размеры и скругления идут с шагом 4 px. Коллекция Base · Spacing — 15 значений от 4 до 160; произвольные отступы в коде запрещены.

Натуральные камни · 12/16 · Label/Caps Янтарь, султанит, жемчуг «Майорка» — Body/M 14/20 Каждая пара собрана вручную — Body/L 16/24

12 px — только капс

Мелкий текст читается только в верхнем регистре с разрядкой. Любой обычный текст начинается с 14 px.

Сетка 12 колонок и база 360

Десктоп 1440: 12 колонок по 88 px, поля 60, межколонник 24. Телефон 360: две колонки по 156 и поля 16 — ширина 375 на 4 ровно не делится.

Архитектура

Три слоя: фундамент, смысл, компонент

Палитра, отступы и скругления — общие для сайта и CRM. Поверх них у каждого продукта свой смысловой слой: сайту нужны фоны разделов и тёмный режим, CRM — цвета статусов заявок. Компоненты знают только смысловые имена.

Слой 1 · Base

Фундамент — общий

Сырые значения. Скрыты из выбора в макете: в слой нельзя «залить» brand/flame напрямую.

Base · Palette12
ink
stone
mist
linen
paper
cream
sage
moss
flame
amber
night-2
forest
Base · Spacing15

4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48 · 56 · 64 · 80 · 96 · 120 · 160

Base · Radius5

4 · 8 · 12 · 16 · full

Слой 2 · Semantic

Смысл — у каждого свой

Имена по роли. Каждая роль ссылается на цвет палитры, и у сайта эта ссылка своя для светлой и тёмной темы.

Site15 токенов × 2 темы
ТокенLightDark
text/primaryinklinen
text/secondarystonemist
text/on-darklinenink
bg/paperpaperink
bg/creamcreamnight-2
bg/nightinkink
accent/mossmossamber
accent/flameflameflame

+ ещё 7: bg/sage, accent/amber, text/on-accent, border/*, overlay/scrim

CRM36 токенов · одна тема
text/primaryink
surface/default#FFFFFF
status/new/baseflame
status/paid/base#3F7A4F
status/paid/subtle#3F7A4F · 8%

С палитрой бренда CRM делит ink и flame; остальные статусы — свои оттенки, у каждого 4 ступени: base, subtle, border, soft.

Слой 3 · Components

Компоненты

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

Site / Button · Primary · L
Заливкаaccent/moss
Текстtext/on-dark
ШрифтSite/Label/M
Поляspace/32 · gap space/8
Скруглениеradius/full
CRM / Tag · Badge
Заливкаstatus/paid/subtle
Текстstatus/paid/base
ШрифтCRM/Body 14 · Medium
Поляspace/8 · space/4
Скруглениеradius/sm

Всего: 45 компонентов сайта, 30 — CRM, 39 текстовых стилей.

Режимы

Тёмный раздел — это режим, а не копия

Натуральные камни показаны на тёмном фоне. Вместо второго набора компонентов у коллекции Site есть режим Dark: секции достаточно переключить режим, и вложенные компоненты перекрашиваются сами. Подвал внутри тёмного раздела принудительно остаётся светлым.

Site · Light — раздел «Стекло»
Раздел «Стекло» в светлом режиме: заголовок и мозаика пар
Site · Dark — раздел «Камни»
Раздел «Камни» в тёмном режиме: фильтр по материалу и полка из трёх колонок
ТокенLightDarkГде видно
text/primarybrand/inkbrand/linenНазвания пар, заголовки, текст
bg/paperbrand/paperbrand/inkФон раздела
bg/creambrand/creambrand/night-2Подложки, плашки
bg/sagebrand/sagebrand/forestАкцентные вставки мозаики
accent/mossbrand/mossbrand/amberКнопки, активный фильтр, курсив в заголовке
text/on-darkbrand/linenbrand/inkТекст на кнопке и тёмных плашках

В коде то же самое: переменные Site лежат в :root, режим Dark — блок [data-theme="dark"] с теми же именами. Разделу камней достаточно атрибута data-theme.

Типографика

Журнальная шкала, которую можно проверить

Piazzolla — для заголовков, имён пар и цитат; Golos Text — для текста, цен и интерфейса. Обе с полной кириллицей. У телефона своя ступень крупных заголовков, остальное общее.

Стиль · размер/интерлиньяжОбразецТелефон
Display/HeroPiazzolla Light 160/136
Искусство
64/60
Display/H2Piazzolla Light 80/76
Стекло, рождённое в пламени
40/44
Display/StatPiazzolla Light 64/56
100%  25+
—
Display/H3Piazzolla Light 48/48
Нашли свою пару?
32/36
Display/QuotePiazzolla Light Italic 40/44
«Украшение — это эмоция»
—
Title/L · M · SPiazzolla Regular 28 · 24 · 20
Изумрудная роса
16/20
Body/L · MGolos Text 16/24 · 14/20
Серьги из авторского стекла lampwork и натуральных камней. Каждая пара — в единственном экземпляре.
—
Label/PriceGolos Text Medium 16/20
3 250 ₽
20/24
Label/CapsGolos Text Medium 12/16 · капс
НАТУРАЛЬНЫЕ КАМНИ
—

Курсивные пары (Hero Italic, H2 Italic…) — отдельные стили с тем же размером: в заголовке «Искусство в деталях» вторая строка курсивом и цветом accent/moss.

Компоненты и состояния

Состояние — это вариант компонента, а не отдельный макет

Каждый элемент интерфейса — компонент с вариантами и свойствами. Состояния, о которых в первом макете не думали, я добавила вариантами: их видит Ольга на согласовании и агент при вёрстке.

Карточка пары в трёх состояниях: в наличии с ценой и кнопкой, в резерве, нашла хозяйку с приглушённым фото
Site / Product Card

Пара в наличии, в резерве или уже у хозяйки

Проданная пара не исчезает: остаётся в мозаике с приглушённым фото (56%). Это доверие к мастеру и повод заказать похожую.

ShapeArch · Arch Down · Oval · Rect
SizeS · Tall · L · Shelf 4:5 · Shelf 1:1
Statusтекст: «В резерве», «Нашла хозяйку»
Availableboolean: цена и материал
Show statusboolean

14 вариантов на десктопе, 10 — на телефоне

Корзина и заказ · телефон 360

Пограничные случаи, собранные из тех же компонентов

Cart Item · Drawer Header · Input · Choice Chip · Info Note · Empty State · Sticky Bar

Корзина на телефоне с двумя парами

Корзина

Цена над главной кнопкой, как на десктопе; состав заказа и итог — в одном экране.

Форма контакта без Telegram: выбор канала и обязательное поле

Без Telegram

Сначала выбор канала, потом обязательное поле под него: телефон, ссылка VK или почта.

Пустая корзина с блоком «Недавно смотрели»

Пустая корзина

Не тупик: блок «Недавно смотрели» возвращает к парам.

Корзина, где одну пару купили во время оформления

Пару купили, пока оформляли

Статус в строке корзины и похожие пары вместо ошибки.

Site / Input

Ошибка всегда объясняет, что не так

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

Поля ввода: пусто с подсказкой, введено, ошибка с текстом под полем
Мозаика

Сетка, которая собирается из любого числа пар

Мозаика вместо сетки 3×3 — главная визуальная идея магазина и главный риск: сегодня у Ольги 9 пар стекла, завтра 17. Я разложила мозаику на компоненты с правилом сборки, чтобы каталог из базы данных собирал её сам.

Два шаблона блока и хвост

Блоки чередуются: Left, Right, Left, Right… Каждый берёт 3 пары и следующую надпись Ольги из списка. Остаток 0, 1 или 2 пары закрывает хвост с финальной фразой. Например, 16 пар = 5 блоков + хвост с 1 парой. Каталог из базы собирает мозаику по этому правилу сам.

Блок мозаики Left: большая арка слева, овал, высокая карточка и текстовая вставка

Блок · Left 1-й, 3-й, 5-й…

Блок мозаики Right: зеркальная раскладка с большой аркой справа

Блок · Right 2-й, 4-й…

Хвост мозаики с одной парой и фразой «Лёгкие. Звонкие. Живые.»

Хвост · остаток 1 пара 16

Макет = код

Одно имя в Figma, в CSS и в компоненте

Система перенесена в код: переменные стали CSS-переменными, текстовые стили — утилитами Tailwind, компоненты — React-компонентами с теми же вариантами. ИИ-агент верстает по именам и не изобретает цвета и отступы.

FigmaCSS · site.cssTailwind / React
Base · Palette — brand/moss--brand-moss: #2e4a35— в компонентах не используется
Site — accent/moss--accent-moss: var(--brand-moss)bg-moss
Site — text/secondary--text-secondarytext-fg-muted
Site — режим Dark[data-theme="dark"] { … }<section data-theme="dark">
Текстовый стиль Site/Display/H2@utility t-display-h2className="t-display-h2"
Base · Spacing — space/24шкала Tailwind, шаг 4 pxp-6 · gap-6
Site / Button · Kind=Primary · Size=L—<Button kind="primary" size="L">
src/design/site.css

/* Base · Palette — сырые значения */
--brand-moss: #2e4a35;
--brand-amber: #e2a64b;

/* Site · Light */
--accent-moss: var(--brand-moss);
--bg-paper: var(--brand-paper);

/* Site · Dark — раздел камней */
[data-theme="dark"] {
  --accent-moss: var(--brand-amber);
  --bg-paper: var(--brand-ink);
}
0HEX-цветов в 63 файлах компонентов сайта и CRM — только токены
26 = 26текстовых стилей сайта в Figma и утилит t-* в коде
/kitстраница со всеми компонентами кода для сверки с Figma
CRM

CRM — рабочий инструмент со своими стилями

CRM — ежедневный инструмент Ольги, поэтому журнальный стиль сайта сюда не переносится: только Golos Text, нейтральные поверхности, плотные списки. Фирменные цвета работают как значения статусов заявок.

Доска заявок CRM: шесть колонок статусов с карточками клиентов
Лид Новая В работе Ссылка отправлена Оплачено Закрыта

status/new · progress · sent · paid · closed · lead — по 4 оттенка на статус

Итог

Что даёт система и что дальше

Один набор на две темы

Карточки, кнопки и фильтры в тёмном разделе камней — те же компоненты, что в светлом. Их перекрашивает режим Dark, тёмных копий нет.

Любое число пар

Мозаика собирается сама из блоков и хвоста; проверено на 9, 15, 16 и 17 парах.

1 правка

В палитре Base меняет оттенок сразу на сайте и в CRM — смысловые токены ссылаются на неё.

По именам

Агент верстает из готовых компонентов и токенов — в коде 0 цветов, заданных вручную.

Что бы сделала иначе

Порядок — тот же, но с одним исключением

  • СразуЦвета и шрифты завела бы переменными и стилями с первого черновика. Это почти ничего не стоит и не замедляет поиск — зато аудит v3 был бы короче.
  • После выбораКомпоненты, правила сетки и мозаику — по-прежнему после того, как направление утверждено: систематизировать то, что завтра будет не нужно, дороже, чем потом собрать.
  • В продуктеВ команде с готовой дизайн-системой порядок обратный: новый экран начинается с системы, а не с черновика.
  • ДальшеCode Connect: сейчас Figma и код связаны одинаковыми именами и страницей /kit, следующий шаг — чтобы агент получал код компонента прямо из макета.
Главный вывод

Система окупилась в тот момент, когда вёрстку стал делать ИИ-агент: он перестал придумывать значения, потому что всё, что ему нужно, уже названо.