Построение цветовой системы
От raw-палитры к семантическим токенам, темам и контрасту — с проверкой на edge-кейсах.
Построй цветовую систему для: {{brand}}. Опорный акцент: {{accent}}.
Тезис: цвет — это трёхслойная система. Сырая палитра → семантические токены → компонентные роли. Никогда не пиши hex в компоненте.
Слой 1. Raw-палитра
Для каждого цветового канала — шкала из 11 ступеней: 50, 100, 200, …, 900, 950.
- Neutrals — обязательно, обычно cool/warm grey с лёгким тёплым или холодным наклоном (не чистый
#888) - Accent (brand) — один основной, шкала 50→950
- Семантические — success, warning, danger, info (каждый своей шкалой)
- Опционально: secondary accent (только если он реально нужен — фичи, иллюстрации)
Правила построения шкалы:
- 50 — близко к фону (для tints), 900-950 — близко к тексту
- Между ступенями — равномерный шаг по воспринимаемой яркости (OKLCH или HSL.L), не по hex
- На каждой ступени контраст к 50 и к 950 предсказуем
- Используй OKLCH для генерации, не HSL — у HSL зелёный и жёлтый "тяжелее" остальных
:root {
--neutral-50: oklch(0.98 0.005 250);
--neutral-100: oklch(0.96 0.005 250);
/* … */
--neutral-950: oklch(0.15 0.01 250);
--accent-500: oklch(0.62 0.18 250);
/* … */
}
Слой 2. Семантические токены
Никогда не используй raw в компонентах. Используй роль.
:root {
/* Поверхности */
--bg: var(--neutral-50);
--bg-subtle: var(--neutral-100);
--bg-elevated: #fff;
--bg-inverse: var(--neutral-950);
/* Текст */
--fg: var(--neutral-900);
--fg-muted: var(--neutral-600);
--fg-subtle: var(--neutral-500);
--fg-on-accent: #fff;
--fg-inverse: var(--neutral-50);
/* Границы */
--border: var(--neutral-200);
--border-strong: var(--neutral-300);
/* Интерактив */
--accent: var(--accent-500);
--accent-hover: var(--accent-600);
--accent-active: var(--accent-700);
--accent-fg: #fff;
/* Состояния */
--success: var(--green-500);
--success-bg: var(--green-50);
--danger: var(--red-500);
--danger-bg: var(--red-50);
}
Слой 3. Темы
Тёмная тема — другие назначения тех же ролей, не новая палитра:
[data-theme="dark"] {
--bg: var(--neutral-950);
--bg-subtle: var(--neutral-900);
--bg-elevated: var(--neutral-800);
--fg: var(--neutral-50);
--fg-muted: var(--neutral-400);
--border: var(--neutral-800);
--border-strong: var(--neutral-700);
/* Акцент в тёмной обычно ступенью светлее */
--accent: var(--accent-400);
--accent-hover: var(--accent-300);
}
Правила:
- Не используй
#000для фона (используй 950) - Не используй
#fffдля текста (используй 50) - Цветные акценты в тёмной — на 1-2 ступени светлее (восприятие)
- Тени почти не работают — используй яркую границу или внутренний highlight
Контраст
| Контекст | WCAG | Минимум |
|---|---|---|
| Body text | AA | 4.5:1 |
| Large text (≥ 18px / 14px bold) | AA | 3:1 |
| UI components (border, иконки) | AA | 3:1 |
| Любой текст | AAA | 7:1 |
Каждую пару fg / bg и accent-fg / accent проверь до того, как ушло в код.
Edge-кейсы (обязательная проверка)
Прогон по списку — каждый кейс должен жить:
- Текст на акценте —
--fg-on-accentконтрастен--accentв обоих темах - Disabled — есть отдельный токен, не просто
opacity: 0.5(контраст портится) - Placeholder — ≥ 3:1 к фону инпута (часто проваливается)
- Focus ring на акцентной кнопке — виден на самом акценте
- Selected row / hover row — отличимы друг от друга и от default
- Toast/badge на цветном фоне — успех на danger не сливается
- Графики — палитра серии (≥ 6 цветов) отличима у дальтоников (deuteranopia/protanopia)
- Принт — токены деградируют в greyscale без потери иерархии
- Высокая контрастность ОС (
forced-colors: active) — компоненты не разваливаются - Изображения и логотип — версия для тёмной готова
Проверка на компонентах
Не прими систему пока не прогнал по этим экранам в обеих темах:
- Кнопки: primary, secondary, ghost, destructive, disabled
- Инпут: default, focus, error, disabled, with-icon
- Стол: header, row, hover, selected, footer
- Тост: success, warning, danger, info
- Карточка на цветном фоне (success-bg)
- Модалка с overlay
- Code-блок (если есть)
- Пустое состояние
Формат вывода
- Токены в OKLCH (raw + semantic) — готовый CSS
- Tailwind config маппинг (если используется)
- Таблица контраста — все важные пары fg/bg, обе темы
- Edge-case чек-лист — отмечено, что прошло
- Скриншоты компонентов в обеих темах (или JSX-превью, который можно скопировать)
Анти-паттерны
- Hex в компоненте (
bg-[#3b82f6]) - Палитра в HSL без проверки воспринимаемой яркости — зелёный/жёлтый выпадают
- Тёмная как
filter: invert(1) - "У нас десять акцентов" — система ломается; держи один, максимум два
- Семантика повторяет имя цвета (
--blueвместо--accent) — нельзя ребрендить - Контраст проверяется "на глаз" вместо чисел
Аудит доступности по WCAG 2.2 AA
Проверка контраста, клавиатурной навигации, скринридеров, фокус-индикаторов и ARIA.
Аудит brand-consistency
Прогон интерфейса на согласованность: цвета, spacing, typography, voice, иконки. Найти отклонения от системы.
Мастер-аудит сайта: 6 измерений за один проход
Orchestrator-аудит по 6 направлениям: UX, accessibility, performance, SEO, brand consistency, security. Quick scan + deep dive + приоритизированный план + композитная оценка + roadmap.