Цветовая система и брендовые палитры
1) Зачем формализовать цвет
Цвет — это не набор «хороших оттенков», а управляемая система для:- узнаваемости бренда и визуальной консистентности,
- читаемости и доступности (WCAG),
- масштабирования интерфейсов (темы, платформы, локали),
- предсказуемых A/B-экспериментов (контраст, CTR, ошибки).
2) Основания системы: модели и метрики
OKLCH (рекомендуется): перцептуально равномерная, удобно контролировать светлоту `L` и насыщенность `C` при сохранении оттенка `H`.
Lab/LCH: также годится; OKLCH стабильнее по восприятию.
sRGB: конечное пространство отображения; итоговые значения всегда валидируем в sRGB и по WCAG.
Контраст (WCAG 2.2): базовый текст ≥ 4.5:1, крупный ≥ 3:1; критические уведомления — целиться в AAA (7:1) там, где это возможно.
3) Слои системы: от бренда к семантике
1. Бренд-ядро: 1–2 фирменных оттенка (+ поддерживающий акцент).
2. Семантика интерфейса: роли (`primary`, `secondary`, `success`, `warning`, `danger`, `info`, `neutral`).
3. Шкалы тонов: шаги по светлоте (напр., 25/50/100…900).
4. Темы: `light` / `dark` (+ high-contrast, AMOLED).
5. Состояния: `default/hover/active/focus/disabled`.
6. Контекст: поверхностей (`bg/base`, `bg/subtle`, `bg/elevated`) и текста (`fg/primary`, `fg/secondary`, `fg/muted`).
7. Визуализация данных: отдельные дискретные и непрерывные палитры.
4) Бренд-ядро: выбор и ограничители
Выберите главный оттенок (Hue) и определите рабочую светлоту для бренда в светлой и темной темах (часто `L≈0.60–0.70` для заливки кнопок в light и `L≈0.70–0.80` для текста/иконок в dark).
Ограничьте хрому `C`: высокие `C` красиво на баннерах, но ломают читаемость в UI — держите 2 версии: «маркетинговая» (насыщенная) и «продуктовая» (сдержаннее).
Зафиксируйте вариативы: основной (`brand/primary`), альтернативный (`brand/alt`) и нейтральная опора (`neutral`).
5) Шкалы тонов (tonal scales)
Цель — получить равномерные ступени светлоты с управляемой насыщенностью:- Для OKLCH двигайте `L` ступенями (напр., 0.98→0.90→0.80→…→0.18), а `C` слегка уменьшайте к краям шкалы, чтобы избежать «грязи» в светлых и «мутности» в темных.
- Фиксируйте контрольные точки: `50/100/300/500 (key)/700/900`.
- На каждом шаге проверяйте контраст пары с базовым фоном и с ожидаемым цветом текста.
Пример шкалы brand/primary (OKLCH, приближенно)
brand. primary. 50 = oklch(0. 98 0. 03 230)
brand. primary. 100 = oklch(0. 94 0. 05 230)
brand. primary. 300 = oklch(0. 86 0. 08 230)
brand. primary. 500 = oklch(0. 74 0. 10,230) # keytone brand. primary. 700 = oklch(0. 56 0. 09 230)
brand. primary. 900 = oklch(0. 32 0. 07 230)
6) Семантические роли и маппинг
Разделяйте бренд и семантику: «успех» не обязан быть бренд-зеленым.
role. primary. bg -> brand. primary. 500 role. primary. text -> fg. on-primary # ≥ 4. 5-1 to the role. primary. bg role. success. bg -> green. 500 role. warning. bg -> amber. 500 role. danger. bg -> red. 500 role. info. bg -> blue. 500 role. neutral. bg -> gray. 200/700 (light/dark)
Тексты `on-` рассчитываются автоматически (см. §10).
7) Светлая/темная темы и поверхности
Определите базовую шкалу поверхностей и текста:
light:
bg/base = oklch(0. 98 0. 01 260)
bg/subtle = oklch(0. 96 0. 01 260)
bg/elevated = oklch(0. 93 0. 01 260)
fg/primary = oklch(0. 18 0. 03 260) # ≈7:1 к bg/base fg/secondary = oklch(0. 32 0. 03 260) # ≥4. 5:1 border = oklch(0. 80 0. 02 260)
dark:
bg/base = oklch(0. 16 0. 01 260)
bg/subtle = oklch(0. 20 0. 01 260)
bg/elevated = oklch(0. 24 0. 01 260)
fg/primary = oklch(0. 90 0. 02 260)
fg/secondary = oklch(0. 78 0. 02 260)
border = oklch(0. 34 0. 02 260)
Сохраняйте равные цели контраста в обеих темах; избегайте «слепящих» белых на чистом черном — поднимайте `L` фона до ~0.16.
8) Состояния и интерактивность
Для каждой роли задайте состояния с контролируемым `ΔL` и `ΔC`:
button/primary:
default. bg = brand. primary. 500 hover. bg = brand. primary. 500 with +ΔC(0. 01) -ΔL(0. 02)
active. bg = brand. primary. 700 focus. ring = brand. primary. 300 # ring contrast ≥ 3:1 to the disabled environment. bg= neutral. 200 (light) / neutral. 700 (dark)
text. on = auto-contrast(default. bg) # ≥ 4. 5:1
9) Ответственность и WCAG
Базовый текст и иконки в управляющих элементах — ≥ 4.5:1.
Ключевые системные уведомления (KYC/AML, 18+, платежные ошибки) — целимся в AAA (7:1).
Состояния и границы полей — не ниже 3:1.
Ссылки отличайте не только цветом (подчеркивание/focus-стиль).
10) Автоподбор контрастного текста (`on-`)
Логика: при выборе заливки компонента вычислять `on-color`:1. По OKLCH определить предлаг. текст `L_on` так, чтобы `(L_text vs L_bg) ≥ 4.5:1`.
2. Если хрома высока, снизить `C_text` до 0.01–0.03.
3. Для темной темы поднимать `L_on` еще на 0.02–0.04, чтобы компенсировать глейр.
Псевдо-токен:
fg. on(colorX) = auto(colorX, targetContrast=4. 5)
11) Визуализация данных
Категориальные палитры: 8–12 цветов, устойчивых к дальтонизму (избегайте пар «красный–зеленый» без альтернативных признаков).
Непрерывные: от `bg/elevated` к акценту с контролем контраста подписей.
Добавляйте паттерны/маркеры для различимости без цвета.
12) Международный контекст (культурные ассоциации)
Учитывайте локальные коннотации (напр., красный — опасность/внимание; золото — выигрыш/приз).
Для iGaming: избегайте конфликтов «успех/опасность» с брендовыми акцентами в одном экране; иконография и подписи важнее «яркости».
13) Интеграция в дизайн-систему
13.1 Именование токенов
color.{theme}.{role surface brand}.{state step}
color examples. light. brand. primary. 500 color. dark. role. success. bg color. light. surface. bg. base color. light. fg. on-primary
13.2 Токены (JSON / Style Dictionary)
json
{
"color": {
"light": {
"surface": { "bg": { "base": "oklch(0. 98 0. 01 260)"} },
"brand": { "primary": { "500": "oklch(0. 74 0. 10 230)" } },
"role": { "primary": { "bg": "{color. light. brand. primary. 500}" },
"danger": { "bg": "oklch(0. 62 0. 12 25)" } },
"fg": { "primary": "oklch(0. 18 0. 03 260)",
"on-primary": "auto({color. light. role. primary. bg},4. 5)" }
}
}
}
13.3 CSS-переменные (слой тем)
css
:root[data-theme="light"] {
--bg-base: oklch(0. 98 0. 01 260);
--brand-primary-500: oklch(0. 74 0. 10 230);
--fg-primary: oklch(0. 18 0. 03 260);
--on-primary: color-contrast (var (--brand-primary-500)) ;/auto-fit/
}
[data-theme="dark"] {
--bg-base: oklch(0. 16 0. 01 260);
--brand-primary-500: oklch(0. 74 0. 10 230);
--fg-primary: oklch(0. 90 0. 02 260);
--on-primary: color-contrast(var(--brand-primary-500));
}
13.4 Figma/документация
Компоненты используют только токены, прямые HEX/SRGB запрещены линтерами.
В библиотеке — страница «Матрица контраста»: таблица `fg × bg` с фактическими коэффициентами.
14) Процессы контроля качества
В дизайне: проверка контраста на артбордах (оба режима), отдельные пресеты для дальтонизма.
В коде: юнит-хелперы вычисляют контраст и падают при нарушениях; визуальные снепшоты для критичных экранов.
В CI/CD: проверка всех пар токенов и состояний, отчет с компонентом, темой и фактическим значением.
15) Специфика iGaming
Промо и турниры: используйте оверлей и ограничение `C` на фонах, чтобы текст не «тонул».
Ответственные уведомления (лимиты, 18+, риски) — искренне AAA.
Метрики/таблицы: числа и знаки изменений (↑/↓) различайте формой и контрастом, а не только цветом.
16) Чек-лист внедрения
- Определены бренд-оттенки и их тональные шкалы (OKLCH).
- Заданы роли, состояния и поверхности для двух тем.
- Автогенерация `on-` с целевым контрастом.
- Матрица `fg × bg` и тесты WCAG в CI.
- Отдельные палитры для датавиз (с поддержкой дальтонизма).
- Линтер стилей запрещает «сырые» цвета.
- Страница «Исключения и причины» в гайдлайне.
17) Анти-паттерны
Смешивать бренд-акцент с «успех/ошибка» в одном UX-сигнале.
Полагаться только на насыщенность для иерархии.
Не синхронизировать light/dark (контраст «уехал» в одной из тем).
Жесткий HEX без токенов → неконтролируемый дрейф интерфейса.
Краткое резюме
Стройте палитру сверху вниз: бренд-ядро → семантические роли → шкалы тонов → темы → состояния. Работайте в OKLCH, закрепляйте токены, автоматизируйте `on-` и WCAG-проверки. Отдельно ведите палитры для датавиз. Это даст консистентность бренда, читаемость и масштабируемость продукта.