# Дизайн-код админки СКН

Версия 1.1, 2 ноября 2026. Область действия — `/adminka`.

Публичная документация разработчика: [sakonews.ru/design/?doc=admin](https://sakonews.ru/design/?doc=admin). Исходник доступен по адресу [sakonews.ru/docs/admin-design-code.md](https://sakonews.ru/docs/admin-design-code.md). Код публичного сайта опубликован отдельно в этом же справочнике.

## Характер и источник правил

«Графит»: редакционный рабочий инструмент с матовыми поверхностями, мягким светом и точным контуром. Тёмная тема — графит и светлый лаймовый акцент, светлая — бумажный фон и оливковый акцент. Декоративные градиенты и разноцветные эмоджи в интерфейсе не используются.

Канонические значения находятся в `manager/css/admin-design-system.css`, поведение — в `manager/js/admin-design-system.js`. Этот слой подключается после старых модулей. Зафиксированные `!important` в геометрии контролов — временный адаптер к историческим inline-стилям; новые компоненты используют токены и не добавляют локальных переопределений. При переносе старого компонента его дублирующие правила удаляются.

## Типографика и сетка

- Шрифт: локальный PT Sans. Поля, кнопки, таблицы и подписи наследуют один шрифт.
- Основной текст — 14 px / 1.5; поля — 14 px; кнопки — 13 px; подписи и вспомогательный текст — 12 px.
- H1 — 22 px / 1.2, 700; H2 — 20 px / 1.3; H3 — 16 px / 1.4. На телефоне H1 — 19 px.
- Базовый шаг — 4 px. Отступы: 4, 8, 12, 16, 24, 32 px. Горизонтальный отступ рабочей области — 24 px, на узких экранах — 16 / 12 px.
- Контейнер: фон `--ui-surface`, рамка `--ui-line` 1 px, радиус 10 px, внутренний отступ 24 px (16 px на телефоне). Сходные контейнеры не получают индивидуальных теней и скруглений.

## Хэдер — центр команд текущего раздела / сущности

Все разделы используют `templates/admin-header.tpl`. Высота — 88 px; на телефоне — 116 px с отдельной строкой команд. Добавление кнопок не меняет высоту хедера.

Слева: название и метаданные/статусы. Справа: возврат, просмотр, специальные действия, основное сохранение. Редактор не встраивает кнопки в H1. При длинной форме нижнее сохранение допустимо как повтор верхнего. Сворачивание навигации сохраняет хэдер доступным.

Контракт PHP:

```php
$pageTitle = 'Редактирование страницы';
$headerMeta = [['label' => 'Опубликована', 'class' => 'status-active']];
$headerActions = [
    ['url' => '/adminka?action=pages', 'label' => 'Назад', 'icon' => 'arrow-left', 'class' => 'btn'],
    ['type' => 'button', 'label' => 'Сохранить', 'icon' => 'save', 'class' => 'btn btn-primary',
     'attrs' => ['type' => 'submit', 'form' => 'page-form', 'name' => 'save_page', 'value' => '1']],
];
include __DIR__ . '/admin-header.tpl';
```

Дополнительно: `headerSubtitle`, `icon_only`, `optional_label`, `attrs`. HTML статуса разрешён только через явный `headerMeta[].html` из доверенного шаблона. Обычные подписи экранируются.

## Контролы и иерархия

| Элемент | Размер и назначение |
| --- | --- |
| Поле / select / кнопка формы | 40 px, радиус 7 px |
| Контрол списка | 32 px, радиус 8 px |
| Иконка | 20 px, сетка 24×24, контур 1.65 px |
| Основное действие | `.btn-primary`, акцентный фон |
| Второстепенное действие | `.btn`, матовая приподнятая поверхность |
| Опасное действие | `.btn-danger` / `.is-danger`, приглушённый красный |
| Иконка-действие списка | `.action-link` / `.icon-action`, без постоянной рамки |

В смысловой группе применяется один размер. Верхнее сохранение — единственная основная кнопка группы; AI-действия второстепенные. Текст кнопок не переносится. У иконки без видимой подписи обязательны `aria-label` и подсказка `title`.

Список воспринимается как матовая поверхность с отдельными зонами прикосновения: без ховера иконка спокойная, при наведении получает мягкое гнездо и светлый контур; при нажатии слегка утапливается. Цвет добавленной в очередь новости показывает состояние, а не декоративное отличие.

Single-select использует общий кастомный listbox. Исходный `select` сохраняет имя, значение, `required`, `disabled` и обработчики формы. Клавиши: стрелки, Home/End, Enter/Space, Escape, набор первых букв. Меню портируется в `body`, чтобы не обрезаться контейнером. Multiple/size-select, inline-редактор таблицы и явный `data-native-select` сохраняют специальное поведение.

## Состояния и подсветка

- Hover — изменение поверхности/контура; текст не прыгает, размер не меняется.
- Active — смещение 1 px и мягкая внутренняя тень; для списков дополнительно scale .96.
- Keyboard focus — акцентный контур 2 px с отступом 3 px. У поля — акцентная рамка и кольцо.
- Selected / expanded — акцентный текст и приглушённый акцентный фон. Выбранная строка подсвечена целиком.
- Disabled — opacity .4, запрет на анимацию нажатия.
- Ошибка — семантический красный плюс текст. Успех — зелёный, ожидание — янтарный, справка — голубой.
- Модалки — единый фон, радиус 14 px, отступ 24 px, тёмный backdrop с blur 6 px. Выпадающие меню — тот же набор токенов и тень.
- Анимации — 160–180 ms; `prefers-reduced-motion` отключает движение.

## Новости

- Фильтр закрыт при входе; кнопка-лупа находится в хэдере и показывает активность фильтров. Нажатие раскрывает панель под хэдером, повторное нажатие, Escape или клик вне панели закрывают её. Выбранные фильтры остаются в GET-параметрах.
- Поля и две кнопки фильтра составляют одну строку. На узком экране строка прокручивается горизонтально, без переноса отдельных кнопок.
- Панель массовых действий появляется снизу при выделении хотя бы одной новости, показывает счётчик и позволяет снять выбор. В пустом состоянии она не занимает рабочую область.
- Колонки «Дата» и «Подача» убраны из списка. «Добавлена» сохраняется. Даты и подача в данных не удаляются.

## Редактор новости

Общие компоненты дополняет `manager/css/admin-news-editor.css`. Это композиция существующих полей, а не отдельная визуальная тема.

- Основная вкладка: материал занимает большую колонку, параметры источника — меньшую; пропорция 2:1. Внутри каждой колонки поля выстраиваются по общей сетке без разрозненных локальных ширин.
- Название, описание и основной текст образуют последовательную редакционную группу. Даты и источник — самостоятельный служебный блок. Подписи и подсказки используют одни размеры и отступы.
- Вкладка подготовки делится на повествовательные поля и блок для подкаста. На узком экране все колонки переходят в одну в том же порядке.
- Галерея, формы добавления изображения/видео, хронология и журнал ИИ используют одинаковые поверхности, заголовки секций, контуры и шаги отступов.
- Превью медиа сохраняют соотношение сторон; служебные действия не перекрывают содержимое. Прогресс загрузки и выполнения ИИ использует семантические состояния общего дизайн-кода.
- При изменении раскладки сохраняются имена, идентификаторы, форма отправки, обработчики и содержимое полей.

## Иконки и развитие системы

Собственный набор SKN Cutline: `manager/assets/admin-icons.svg`, реестр и PHP helper — `manager/ui-icons.php`, JS — `manager/js/admin-icons.js`. См. `docs/admin-icons.md`. Новый символ добавляется в sprite и реестр, затем используется по смысловому ключу. Не заменять эмоджи в данных, текстах новостей и пользовательском вводе.

Новое правило сначала добавляется сюда и в общий компонент, затем применяется к разделам. Нельзя создавать локальный вариант уже существующей кнопки, подписи, статуса или контейнера без обоснованной новой роли.
