Логотип и бренд
Единый источник знака — src/assets/brand.js (MA_BRAND). Перерисовывать запрещено: любая поверхность (страница, лендинг, favicon, письмо) берёт ICON_SVG / ICON_SHORT_SVG / WORDMARK_HTML отсюда. Ниже — знак в обеих темах ОДНОВРЕМЕННО (без переключения), в полной и компактной форме.
- Код:
MA_BRAND.ICON_SVG— полный знак;MA_BRAND.ICON_SHORT_SVG— компактный «МА»;MA_BRAND.WORDMARK_HTML— вордмарк. Источник —src/assets/brand.js. Брать оттуда, НЕ рисовать заново. - Цвета знака (фикс., одинаковы в обеих темах):
#5b6ef5бренд ·#8b5cf6градиент ·#34d96bлиния роста. - Бренд-синий vs UI-акцент (канон 2026-06-07). «Ассист» в вордмарке =
var(--brand)=#5b6ef5— ЕДИНЫЙ бренд-синий, совпадает со знаком, фикс. в обеих темах. «Маркетплейс» =var(--text)(нейтральный, адаптируется к фону для читаемости). UI-акцентvar(--accent)(#2563ebсветлая /#6e80f7тёмная) — ОТДЕЛЬНЫЙ токен для кнопок/ссылок (тюнингуется под контраст по теме). Логотип НЕ использует--accent. - Запрещено: старый «4-квадратный» знак; перекрашивать знак под тему; растягивать непропорционально; менять ₽-медальон.
- Центральный реестр ВСЕХ брендов (имя / цвета / адрес / где лежит лого + прямые ссылки):
Bitrix24-www/brands/. Подхват в сессии — скиллbrand-registry(по словам «логотип / бренд»). - Этот раздел
/design-system/#brand— визуальный эталон знака МА (прямая ссылка для других сессий и реестра).
Основы
Палитра
Все цвета — только через CSS-переменные из theme.css. Хардкод HEX в коде продукта запрещён.
data-theme="dark"data-theme="light"Типографика
Системный шрифт: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif.
Базовый размер: 15px (body), 13px для элементов UI.
Правило h1: в заголовке страницы — 20px (page-header); в диалоге/блоке — 18px; в общем тексте — 22px (.h1 helper).
--accent: #6e80f7 / var(--space-4)Сетка и отступы
8pt-сетка: все отступы кратны 4px. Ритм форм: label→control 8px (--space-2), между полями 16px (--space-4).
Радиусы и тени
Правило таблиц: AG Grid / data-таблицы — flush (radius 0). Карточки, поповеры, модалки — --radius-md или --radius-lg.
Компоненты
Кнопки
Классы из base.css:181. Один размер по умолчанию, модификаторы .btn-sm / .btn-lg.
base.css не задаёт явный :disabled стиль. Предложенный стандарт: opacity: 0.5; cursor: not-allowed; pointer-events: none;
— применяется через .ds-hover-demo в этой спеке как демонстрация. Применить глобально в base.css.
Переключатели и ползунки
Сегментный контрол существует (base.css:227). Switch-тогл и range-ползунок — ПРЕДЛОЖЕННЫЙ СТАНДАРТ (в продукте отсутствуют).
.btn-group .btn-toggle существующийИнпуты и формы
Классы из base.css:249. Ритм формы: метка → контрол 8px; между полями 16px.
.input.input-sm.select:focusКарточки и KPI
Два класса: .kpi-card (base.css:142, примитив) и .kc-card (kpi-card.js/css, компонент с состояниями).
.kpi-card — CSS-примитив, .kc-card — JS-компонент (state/loading/trend/href). Рекомендация: консолидировать на .kc-card (через KPICard.create), удалить прямое использование .kpi-card. Отметить как P2 бэклог.
border-radius: var(--radius-md); border: 1px solid var(--border)
.card-clickable — cursor pointer, translateY(-1px) hover
Бейджи и статусы
base.css:369app-sidebar.js:486base.css:348Тулбар-кнопки
Канон — src/analytics/styles.css:192. Сегодня page-specific — каждая страница переопределяет.
Здесь документируется как стандарт портала.
.tb-btn / .tb-btn-icon / .tb-link-btn / .tb-gbtn в src/assets/base.css или отдельный toolbar.css. Сейчас каждая страница копирует ~80 строк CSS.
Тосты и алерты
.alert-warn.alert-error.alert-info
Тосты (error-toast.js): авто-дисмисс, стеками вверх-справа. Тип error / warning / info.
Нет собственных классов — inline-стили (технический долг, кандидат на рефакторинг под .alert-*).
Таблицы — AG Grid Community 32.3.3
Один табличный движок на весь портал. Эталон: src/analytics/ma-aggrid.js. Таблица на всю ширину; режим/возможность выбирается выпадающим списком над таблицей.
Лёгкие таблицы дашборда — упрощённый грид (без тулбара)
Решение (2026-06-07, по логике проекта): дашбордные SKU-таблицы — это ТОТ ЖЕ движок AG Grid, просто в УПРОЩЁННОМ режиме (без тулбара, минимум колонок, фикс. короткий список). Не плодим отдельные виджеты — один табличный движок на всё, меняется только конфигурация. Это снимает разнобой и техдолг.
- Полный грид — данные селлера: тулбар, сортировка / фильтр / группировка, виртуализация, Σ Итого. Эталон:
/analytics/,/pricing/. - Упрощённый грид (БЕЗ тулбара) — дашборд: фикс. короткий список (топ-5/10), product-ячейка (фото + название + SKU) + метрики. Тот же AG Grid, конфиг минимальный (без тулбара, без фильтров, autoHeight). Сюда переезжают «Самые прибыльные/убыточные» и сводка категорий.
- Презентационная
<table data-adr-0002-exempt>— ТОЛЬКО крошечная статика (2–4 строки, без данных селлера, без интерактива), где движок реально избыточен (напр. справочная таблица в модалке).
.top-item, легаси) → канон: упрощённый грид выше. Мигрировать.<table data-adr-0002-exempt> — статическая сводка| Категория | Товаров | Ср. маржа | На складе |
|---|---|---|---|
| Дом и сад | 142 | 19,4% | 3 210 |
| Рукоделие | 86 | 24,1% | 1 740 |
| Декор | 53 | 12,8% | 920 |
.top-item — мигрировать на упрощённый гридПаттерны
Шапка страницы (page-shell)
Канон из page-shell.css. Классы: .biz-panel / .biz-row / .header-period / .hs-accent / .hs-accent.pos / .hs-accent.neg.
Контрол периода — канонное расположение
Эталон: src/analytics/ — 2-я строка, слева. Страницы с контролем справа-вверху (returns, advertising) — отклонение. Подробнее в Антипаттернах.
MA_Format — единственный способ форматирования чисел
window.MA_Format.fmt(n, opts) из format-utils.js.
Никаких локальных function fmt() в page-specific коде.
Порядок кнопок тулбара и правило «compact ON по умолчанию»
Canonical order: [режим] [свернуть] [Компакт✓] [Тепловая] [Σ Итого] [настройки⚙] | [Сбросить] [CSV/Excel].
Компактный вид должен быть включён по умолчанию на всех страницах с AG Grid (analytics ✓, pricing ✓, my-expenses ✓; returns ✗, advertising ✗ — отклонение).
Антипаттерны
Реальные расхождения из аудита 2026-06-04. Каждый — доказательство из кода (файл:строка).
aggrid-theme.css:56--ag-wrapper-border-radius: 8pxaggrid-theme.css:56:--ag-wrapper-border-radius: 0pxОдна правка в shared-файле → все страницы.
Карточки / поповеры / модалки —
var(--radius-md).
src/returns/index.html:~40src/advertising/index.html:~38Селлер переключается между страницами — период «прыгает».
src/analytics/ — строка 2, слева.Правило: период всегда в 2-й строке шапки, первый элемент слева.
Применить на returns и advertising при следующем рефакторинге шапки.
src/returns/returns.jssrc/advertising/advertising.js
Строка 34px → 26px + скрытие фото-колонок.
Правка: инициализировать
compact: true в начальном состоянии тулбара.
.tb-full / .tb-compact) на analytics/pricing, но плоский текст на returns/advertising.⚙ Настройки отсутствует на returns, advertising.«Группировка» на advertising vs «По группам» на others.
Адаптивные спаны — на всех страницах.
⚙ Настройки — присутствует на всех страницах с колонками.Canonical labels: «☰ Компакт», «≡ По группам», «⊡ Свернуть».
title= и без hover-тултипа.kpi-card.js/css: нет title в записи инвентаря.Селлер видит число — не знает, что с ним делать и как оно связано с другими.
(1) что означает эта метрика,
(2) как она вычислена,
(3) прямые взаимосвязи (на что влияет).
Реализация:
title= на .kc-card + headerTooltip на AG Grid-колонках.
background: rgba(110,128,247,0.3), color: #ef4444.Два класса KPI:
.kpi-card (base.css) и .kc-card (kpi-card.js) — дублируют структуру.
var(--accent-light), var(--error) и т.д.Канонный KPI-компонент:
KPICard.create() (kpi-card.js) → state/loading/trend/href.Прямое
.kpi-card — только для presentational демо. Долг: убрать дубль.
Чеклисты QA и Definition of Done
Обязательные проверки перед каждым мержем UI-изменений.
- Метка → контрол: ровно 8px (
--space-2) - Между полями формы: 16px (
--space-4) - Нет перекрытий label / input на любом viewport
- Шрифт инпутов/кнопок:
font-family: inherit
- AG Grid radius = 0 (flush, не скруглён)
- Одна горизонтальная полоса прокрутки
- Compact ON по умолчанию
- Σ Итого — серверный summary, не пересчёт клиента
- Нет manual
<table>безdata-adr-0002-exempt
- Каждая колонка AG Grid:
headerTooltip - Каждая KPI-карточка:
titleс метрикой + взаимосвязями - Тултип = «что это» + «как считается» + «что делать»
- Иконки с семантикой:
titleилиaria-label
- 2-я строка шапки, левый элемент
- Канон: как в
src/analytics/ - Не в верхней строке; не справа от h1
- Один лейбл на одну функцию во всём портале
- ⚙ Настройки есть на всех страницах с колонками
- Адаптивные спаны (
.tb-full / .tb-compact) везде - disabled: opacity 0.5, cursor not-allowed
- Нет хардкода HEX в production CSS
- Только
var(--name)из theme.css - Обе темы (dark + light) визуально корректны
- MA_Format для всех числовых значений
- Переключить data-theme в CDT — нет «белых пятен»
- Иконки/свг читаемы в обеих темах
- Токены контраста: --text на --bg ≥ 4.5:1
- Все числа через
window.MA_Format.fmt() - Нет локальных
function fmt(n) - null → «—», не «0» или пустая строка
- T1-сверка: итог = Σ строк (до копейки)
Принятие решений / Утверждения
Живой реестр: что выбрали, к чему пришли и почему. Через него отбираем все элементы портала и приводим сайт к единому виду. Наполнение — на PL.
Тулбар и призмы
Решения от 29.07.2026 по панели над таблицей и строке призм. Первая половина — уже принятое,
отрисованное боевыми контролами: их не выбирают, на них смотрят и по ним делают. Вторая — развилки,
каждая в рамке «варианты — отметить один», каждый вариант — настоящая строка, а не описание словами.
Отметки сохраняются в браузере. Документ-первоисточник —
docs/design-system/DECISIONS-toolbar-and-prisms-2026-07-29.md.
Принято
1 · Тулбар: зоны и порядок принято
Движковые кнопки (те, что работают одинаково в любом разделе) — пиктограммы 28×28 с подсказкой.
Кнопки со смыслом только своего раздела остаются словами и живут в своей строке над таблицей.
Порядок зон: строки, колонки, поиск (забирает всё свободное место), что видно и как подкрашено, выгрузки и настройки.
Панель ниже собрана из боевых знаков движка: «Перенос строк» в зоне строк взята из каталога
MA_TableShell.TOOLBAR_ICONS, а не перерисована здесь второй раз.
2 · Форма кнопки и защита от случайного щелчка принято
Значок — жёсткий квадрат 28×28, включение меняет ТОЛЬКО заливку: ширина кнопки не зависит от состояния. Проверка встроена в блок — кнопка ниже щёлкает все кнопки панели и сравнивает ширины до и после.
Действие ≠ переключатель
«Колонки по умолчанию», «Сжать колонки», «Сбросить фильтры» не имеют состояния «включено» — они никогда не подсвечиваются акцентом. Защита разная по весу последствий: окно подтверждения там, где теряется настроенное вручную и вернуть нечем; сообщение с «вернуть как было» — там, где потеря мелкая и частая.
Где селлер может потерять свою настройку
3 · Подсказки: единый формат и переименования принято
Формат один для всех: Название. Что делает и за счёт чего. Первое слово подсказки = название кнопки, дальше объяснение словами селлера. Наведите на любой знак в карточках ниже — увидите ровно тот текст, который уйдёт в код.
4 · Знаки кнопок выбраны, кроме «Цены»
Пиктограммы приняты как форма; знаки выбраны — щелчок по варианту меняет отметку и сохраняет её. Стрелки скачивания и обмена — одно семейство: общий лоток, одинаковая длина стержня и головы. Единственный неутверждённый знак — у кнопки «Цены»: он поедет вместе с её именем, развилка ниже.
5 · Строка призм принято
Собрано ровно из выбранных 29.07 осей: невыбранные призмы получают лёгкую заливку (видно, что это кнопки); режимы общих расходов живут внутри кнопки «Прогноз» на приглушённой подложке; кнопка не раскрывается и не сжимается — ширина постоянная, при другой призме режимы просто приглушаются; расшифровка — подсказка на каждом режиме плюс знак на полное окно; предупреждение о незакрытом периоде — жёлтая капсула в конце той же строки.
Что это заменяет
Было: строка призм плюс отдельная жёлтая плашка-баннер под ней. Плашка уходит внутрь строки, таблице возвращается её высота.
Объяснение режимов — на числах
Открывается по знаку в строке призм. Итог периода одинаков в обоих режимах — меняется только раскладка.
6 · Канон строки режимов принято
Одна строка держит разнородное: режимы разбивки (по SKU / по заказам / по склейкам), кнопку состояния «Ожидают», оси-сегменты («Числа», «Отгрузка»), фильтры конкретного раздела («Реклама») и вход в «Сводку». Канон один для всех разделов: слева режимы и состояние, затем оси в порядке «Числа», «Отгрузка», раздел-специфичные, «Сводка» прижата вправо. Слово-подпись оси уходит целиком, остаётся только знак справки — и он стоит ПОСЛЕ сегмента, ровно так же, как в строке призм.
7 · Чем помечаем новинку выкачено
Было — звёздочки-искры: опознавательный знак AI-генерации, на нём продукт читается как сделанный машиной.
Стало — флажок-вымпел: знак отметки-вехи, «здесь появилось что-то, на что стоит взглянуть».
Знак уже в коде и рисуется одним источником — MA_Glyphs.newFeature()
из src/assets/ma-glyphs.js; четыре прежние копии убраны.
8 · Индикация загрузки и потолок ожидания сделано 30.07
Процентов нет намеренно: страница шлёт один запрос и не знает, что сервер уже успел сделать.
Шкала, застрявшая на 80 %, хуже честного счётчика секунд. Показываем три факта, которые страница действительно знает,
плюс бегущую полосу и счётчик.
🔴 Главное — не картинка, а потолок. До этой правки ограничения по времени не было вовсе: обрыв срабатывал,
только когда селлер сам запускал новый запрос. Молчащий сервер = вечное ожидание. Теперь через 3 минуты запрос
обрывается и селлеру предлагается выход.
Кнопки ниже показывают настоящую панель — тот же код, что на боевых страницах
(src/assets/ma-load-progress.js). Потолок в показе укорочен до 6 секунд, чтобы не ждать три минуты.
Замер на боевых данных (1714 товаров): месяц — 1,7–3,3 с, год — 13 с, 2,5 года — 13–15 с. Поэтому подсказка кнопки говорит «до одной минуты», а не «до нескольких минут»: прежняя формулировка замером не подтвердилась.
Развилки — ждут решения
9 · Строка «ИТОГО», когда включён фильтр или поиск ждёт решения
Сейчас строка «ИТОГО» всегда показывает весь период. Селлер отбирает 128 товаров из 428, смотрит вниз — и видит цифру, которая к отобранному не относится. Ни подписи, ни признака, что это не про них.
Варианты — отметить один
10 · Кнопка «Цены»: имя, поведение и ограничение ждёт решения
Проверено в коде src/pricing/pricing-ag.js: на Wildberries кнопка видна,
но выключена с подсказкой «Пока только для Ozon» (строка 672), и обработчик закрывает вход повторно (строка 5946).
Механизм заполнения ищет колонку шаблона Ozon «Новая цена (со скидкой)» — пути для WB в коде нет вовсе.
Значит, нейтральное имя «Цены» обещает больше, чем кнопка умеет. Вместе с именем едет и знак — он единственный неутверждённый.
Варианты — отметить один
11 · Стрелки «Excel» и «Цены» — одно семейство или два ждёт решения
Продолжение развилки 10 — про сам знак. Решение 29.07 говорит: «стрелки скачивания и обмена —
одно семейство: общий лоток, одинаковая длина стержня и головы». Замер 30.07 показал, что семейства нет.
Лоток у обоих знаков действительно один и тот же путь, а дальше расходятся: у «Excel» стержень 12 единиц
и голова 5, у «Цен» — стержень 9 и голова 3.5. Обе кнопки стоят вплотную в правой группе «Экономики»,
поэтому разница видна без всякого сравнения. Числа под каждым вариантом — замеренные браузером
(длина штриха берётся у самого пути), а не выписанные на глаз; рисунок и таблица собираются из одних и тех же
чисел, поэтому разойтись не могут. Первоисточник замера —
docs/audit/_evidence/toolbar-buttons-conformance-2026-07-30.md, пункт D6.
download библиотеки
Lucide, из которой взят весь набор значков портала. То есть чужеродная в паре — стрелка обмена,
и вопрос ровно один: подтянуть её к «Excel» числом в число (вариант А) или по правилу самой библиотеки,
которая при двух стрелках уменьшает голову (вариант Б).
Варианты — отметить один
12 · «Сжать колонки» делает разное на разных страницах ждёт решения
Одна кнопка, один знак, одна подсказка — и два несовпадающих поведения. Проверено чтением кода:
в «Аналитике» она возвращает объявленные ширины из определения колонок
(analytics/ma-aggrid.js, compactCols), а в «Экономике»,
«Возвратах», «Рекламе» и «Моих расходах» — растягивает колонки так, чтобы они заняли ровно ширину экрана
(sizeColumnsToFit). На узкой таблице второе поведение колонки не сжимает, а раздувает.
Варианты — отметить один
13 · Видимый признак включённых фильтров ждёт решения
По решению 29.07 «Сбросить фильтры» — кнопка-действие, и акцентом она больше не подсвечивается.
Сигнал «сейчас что-то отфильтровано» переехал в текст подсказки (analytics/ma-aggrid.js,
onFilterChanged). Но чтобы прочитать подсказку, надо навести курсор именно на ту кнопку,
о существовании которой селлер и не подозревает: строка отфильтрована, итог не сходится с ожидаемым, а почему — не видно.
Нужен признак, который заметен без наведения и при этом не спорит с правилом «акцент = включено».
Варианты — отметить один
14 · Три мелких — по подсказкам и поведению ждут решения
Каждая мелочь проверена в коде и стоит отдельного «да / нет»: они не связаны друг с другом и могут разъехаться по разным волнам.
Инвентарь контролов
Всё, что живёт на грид-страницах помимо тулбара и призм — отрисовано боевыми классами, на том фоне,
где реально стоит. Жёлтая метка нет подсказки означает: у контрола нет ни
title, ни другого объяснения при наведении — селлер догадывается сам. Проверено чтением кода, а не на глаз.
Что осталось до беты
Живой список: решённое из него уходит, открытое остаётся с указанием, где смотреть.
Источники дизайна (картотека)
Где смотреть идеи — человеческий дизайн, без AI-slop, только бесплатное (Запад + Азия). Берём идею, не обязательно готовый кирпич. Полный список (38 ресурсов) → docs/design-system/sources-catalog-2026-06-05.md. Правила — GLOBAL_DESIGN.md; сохранённые эффекты — effects-catalog/.
Иконки
Стандарт
Векторные иконки Lucide — уже используются в сайдбаре (app-sidebar.js → ICONS).
Рендерятся как inline SVG: сетка 24×24, stroke 2px, цвет currentColor (наследует цвет текста, работает в обеих темах без правок).
Размер управляется атрибутами width/height.
Кастомные формы — только под бренд-знак (₽, MA_BRAND §14 канон).
Наш набор (живой рендер)
Все иконки из app-sidebar.js ICONS + часто используемые Lucide. Цвет — currentColor: переключите тему кнопкой в шапке — иконки перекрасятся автоматически.
Миграционная таблица: эмодзи → Lucide
Плановая замена эмодзи в тулбарах. Причины — в блоке «Антипаттерн» ниже.
Антипаттерн — эмодзи вместо иконок
💾 CSV, 🌡 Тепловая,
Σ Итого, ☰ Компакт,
⚙ Настройки, ⊡ Свернуть,
☑ Выбрать- Рендер зависит от ОС: Windows ≠ Mac ≠ Android
- Не масштабируются с текстом (растровые при zoom)
- Нет вариантов темы (всегда цветные/чёрные OS-цвета)
- AI-паттерн — сигнал сгенерированного интерфейса
- Нет
aria-label— ломает a11y для screen readers
<button>[svg save] CSV</button>- Одинаковы на всех ОС (векторные)
- Масштабируются без артефактов
currentColor— меняют цвет вместе с текстом в обеих темах- Выглядят как профессиональный B2B SaaS
- Добавить
aria-labelна кнопку — a11y готова
Свечение карточек (ореол)
Деликатный световой контур по периметру карточки — мягкий отклик на наведение,
premium-ощущение (как у Vercel/Cursor), не неон. Чистый CSS:
контур в покое + усиление на hover работают без JS; нюанс «ярче у курсора» —
крошечный внешний /assets/glow-card.js (CSP-safe).
Цвет — токены var(--accent) / var(--brand), обе темы.
Реализация — общий /assets/glow-card.css (класс .glow-card).
.glow-card ещё НЕ применён к боевым карточкам портала.
После выбора Александра — раскатаем на KPI / insight / .biz-panel / топ-листы / дашборд-карточки (Rule of Three → shared).
Контракт компонента
Раскрытие описаний
Индикатор «развернуть/свернуть» для блоков «Про раздел» (MA_HelpSection),
аккордеонов, раскрытия строк. Индикатор — векторная Lucide (никаких литеральных «▼»/«→» —
это AI-tell). Плавное раскрытие по высоте/прозрачности, тайминг — токенный, reduced-motion уважается.
MA_HelpSection ещё НЕ меняли — это витрина вариантов.
Письма
Галерея email-шаблонов — 8 типов писем с live-превью в iframe. Канон: Вариант A·Stripe 600px, тёмный режим, feedback-invite.
Шаблоны в api/email-service.js (движок) + api/email-templates/ (HTML-файлы).
Живая галерея (8 типов) открывается на отдельной странице — iframe-превью 600px, sample-данные, подписи subject + preheader.
Открыть галерею писемТерминология
Единый словарь концептов с деньгами и расчётами. Источник:
docs/design-system/terminology-dictionary-draft-2026-06-11.md.
Программный синоним: src/assets/glossary.js → window.MA_Glossary.
Один концепт = одно имя везде: колонка == плитка == тултип == дрилл-даун.
Словарь универсальный: в разделах A–D используется нейтральное слово
«маркетплейс» (концепты есть на любом маркетплейсе). Термины, характерные только для
конкретного маркетплейса, вынесены в раздел E — только там в описании назван конкретный
маркетплейс. У каждого термина — «Где» (где применяется) и «Зачем селлеру» (почему важен).
Плитки разделов /overview/ — редизайн
Три направления без AI-tell'ов: убрана 3px левая полоса + литеральная «→».
Цвет раздела сохранён (через чип/иконку/dot/верхний бордер). Иконки = Lucide, ровно как в сайдбаре.
Спецификация: docs/specs/overview-section-tile-redesign-2026-06-27.md.
Кнопка «Сделать приятное»
Портальная кнопка поддержки проекта (будущий «кофе / тортик»). В проде 3 выбранных варианта будут чередоваться по времени суток автоматически. Отметьте 3 понравившихся — маппинг по часам утвердим вместе.