Каждый элемент системы имеет стабильный номер. Правки удобно давать так:
BRK-024 — аватар 44px вместо 40 или BRK-041 — строка 48px.
Номера постоянные и никогда не переиспользуются: новый элемент получает следующий свободный номер,
даже если стоит в другом разделе. Клик по номеру копирует его. Демо отрисованы настоящим
tokens/brand.css — то, что видите, и есть поставляемый стиль (проверьте обе темы
переключателем справа).
Основы
Палитра: бренд и нейтрали
accent#0d8f9c
banner#16386e
ink#14181f
ink-2#3a4150
muted#6a7180
faint#98a0ae
bg#eef0f4
surface#ffffff
surface-2#f7f8fb
field#f5f6fa
chip#f0f2f7
sidebar-bg#fafbfc
line#e6e8ee
line-2#eef0f4
Hex в свотчах — светлая тема; в тёмной те же переменные получают значения из theme.dark (переключите тему — свотчи живые). Локальные палитры и hard-coded цвета запрещены.
Только для состояния, не как декоративная палитра серий. Софт-подложки строятся через color-mix от базового цвета — в тёмной теме пересчитываются сами.
Продуктовый цвет живёт только в чаше фавикона и слове модуля. --accent остаётся цветом active/hover/KPI в каждом продукте. Новый продукт берёт следующий свободный цвет; статусные не переиспользовать; если не подходит ни один — спросить владельца.
Три режима, по умолчанию system. Тёмная включается атрибутом data-theme="dark" на <html>; компоненты на токенах не требуют отдельного тёмного CSS. No-flash скрипт theme.head.html инлайнится в <head> до стилей — обязательно.
Формула: IBM Plex Mono — числа, Onest — интерфейс, Red Hat Display — логотип. Red Hat Display в заголовках интерфейса запрещён (есть typography guard в тестах).
Пять ярусов, других размеров в интерфейсе нет. Внутри инструментов — вес, а не размер: заголовки дашбордов компактные.
tokens: text.* · CSS: .bark-h1….bark-caption
Шкала отступов (4px)
4 · 8 · 12 · 16 · 20 · 24 · 32 · 40
Каждый gap и padding — со шкалы, промежуточных значений нет. Больше 40px в рабочих экранах не бывает (воздух сверх этого — только empty states и auth).
tokens: spacing · CSS: --space-1…--space-10
Радиусы
control · 8px
panel · 12px
tile · 22%
Три радиуса: контролы/чипы/пункты — 8px, карточки/панели — 12px, плитка логотипа — 22% стороны (в ассетах — round(0.22×сторона): favicon rx14, app icon rx113, локап rx16). Других нет.
Три уровня: card — покой на поверхности, up — приподнятые блоки, pop — всплывающие слои (модалки, меню, тосты). Случайные тени запрещены.
tokens: shadow.* · CSS: --shadow-card/-up/-pop
Motion
fast 120 · base 200 (popover/modal) · slow 300 (reveal) · easing cubic-bezier(0.2, 0, 0, 1)
Transition только для color / background / border-color / box-shadow / opacity / transform — никогда для всех свойств сразу. prefers-reduced-motion отключает декоративную анимацию.
Промежуточные значения не изобретаются. Дропдауны и меню — --z-dropdown, тосты — --z-toast, полноэкранный лоадер — --z-loader.
tokens: z.* · CSS: --z-*
Иконки: Lucide
18px — сайдбар20px — контент
Один пакет: Lucide (lucide.dev), outline, currentColor, stroke 1.7. 18px в сайдбаре, 20px в контенте. Filled-иконки, чужие паки и смешанные stroke запрещены.
плитка тёмная в обеих темах; счётчик чаши — фон, не цветная точка
Единственная геометрия из assets/mark.svg (стем + кольцо, viewBox 64). Белый знак на градиентной ink-плитке #1d2733→#14181f; знак = 74% плитки. Минимум плитки 16px; ниже — только фавикон. Перекраска, наклон и перерисовка запрещены.
ассеты: assets/mark.svg, mark-mono.svg · док: docs/STYLE_GUIDE.md §Logo system
Red Hat Display: bark 800 в ink, модуль 600 в продуктовом цвете (через --logo-module, fallback — accent), сабтайтл Onest 700 uppercase на своей строке. Сайдбар всегда ярус lg: плитка 32 / слово 18 / сабтайтл 10.
Запрещено: PascalCase (BarkOne), пробел (bark one), точка (bark·one), подчёркивание (bark_one), КАПС. Клирспейс — 0.5 высоты плитки со всех сторон.
UI-wordmark всегда lower-case, слитно: bark<module>. Цвет несёт суффикс, не «bark». В прозе заголовков GitLab допустим Title Case, в UI — нет. Naming-guard в проверке ловит запрещённые формы в ассетах и шаблонах.
Чаша «b» заливается продуктовым цветом — ключ вкладки на 16px; семейный фавикон остаётся монохромным. Генерация только через npm run make:product, руками не рисовать.
Чаша отражает живой статус: один SVG на состояние, свап через setFaviconState(). Плитка и стем неизменны; бренд-цвет продукта в иконке приложения остаётся прежним.
Типографский «b» (Red Hat Display, белый) + слово модуля в продуктовом цвете, rx = 22% стороны. PNG (192/512/apple-touch) растеризуются из этого SVG со шрифтом — см. README ассетов продукта.
генератор: tools/make-product-assets.mjs · манифест: theme_color = продуктовый цвет
5 пунктов приёмки: generated favicon.svg · PNG 192/512 + apple-touch из pwa-icon · generated manifest · theme-color = продуктовый цвет · старые иконки удалены. Каждый продукт имеет готовый заполненный файл.
244px, sticky 100dvh, фон --sidebar-bg, паддинг 20 14 14. Скроллится только навигация; логотип и нижняя зона пиновые. Порядок низа: theme switch → блок идентичности → мета. Ширину, лейблы групп и подсветку актива менять нельзя.
Сегментный 3-way (солнце/луна/монитор), активный сегмент — приподнятая пилюля --raised + accent-иконка. На десктопе — полноширинный в низу сайдбара; на мобиле — в drawer. Две видимые копии одновременно запрещены.
Аватар 40px (фото из SSO picture; fallback — инициалы initialsFromName()), имя Onest 13/600 и email 11/500 — по одной строке с ellipsis, справа icon-only «Выйти». Имя/email — из текущей SSO-сессии. Ровно одна точка идентичности в оболочке; в шапке страницы аватара нет; barkone — задокументированное легаси-исключение.
наведите: hover = bad-soft + badbusy: спиннер 18px + aria-busy
Icon-only 40×40, Lucide LogOut 18px, «Выйти» — только aria-label + title. Вызывает существующий logout-handler приложения; confirmation-модалки по умолчанию нет; продуктовый цвет кнопку не трогает.
tokens: sidebar.footer.logout · CSS: .bark-sidebar__logout · док: COMPONENT_RULES §Выход из системы
Faint 11/500: продукт + версия, commit-хэш в mono, версия бренда «Bark UI vX.Y.Z» (обязательно — по ней видно отставшие продукты), дата ДД.ММ.ГГГГ. Атрибуция разработчика опциональна и никогда не вытесняет навигацию или блок идентичности.
H1 слева (+ мета-строка: caption 12, значения в mono через «·»), справа ghost-кнопки 36px (Lucide 20). Аватара в шапке нет — идентичность в BRK-024. Приветствие с именем — контент главной, не элемент оболочки.
.bark-main padding 24px 32px 40px (моб. 16px)
секции gap 24px сетки карточек gap 16px
панель body 20px --dense 12px 16px
таблица 44px / 36px KPI 16px 20px
reading max-width 840px >40px только empty/auth
Плотность — константа бренда. Два режима: default и --dense; «воздушнее» стандарта не бывает. Проверка: на 1440×900 первый экран дашборда = шапка + минимум два ряда контента.
tokens: layout, density · CSS: .bark-main, .bark-grid · док: STYLE_GUIDE §Page shell & density
Панель: анатомия
Заголовок панели
Тело панели — паддинг 20px.
Dense
Тело 12×16 — мониторинг и плотные списки.
Радиус 12, бордер --line, тень card. Header 16 20 с разделителем --line-2, body 20, footer 12 20 (кнопки справа). Единственный плотный режим — --dense.
Паддинг 16 20; label — caption 12/500 muted; значение — IBM Plex Mono 24/600 с tnum; дельта — статусная пилюля; сетка — .bark-grid (minmax 220, gap 16). Компактные деньги — только здесь.
tokens: kpi · CSS: .bark-kpi*
Аватар: размеры и fallback
ВШВШВШsm 24 · md 32 · lg 40 · фото cover
Круг, бордер --line; инициалы Onest 600 на --accent-soft — считаются только initialsFromName(): первые буквы первого и последнего слова («Владимир Шурыгин» → «ВШ»; одно слово → две буквы; пусто → «•»). Фото — строго из SSO picture с lazy/async/no-referrer.
Async-кнопка: спиннер 18px заменяет иконку, ширина не меняется, текст — действие в процессе («Сохраняем…», не «Загрузка…»), disabled + aria-busy. --block тянется только в узком контейнере; на десктопе кап ~360px — кнопок во всю ширину экрана не бывает.
Существующая кнопка входа сразу после клика: спиннер 18px + «Входим…», disabled + aria-busy, держится до redirect/ошибки (через startButtonLoading() — успех не снимает загрузку). Вторая кнопка или одновременный полноэкранный лоадер запрещены.
Label всегда виден (12/600); placeholder — пример, не замена. Высота 40 (sm 32 / lg 48), фон --field, радиус 8. Focus: accent-бордер + кольцо; error: --bad + текст; hint резервирует место (нет прыжков). Валидация — на submit/blur.
Софт-подложка + статусный текст, радиус 999, паддинг 4 10, Onest 12/600. Используются для состояния (таблицы, KPI-дельты, шапки панелей) — не как декоративные теги.
CSS: .bark-pill--ok/warn/bad/info
Модалка
Подтвердите действие
Смена привязки БД применяется сразу, без перезапуска.
Ширины: sm 400 / md 560 / lg 720; max-height 85dvh, скроллится только body; backdrop — ink 56%. Закрытие: X (Lucide), Esc; фокус-ловушка. Кнопки: secondary → primary; деструктив — --bad и явный глагол. Вложенные модалки запрещены; формы >6 полей — на страницу/в drawer.
Ровно одна активная сортировка: th[aria-sort], стрелка и заголовок — accent. Весь заголовок — кнопка; неактивная сортируемая колонка — arrow-up-down 14px faint. Первый клик: числа/даты — по убыванию, текст — по возрастанию; повторный — смена направления. Multi-sort запрещён; состояние в URL; смена возвращает на страницу 1.
tokens: table.sort · CSS: .bark-table__sort · док: COMPONENT_RULES §Сортировка и действия строк
Действия строк
Сотрудник
Действия
Пример строки
Последняя колонка, вправо, ширина по содержимому. До 2 частых действий — icon-only ghost 32px, видимы всегда (не только hover). 3+ — один kebab с меню BRK-042. Деструктив — только в меню + подтверждение; инлайн-корзина запрещена. Строка с деталкой кликабельна целиком (кроме зоны действий).
Min-width 180, пункты 36px (Onest 14 + Lucide 18), паддинг 4, radius 8, тень pop, слой --z-dropdown. Деструктивный пункт — --bad за разделителем, hover — --bad-soft. Esc закрывает, фокус возвращается на триггер. Используется для kebab строк и popover «Фильтры».
tokens: menu · CSS: .bark-menu*
Тулбар фильтров
…таблица…
Паддинг 12 20, контролы 32px, gap 8. Поиск ≥220px; до 3 inline-фильтров, дальше — одна кнопка «Фильтры» с popover (drawer запрещён). Применённые фильтры — accent-чипы 28px с крестиком; «Сбросить» видна при ≥1 активном. Состояние — в URL; пустой результат — empty state со сбросом.
Единственный контрол мульти-выбора в тулбаре. Кнопка-пилюля 28px с aria-pressed: вкл — --accent-soft + accent + галочка 14px, выкл — --chip + --ink2. От 2 до 6 опций; больше — один popover «Фильтры». Подпись группы — caption 12/500 muted с двоеточием, не жирный заголовок; отдельные info-иконки в тулбаре запрещены. Переключение применяется сразу, состояние в URL. Чекбоксы в рамках/квадратах — запрещены.
Обязательна при >50 строк. Размеры 25/50/100 (по умолчанию 50); счётчик «1–50 из 1 234» в mono; prev/next 32px, на краях disabled. Номерных страниц и infinite scroll нет; переход сохраняет фильтры и сортировку.
По заданным фильтрам нет записей. Попробуйте изменить условия.
Иконка 20px в круге 40 --chip, заголовок 14/600 --ink2, подсказка 12 ≤360px, одно ghost-действие. Заполняет свой регион, никогда не весь экран и не маркетинговая иллюстрация. Полезно и коротко.
Один стек справа внизу (демо — статичное), ≤3 видимых, ширина ≤360. ok/info 5с · warn 8с · bad до закрытия; появление 200ms. role=status/alert. Заголовок ≤60 обязателен; текст ≤140 и одно действие — опция. Toast = событие; валидация — у поля, состояние — BRK-047, решение — модалка.
Раздел в режиме «только чтение» до завершения инвентаризации.
Данные могли устареть: синхронизация 32 мин назад.
Интеграция с CRM недоступна — заявки не обновляются.
Постоянное состояние региона (деградация, read-only, устаревшие данные): живёт внутри региона, не стекается, не исчезает сам. Паддинг 12 16, radius 8, Lucide 18 в цвет статуса. Toast = событие, alert = состояние.
tokens: alert · CSS: .bark-alert--*
Лоадер бренда (lg / md / sm)
lg 60/43 — cold start · md 40/29 — регион · sm 28/20 · оборот 0.9с
Accent-дуга вокруг монохромного знака — один loader language на все продукты, свои спиннеры запрещены. Полноэкранный — только cold start/восстановление сессии. Регион: показывается после 400ms, ≥300ms видим; после 2с — пояснение, после 8–10с — retry/cancel.
route progress 2.5px — верх main-content, после 150ms, не поверх сайдбара
Формируем отчёт · 64%
Skeleton — на месте будущих строк, без layout shift. Determinate progress + % — для upload/export >2с, рядом с задачей, не в глобальном оверлее. Один action = один лоадер (без дублей overlay+region+button).
линия 2px · заливка области 12% · сетка --line-2 · оси и значения — IBM Plex Mono
Библиотека: Apache ECharts 5+ для новых графиков (тема «bark» из живых токенов; бандл self-hosted, CDN запрещён; легаси сохраняет свою библиотеку на этих же токенах). Максимум 4 серии; статусные цвета — только для состояния; продуктовый цвет данными не становится. Разрешены: line, area, bar, hbar, stacked, donut (2–5 сегментов), scatter, sparkline. Запрещены 3D, radar, gauge, exploded pie, dual axis без причины.
toast = событие · alert = состояние · модалка = решение · у поля = валидация
Фоновые/долгие операции завершились — toast (BRK-046). Регион живёт в особом режиме — inline alert (BRK-047). Нужно блокирующее решение — модалка (BRK-038). Ошибка ввода — подсказка у поля (BRK-035). Никогда не смешивать и не дублировать каналы для одного события.
док: COMPONENT_RULES §Уведомления
Композиционный guard (для AI-агентов)
Код и текущий интерфейс приложения определяют, что существует. Брендбук определяет, как существующее выглядит и ведёт себя. Примеры и скриншоты — не бэклог: ничего не добавлять, не удалять и не выдумывать без запроса.
Запрещено: вторые Avatar/sidebar/chart engine, придуманные данные и разделы, смена бизнес-логики ради брендинга. Обязателен отчёт: что изменено, что намеренно нет, какие gaps найдены.
Все времена — МСК (Europe/Moscow), локальная таймзона браузера не используется; где неочевидно — суффикс «МСК». 24 часа; 12-часовой формат, AM/PM и ISO-вид в UI запрещены. В API/datetime — ISO 8601.
Разряды и запятая — Intl ru-RU, свои разделители запрещены. «руб.», «RUB», ₽ перед суммой и латинские K/M — запрещены. Компактные деньги — только KPI; таблицы и детали всегда точные.
Лестница длительностей фиксированная; единицы русские сокращённые. Диапазоны — en dash со схлопыванием общих частей. ID/хэши/версии не группируются и не сокращаются.
npm i @bark/brand-system@^2 # GitLab Package Registry (проект 63)
<link href="https://static.bybark.net/dist/v2.0.0/brand.css"> # URL закреплён навсегда
npx bark-check # линтер бренда в CI каждого продукта
npm run release -- 2.1.0 # релиз: версия + зеркала + dist + check
SemVer (CHANGELOG.md): major — ломающие изменения, minor — новые компоненты, patch — правки значений. Тег vX.Y.Z публикует npm-пакет; dist/vX.Y.Z/ — append-only статика для PHP-продуктов. Каждый продукт показывает Bark UI vX.Y.Z в мета сайдбара (BRK-026). Зеркала CSS/Tailwind генерируются из токенов — правки значений только в brand.tokens.json + npm run build:tokens.
push в main → deploy # ветки и MR только проверяются
tags: [runner-dev] # на КАЖДОЙ джобе, иначе pending навсегда
include: ci/bark-deploy.gitlab-ci.yml + переменные DEPLOY_*
откат: git revert → пайплайн # или Retry старой deploy-джобы
Единственный путь выкладки — GitLab CI на `runner-dev` (shell executor, `image:` игнорируется); ручной rsync/scp мимо CI запрещён. Продукт подключает готовую джобу include-ом и задаёт переменные: `DEPLOY_KEY` (file), `DEPLOY_HOST_KEY` (пиновый), `DEPLOY_TARGET`, опционально `SOURCE_DIR`/`BUILD_CMD`/`RELOAD_CMD`/`URL`. Деплой-пользователь без root; секреты только в CI-переменных; environment `production` показывает живой URL. Промт внедрения — `templates/DEPLOY.prompt.md`.