редизайн кнопок 1st version

This commit is contained in:
2026-06-01 02:41:28 +03:00
parent 30972db9ee
commit 3217586657
62 changed files with 1502 additions and 479 deletions

420
docs/BUTTON_STYLING_PLAN.md Normal file
View File

@@ -0,0 +1,420 @@
# План стилизации кнопок
Дата аудита: 01.06.2026
Среда аудита: `https://localhost`
Метод: визуальный обход через Playwright, фиксация скриншотов и computed styles.
## 1. Краткое резюме
Интерфейс уже имеет узнаваемую базу: тёмная админ-панель, фиолетовый акцент, компактные таблицы и отдельные публичные кабинеты преподавателя/студента. Главная проблема не в отдельных кнопках, а в отсутствии единого контракта между смыслом действия и его визуальным видом.
Сейчас одинаковые классы могут выглядеть по-разному в разных SPA, а одинаковые действия могут получать разные цвета, размеры и плотность. Из-за этого пользователь каждый раз заново считывает интерфейс: где главное действие, где безопасное второстепенное, а где рискованное.
Цель новой структуры: закрепить единую кнопку как системный компонент с понятными ролями, размерами и правилами использования.
## 2. Что было проверено
| Раздел | Проверенные сценарии | Скриншот |
|---|---|---|
| Авторизация | Вход, показ пароля, переключение темы | [`audit-buttons-01-login.png`](../audit-buttons-01-login.png) |
| Дашборд админки | Быстрые переходы, recheck, сайдбар | [`audit-buttons-02-dashboard.png`](../audit-buttons-02-dashboard.png) |
| Пользователи | Создание пользователя, архивирование | [`audit-buttons-03-users-form.png`](../audit-buttons-03-users-form.png) |
| Меню настроек | Выпадающее меню, выход, переход в настройки | [`audit-buttons-04-settings-menu.png`](../audit-buttons-04-settings-menu.png) |
| Настройки | Навигация отдельной SPA | [`audit-buttons-05-settings-general.png`](../audit-buttons-05-settings-general.png) |
| Кабинет преподавателя | Недели, сегодня, выход, тема | [`audit-buttons-06-teacher.png`](../audit-buttons-06-teacher.png) |
| Кабинет студента | Недели, сегодня, выход, тема | [`audit-buttons-07-student.png`](../audit-buttons-07-student.png) |
| Модальное окно | Создание ручной сетки, отмена, закрытие | [`audit-buttons-08-modal.png`](../audit-buttons-08-modal.png) |
Дополнительно были сохранены скриншоты отдельных разделов: календарный график, аудитории, группы, дисциплины, расписание, формы обучения, база данных, временные слоты.
## 3. Текущее состояние
### 3.1. Авторизация
![Экран авторизации](../audit-buttons-01-login.png)
Найдены кнопки:
| Кнопка | Текущая роль | Комментарий |
|---|---|---|
| `Войти` | Primary | Корректно считывается как главное действие экрана. |
| `Показать пароль` | Icon utility | Нужен единый icon-only стиль и обязательный `aria-label`. |
| `Переключить тему` | Icon utility | Отличается от такой же кнопки в кабинетах преподавателя и студента. |
Вывод: экран логина близок к правильной иерархии, но icon-only controls нужно привести к общей форме и размеру.
### 3.2. Дашборд админки
![Дашборд админки](../audit-buttons-02-dashboard.png)
Найдены кнопки и ссылки-кнопки:
| Кнопка | Текущий вид | Проблема |
|---|---|---|
| `Конструктор расписания` | Primary link | Хороший кандидат на основной CTA блока. |
| `Точечные изменения / Просмотр` | Secondary link | Выглядит как второстепенное действие, это корректно. |
| `Перепроверить` | `btn-primary`, маленькая высота | Primary используется для сервисного действия, хотя это не главное действие страницы. |
| `Настройки` | Sidebar button | Визуально близко к навигации, но реализовано как кнопка. |
| `Переключить тему` | Круглая icon button | Отличается от публичных кабинетов. |
Основной вывод: `btn-primary` сейчас означает и главный CTA, и компактную служебную кнопку. Это размывает иерархию.
### 3.3. Формы и таблицы админки
![Форма пользователей](../audit-buttons-03-users-form.png)
Типичные кнопки:
| Кнопка | Смысл | Текущее впечатление |
|---|---|---|
| `Создать` | Подтверждение формы | Главная кнопка, но размер и стиль отличаются между основной админкой и настройками. |
| `Архивировать` | Рискованное, но часто обратимое действие | Визуально слишком близко к удалению. |
| `Изменить` | Второстепенное действие строки | В разных разделах бывает фиолетовой или нейтральной. |
| `Удалить` | Деструктивное действие | Встречается в разных размерах и оттенках красного. |
Проблема: таблицы используют кнопки как плотный action bar, но размеры скачут от `24x28` до `113x28` и `96x40`. Это создаёт визуальный шум в строках.
### 3.4. Меню настроек и выход
![Меню настроек](../audit-buttons-04-settings-menu.png)
Кнопка `Выйти` находится рядом с навигационными пунктами и выглядит почти как обычный пункт меню. Семантически это сессионное действие с риском потерять текущий контекст, поэтому ему нужен отдельный quiet-danger стиль.
Рекомендация: `Выйти` не должен выглядеть как обычная навигация. Достаточно `Danger subtle`: красный текст на спокойной поверхности без агрессивной заливки.
### 3.5. Отдельная SPA настроек
![Общие настройки](../audit-buttons-05-settings-general.png)
В настройках виден тот же сайдбарный паттерн, но кнопки внутри разделов получают другую визуальную систему.
Пример различий:
| Класс | Основная админка | Настройки |
|---|---|---|
| `btn-primary` | Часто прозрачный фон, белый текст, визуальная заливка может приходить из другого слоя | Фиолетовая заливка `rgb(139, 92, 246)`, высота `40px`, жирность `700` |
| `btn-delete` | Красный tint, высота часто `28px`, font-weight `400` | Красный tint, высота `40px`, font-weight `700` |
| `btn-secondary` | Фиолетовый tint или светлая surface-кнопка | Нейтральная surface-кнопка |
Вывод: одинаковое имя класса не является дизайн-контрактом. Компонент кнопки нужно нормализовать на уровне токенов и модификаторов.
### 3.6. Кабинеты преподавателя и студента
![Кабинет преподавателя](../audit-buttons-06-teacher.png)
![Кабинет студента](../audit-buttons-07-student.png)
В публичных кабинетах используется отдельная светлая система:
| Элемент | Преподаватель | Студент |
|---|---|---|
| `Сегодня` | Primary blue `rgb(29, 78, 216)` | Primary teal `rgb(15, 118, 110)` |
| `Выйти` | Outline, белый фон, radius `8px` | Outline, белый фон, radius `8px` |
| `` / `` | Outline icon-like buttons | Outline icon-like buttons |
| `Переключить тему` | Текстовый символ `◐` | Текстовый символ `◐` |
Проблема: одно действие `Сегодня` меняет цвет в зависимости от кабинета. Это допустимо для брендинга ролей, но плохо для системных кнопок. Ролевые цвета лучше использовать в расписании, бейджах и карточках, а не в базовой кнопочной иерархии.
### 3.7. Модальные окна
![Модальное окно создания ручной сетки](../audit-buttons-08-modal.png)
Найдены:
| Кнопка | Роль | Рекомендация |
|---|---|---|
| `Создать сетку` | Primary | Оставить primary. |
| `Отмена` | Secondary/Ghost | Сделать ghost или secondary без акцента. |
| `Закрыть` (`×`) | Icon close | Привести к icon-only button `40x40` или `36x36`, с `aria-label="Закрыть"`. |
Модальная структура в целом правильная, но её нужно подчинить тем же токенам, что и остальные кнопки.
## 4. Семантическая группировка найденных кнопок
### Primary: главное действие
Примеры: `Войти`, `Создать`, `Добавить`, `Сохранить правило`, `Сохранить год`, `Сохранить семестр`, `Сохранить график`, `Сохранить сетку`, `Сохранить слот`, `Создать сетку`.
Правило: одна primary-кнопка на форму, модальное окно или смысловой блок. Если на экране несколько форм, primary может быть в каждой форме, но не должна превращаться в оформление всех кнопок подряд.
### Secondary: обычное второстепенное действие
Примеры: `Изменить`, `Обновить`, `Показать`, `Тест`, `Сменить статус`, `Преподаватели`, `Загрузить сетку`, `Заполнить диапазон`.
Правило: использовать для действий, которые помогают выполнить задачу, но не являются главным подтверждением.
### Tertiary / Ghost: тихое действие
Примеры: `Очистить`, `Очистить форму`, `Отмена`, `Назад в панель`, `Свернуть`, `Из формы`, `Все`, `Точечные изменения / Просмотр`.
Правило: использовать там, где действие должно быть доступно, но не конкурировать с сохранением или созданием.
### Danger: деструктивное действие
Примеры: `Удалить`.
Правило: только для необратимых или почти необратимых операций. Красный цвет должен быть зарезервирован именно под риск.
### Danger subtle: рискованное, но не удаление
Примеры: `Архив`, `Архивировать`, `Удалить сетку`, `Выйти`.
Правило: использовать для действий с негативным или сессионным эффектом, но без визуальной паники solid-red кнопки.
### Icon button: компактное служебное действие
Примеры: `Переключить тему`, `Показать пароль`, `Скрыть панель`, `Закрыть`, ``, ``.
Правило: фиксированный квадратный размер, единое состояние hover/focus, обязательный доступный текст через `aria-label`.
### Navigation item: навигация, а не кнопка действия
Примеры: пункты сайдбара `Дашборд`, `Конструктор правил`, `Календарный график`, `Пользователи`, `Общие настройки`.
Правило: не смешивать навигацию с action button. У неё отдельные active, hover и focus-состояния.
## 5. Предлагаемая дизайн-система кнопок
### 5.1. Токены
| Токен | Светлая тема | Тёмная тема | Назначение |
|---|---|---|---|
| `--button-primary-bg` | `#4F46E5` | `#8B5CF6` | Основное действие |
| `--button-primary-bg-hover` | `#4338CA` | `#7C3AED` | Hover primary |
| `--button-primary-text` | `#FFFFFF` | `#FFFFFF` | Текст primary |
| `--button-secondary-bg` | `#FFFFFF` | `rgba(255,255,255,0.04)` | Второстепенная поверхность |
| `--button-secondary-bg-hover` | `#F1F5F9` | `rgba(255,255,255,0.08)` | Hover secondary |
| `--button-secondary-border` | `#CBD5E1` | `rgba(255,255,255,0.10)` | Граница secondary |
| `--button-secondary-text` | `#334155` | `#F8FAFC` | Текст secondary |
| `--button-ghost-bg-hover` | `#F8FAFC` | `rgba(255,255,255,0.06)` | Hover ghost |
| `--button-danger-bg` | `#DC2626` | `#DC2626` | Удаление |
| `--button-danger-bg-hover` | `#B91C1C` | `#B91C1C` | Hover удаления |
| `--button-danger-subtle-bg` | `#FEF2F2` | `rgba(239,68,68,0.13)` | Риск без solid-заливки |
| `--button-danger-subtle-text` | `#B91C1C` | `#FECACA` | Текст risk subtle |
| `--button-focus-ring` | `rgba(79,70,229,0.35)` | `rgba(139,92,246,0.45)` | Focus outline |
Примечание: для всего продукта лучше выбрать один primary-акцент. Для текущей тёмной админки логично оставить фиолетовый `#8B5CF6`, а для светлой темы использовать более читаемый `#4F46E5`. Ролевые цвета преподавателя и студента лучше вынести из кнопок в расписание и бейджи.
### 5.2. Размеры
| Размер | Высота | Padding | Шрифт | Где применять |
|---|---:|---|---|---|
| `sm` | `32px` | `0 12px` | `13px / 600` | Таблицы, компактные действия строк |
| `md` | `40px` | `0 16px` | `14px / 600` | Формы, фильтры, модальные окна |
| `lg` | `48px` | `0 20px` | `15px / 700` | Вход, главный CTA экрана |
| `icon-sm` | `32x32` | `0` | icon `18px` | Табличные иконки |
| `icon-md` | `40x40` | `0` | icon `20px` | Верхние панели, модалки, навигация недель |
Базовый `border-radius`: `8px`.
Почему `8px`: интерфейс административный и рабочий. Радиус `8px` сохраняет мягкость, но выглядит собраннее, чем повсеместные `10px`, особенно в таблицах и плотных формах.
### 5.3. Варианты
#### Primary
Использовать для главного подтверждения.
| Состояние | Стиль |
|---|---|
| Default | Фон primary, белый текст, без видимой границы |
| Hover | Фон темнее на 8-12% |
| Focus | Видимый ring `2px` |
| Disabled | Нейтральный фон, muted-текст, `cursor: not-allowed` |
Примеры: `Войти`, `Создать`, `Сохранить правило`, `Создать сетку`.
#### Secondary
Использовать для обычных действий рядом с primary.
| Состояние | Стиль |
|---|---|
| Default | Surface-фон, тонкая граница, основной текст |
| Hover | Чуть более светлая/контрастная поверхность |
| Focus | Такой же focus ring, как у primary |
| Disabled | Opacity `0.5` |
Примеры: `Изменить`, `Обновить`, `Показать`, `Тест`.
#### Ghost
Использовать для тихих действий.
| Состояние | Стиль |
|---|---|
| Default | Прозрачный фон, muted/regular text |
| Hover | Лёгкий surface-hover |
| Focus | Ring без изменения иерархии |
Примеры: `Отмена`, `Очистить`, `Назад в панель`, `Свернуть`.
#### Danger
Использовать только для удаления.
| Состояние | Стиль |
|---|---|
| Default | Красная заливка, белый текст |
| Hover | Более тёмный красный |
| Focus | Красный или общий focus ring |
Примеры: `Удалить`.
#### Danger subtle
Использовать для рискованных действий без полного удаления.
| Состояние | Стиль |
|---|---|
| Default | Красный tint-фон, красный текст, мягкая border |
| Hover | Более насыщенный tint |
| Focus | Видимый ring |
Примеры: `Архивировать`, `Архив`, `Выйти`, `Удалить сетку`.
#### Icon button
Использовать для действий, где текст заменён иконкой.
| Параметр | Правило |
|---|---|
| Размер | `32x32` в таблицах, `40x40` в тулбарах |
| Иконка | 18-20px, один набор иконок |
| Текст | Только через `aria-label` |
| Форма | Квадрат с radius `8px`, не круг, кроме специальных случаев avatar/fab |
Примеры: `Переключить тему`, `Показать пароль`, `Закрыть`, `Предыдущая неделя`, `Следующая неделя`.
## 6. Маппинг текущих кнопок на новую систему
| Текущие кнопки | Новый тип | Размер |
|---|---|---|
| `Войти` | `Primary` | `lg` |
| `Создать`, `Добавить` | `Primary` | `md` |
| `Сохранить правило`, `Сохранить год`, `Сохранить семестр`, `Сохранить график`, `Сохранить сетку`, `Сохранить слот` | `Primary` | `md` |
| `Создать сетку` | `Primary` | `md` |
| `Изменить`, `Обновить`, `Показать`, `Тест`, `Сменить статус` | `Secondary` | `sm` в таблицах, `md` в формах |
| `Преподаватели`, `Подгруппы`, `Календарь`, `Сетка` | `Secondary` | `sm` |
| `Очистить`, `Очистить форму`, `Отмена`, `Свернуть`, `Из формы`, `Все` | `Ghost` | `sm` или `md` |
| `Точечные изменения / Просмотр`, `Назад в панель` | `Ghost navigation` | `md` |
| `Удалить` | `Danger` | `sm` в таблицах, `md` в модалках |
| `Архив`, `Архивировать`, `Выйти`, `Удалить сетку` | `Danger subtle` | `sm` или `md` |
| `Переключить тему`, `Показать пароль`, `Скрыть панель`, `Закрыть`, ``, `` | `Icon button` | `icon-sm` или `icon-md` |
| Пункты сайдбара | `Nav item` | отдельный nav-компонент |
## 7. Правила композиции
### Формы
Primary-кнопка должна стоять в конце формы или action row. Рядом с ней допустимы secondary/ghost-действия, но не ещё одна primary без причины.
Рекомендуемый порядок:
| Сценарий | Порядок |
|---|---|
| Форма создания | `Очистить` как ghost, `Создать` как primary |
| Форма редактирования | `Отмена` как ghost, `Сохранить` как primary |
| Фильтр | `Сбросить` как ghost, `Показать` как secondary или primary, если это единственное действие блока |
### Таблицы
В строках таблицы использовать только `sm`.
Рекомендуемый порядок:
1. Основное безопасное действие: `Изменить`, `Преподаватели`, `Подгруппы`.
2. Дополнительное действие: `Календарь`, `Сетка`.
3. Рискованное действие: `Архивировать` или `Удалить`.
Удаление лучше отделять визуально от остальных кнопок небольшим gap.
### Модальные окна
В модалке primary должен соответствовать заголовку и цели модалки.
Пример:
| Заголовок | Primary | Secondary/Ghost |
|---|---|---|
| `Новая ручная сетка` | `Создать сетку` | `Отмена` |
| `Удалить слот` | `Удалить` как danger | `Отмена` |
| `Редактировать слот` | `Сохранить слот` | `Отмена` |
Кнопка закрытия всегда icon-only с `aria-label="Закрыть"`.
### Навигация
Сайдбарные пункты не должны наследовать стили action-кнопок. У них отдельная логика:
| Состояние | Стиль |
|---|---|
| Default | Прозрачный фон, muted-текст |
| Hover | Нейтральный surface-hover |
| Active | Акцентный tint-фон, accent-текст |
| Focus | Видимый ring/outline |
## 8. Главные исправления по приоритету
| Приоритет | Что сделать | Почему важно |
|---|---|---|
| P1 | Нормализовать `btn-primary`, `btn-secondary`, `btn-delete` между основной админкой и настройками | Один класс должен означать один визуальный контракт |
| P1 | Развести `Danger` и `Danger subtle` | `Удалить` и `Архивировать` не должны выглядеть одинаково опасными |
| P1 | Ввести размерную шкалу `sm/md/lg/icon` | Таблицы и формы станут визуально ровнее |
| P2 | Унифицировать `Переключить тему`, `Закрыть`, ``, ``, `Показать пароль` как icon buttons | Повысит предсказуемость и доступность |
| P2 | Убрать ролевые primary-цвета из student/teacher кнопок | Одинаковые действия будут считываться одинаково |
| P3 | Заменить текстовые символы `◐`, `×`, ``, `` на иконки единого набора | Интерфейс станет аккуратнее и доступнее |
## 9. Визуальный референс поведения
```text
Primary
[ Сохранить правило ]
Фон: акцентный, текст белый. Только главное действие.
Secondary
[ Изменить ]
Фон: поверхность, тонкая граница. Обычное действие.
Ghost
[ Отмена ]
Фон: прозрачный. Тихое действие без конкуренции.
Danger
[ Удалить ]
Фон: красный. Только необратимое действие.
Danger subtle
[ Архивировать ]
Фон: красный tint. Рискованное, но не полноценное удаление.
Icon
[ icon ]
Фиксированный квадрат. Доступное название через aria-label.
```
## 10. Почему это решение улучшит интерфейс
Единая кнопочная система снижает когнитивную нагрузку. Пользователь перестаёт разгадывать каждый экран и начинает быстро узнавать роли: главное действие, второстепенное действие, отмена, удаление, навигация.
Разделение `Danger` и `Danger subtle` особенно важно для админ-панели. Сейчас `Архивировать` визуально конкурирует с `Удалить`, хотя риск у этих действий разный. После унификации красный solid будет означать только настоящее удаление.
Единая размерная шкала сделает таблицы спокойнее. В строках не будет скачков высоты и плотности, а формы и модалки начнут выглядеть как части одной системы.
Общий primary-цвет вернёт продукту целостность. Ролевые цвета можно сохранить там, где они помогают считывать расписание и принадлежность данных, но базовые действия должны оставаться стабильными.
## 11. Приложение: дополнительные скриншоты
| Раздел | Скриншот |
|---|---|
| Конструктор правил | ![Конструктор правил](../audit-buttons-rules.png) |
| Календарный график | ![Календарный график](../audit-buttons-calendar.png) |
| Просмотр расписаний | ![Просмотр расписаний](../audit-buttons-schedule-view.png) |
| Аудиторный фонд | ![Аудиторный фонд](../audit-buttons-classrooms.png) |
| Группы обучения | ![Группы обучения](../audit-buttons-groups.png) |
| Структура вуза | ![Структура вуза](../audit-buttons-structure.png) |
| Дисциплины | ![Дисциплины](../audit-buttons-subjects.png) |
| Пользователи | ![Пользователи](../audit-buttons-users.png) |
| Временные слоты | ![Временные слоты](../audit-buttons-settings-time-slots.png) |
| Формы обучения | ![Формы обучения](../audit-buttons-settings-study-forms.png) |
| База данных | ![База данных](../audit-buttons-settings-database.png) |

View File

@@ -317,16 +317,27 @@ CSS-переменные позволяют поддерживать светл
:root {
--bg-primary: #ffffff;
--text-primary: #1a1a2e;
--accent: #6366f1;
--accent: #4F46E5;
}
[data-theme="dark"] {
--bg-primary: #0f0f23;
--text-primary: #e2e8f0;
--accent: #818cf8;
--accent: #8B5CF6;
}
```
### Система кнопок
Кнопки админ-панели, отдельной SPA настроек, страницы входа и личных кабинетов используют единую семантическую модель:
- `btn` — обязательная база для всех кнопок и ссылок-кнопок.
- Размеры: `btn-sm` — 32px для табличных строк, `btn-md` — 40px для форм и панелей, `btn-lg` — 48px для входа и главных широких действий.
- Иконки: `btn-icon-sm` — 32x32, `btn-icon-md` — 40x40. Все icon-only кнопки должны иметь `aria-label` на русском языке.
- Варианты: `btn-primary` для основного действия блока, `btn-secondary` для редактирования/обновления/показа, `btn-ghost` для очистки/отмены/сворачивания, `btn-danger` для удаления, `btn-danger-subtle` для архивирования, выхода и других рискованных действий без немедленного удаления.
- Единый радиус кнопок — `8px`. Локальные переопределения `.btn-primary`, `.btn-secondary`, `.btn-delete` в feature CSS запрещены: новые экраны должны наследовать токены из `frontend/admin/css/components.css`.
- Primary-акцент общий для продукта: `#4F46E5` в светлой теме и `#8B5CF6` в тёмной. Ролевые цвета кнопок в кабинетах преподавателя и студента не используются.
Переключение — через `theme-toggle.js`.
---