diff --git a/audit-buttons-01-login.png b/audit-buttons-01-login.png
new file mode 100644
index 0000000..0126525
Binary files /dev/null and b/audit-buttons-01-login.png differ
diff --git a/audit-buttons-02-dashboard.png b/audit-buttons-02-dashboard.png
new file mode 100644
index 0000000..37379d0
Binary files /dev/null and b/audit-buttons-02-dashboard.png differ
diff --git a/audit-buttons-03-users-form.png b/audit-buttons-03-users-form.png
new file mode 100644
index 0000000..3908c5b
Binary files /dev/null and b/audit-buttons-03-users-form.png differ
diff --git a/audit-buttons-04-settings-menu.png b/audit-buttons-04-settings-menu.png
new file mode 100644
index 0000000..4be70fa
Binary files /dev/null and b/audit-buttons-04-settings-menu.png differ
diff --git a/audit-buttons-05-settings-general.png b/audit-buttons-05-settings-general.png
new file mode 100644
index 0000000..56270c9
Binary files /dev/null and b/audit-buttons-05-settings-general.png differ
diff --git a/audit-buttons-06-teacher.png b/audit-buttons-06-teacher.png
new file mode 100644
index 0000000..2715515
Binary files /dev/null and b/audit-buttons-06-teacher.png differ
diff --git a/audit-buttons-07-student.png b/audit-buttons-07-student.png
new file mode 100644
index 0000000..a67b4a2
Binary files /dev/null and b/audit-buttons-07-student.png differ
diff --git a/audit-buttons-08-modal.png b/audit-buttons-08-modal.png
new file mode 100644
index 0000000..91c9241
Binary files /dev/null and b/audit-buttons-08-modal.png differ
diff --git a/audit-buttons-calendar.png b/audit-buttons-calendar.png
new file mode 100644
index 0000000..7e7860b
Binary files /dev/null and b/audit-buttons-calendar.png differ
diff --git a/audit-buttons-classrooms.png b/audit-buttons-classrooms.png
new file mode 100644
index 0000000..bdaaa0e
Binary files /dev/null and b/audit-buttons-classrooms.png differ
diff --git a/audit-buttons-groups.png b/audit-buttons-groups.png
new file mode 100644
index 0000000..c77a12f
Binary files /dev/null and b/audit-buttons-groups.png differ
diff --git a/audit-buttons-rules.png b/audit-buttons-rules.png
new file mode 100644
index 0000000..39627fc
Binary files /dev/null and b/audit-buttons-rules.png differ
diff --git a/audit-buttons-schedule-view.png b/audit-buttons-schedule-view.png
new file mode 100644
index 0000000..a76f7e3
Binary files /dev/null and b/audit-buttons-schedule-view.png differ
diff --git a/audit-buttons-settings-database.png b/audit-buttons-settings-database.png
new file mode 100644
index 0000000..b82fcd4
Binary files /dev/null and b/audit-buttons-settings-database.png differ
diff --git a/audit-buttons-settings-study-forms.png b/audit-buttons-settings-study-forms.png
new file mode 100644
index 0000000..b5af080
Binary files /dev/null and b/audit-buttons-settings-study-forms.png differ
diff --git a/audit-buttons-settings-time-slots.png b/audit-buttons-settings-time-slots.png
new file mode 100644
index 0000000..79c6eff
Binary files /dev/null and b/audit-buttons-settings-time-slots.png differ
diff --git a/audit-buttons-structure.png b/audit-buttons-structure.png
new file mode 100644
index 0000000..956c41d
Binary files /dev/null and b/audit-buttons-structure.png differ
diff --git a/audit-buttons-subjects.png b/audit-buttons-subjects.png
new file mode 100644
index 0000000..a7b4e42
Binary files /dev/null and b/audit-buttons-subjects.png differ
diff --git a/audit-buttons-users.png b/audit-buttons-users.png
new file mode 100644
index 0000000..b180fc4
Binary files /dev/null and b/audit-buttons-users.png differ
diff --git a/audit-buttons-workload.png b/audit-buttons-workload.png
new file mode 100644
index 0000000..658b076
Binary files /dev/null and b/audit-buttons-workload.png differ
diff --git a/docs/BUTTON_STYLING_PLAN.md b/docs/BUTTON_STYLING_PLAN.md
new file mode 100644
index 0000000..68db2c9
--- /dev/null
+++ b/docs/BUTTON_STYLING_PLAN.md
@@ -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. Авторизация
+
+
+
+Найдены кнопки:
+
+| Кнопка | Текущая роль | Комментарий |
+|---|---|---|
+| `Войти` | Primary | Корректно считывается как главное действие экрана. |
+| `Показать пароль` | Icon utility | Нужен единый icon-only стиль и обязательный `aria-label`. |
+| `Переключить тему` | Icon utility | Отличается от такой же кнопки в кабинетах преподавателя и студента. |
+
+Вывод: экран логина близок к правильной иерархии, но icon-only controls нужно привести к общей форме и размеру.
+
+### 3.2. Дашборд админки
+
+
+
+Найдены кнопки и ссылки-кнопки:
+
+| Кнопка | Текущий вид | Проблема |
+|---|---|---|
+| `Конструктор расписания` | Primary link | Хороший кандидат на основной CTA блока. |
+| `Точечные изменения / Просмотр` | Secondary link | Выглядит как второстепенное действие, это корректно. |
+| `Перепроверить` | `btn-primary`, маленькая высота | Primary используется для сервисного действия, хотя это не главное действие страницы. |
+| `Настройки` | Sidebar button | Визуально близко к навигации, но реализовано как кнопка. |
+| `Переключить тему` | Круглая icon button | Отличается от публичных кабинетов. |
+
+Основной вывод: `btn-primary` сейчас означает и главный CTA, и компактную служебную кнопку. Это размывает иерархию.
+
+### 3.3. Формы и таблицы админки
+
+
+
+Типичные кнопки:
+
+| Кнопка | Смысл | Текущее впечатление |
+|---|---|---|
+| `Создать` | Подтверждение формы | Главная кнопка, но размер и стиль отличаются между основной админкой и настройками. |
+| `Архивировать` | Рискованное, но часто обратимое действие | Визуально слишком близко к удалению. |
+| `Изменить` | Второстепенное действие строки | В разных разделах бывает фиолетовой или нейтральной. |
+| `Удалить` | Деструктивное действие | Встречается в разных размерах и оттенках красного. |
+
+Проблема: таблицы используют кнопки как плотный action bar, но размеры скачут от `24x28` до `113x28` и `96x40`. Это создаёт визуальный шум в строках.
+
+### 3.4. Меню настроек и выход
+
+
+
+Кнопка `Выйти` находится рядом с навигационными пунктами и выглядит почти как обычный пункт меню. Семантически это сессионное действие с риском потерять текущий контекст, поэтому ему нужен отдельный quiet-danger стиль.
+
+Рекомендация: `Выйти` не должен выглядеть как обычная навигация. Достаточно `Danger subtle`: красный текст на спокойной поверхности без агрессивной заливки.
+
+### 3.5. Отдельная SPA настроек
+
+
+
+В настройках виден тот же сайдбарный паттерн, но кнопки внутри разделов получают другую визуальную систему.
+
+Пример различий:
+
+| Класс | Основная админка | Настройки |
+|---|---|---|
+| `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. Кабинеты преподавателя и студента
+
+
+
+
+
+В публичных кабинетах используется отдельная светлая система:
+
+| Элемент | Преподаватель | Студент |
+|---|---|---|
+| `Сегодня` | 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. Модальные окна
+
+
+
+Найдены:
+
+| Кнопка | Роль | Рекомендация |
+|---|---|---|
+| `Создать сетку` | 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. Приложение: дополнительные скриншоты
+
+| Раздел | Скриншот |
+|---|---|
+| Конструктор правил |  |
+| Календарный график |  |
+| Просмотр расписаний |  |
+| Аудиторный фонд |  |
+| Группы обучения |  |
+| Структура вуза |  |
+| Дисциплины |  |
+| Пользователи |  |
+| Временные слоты |  |
+| Формы обучения |  |
+| База данных |  |
diff --git a/docs/FRONTEND.md b/docs/FRONTEND.md
index f52dba3..d8f54d5 100644
--- a/docs/FRONTEND.md
+++ b/docs/FRONTEND.md
@@ -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`.
---
diff --git a/frontend/admin/css/auditorium-workload.css b/frontend/admin/css/auditorium-workload.css
index e7ada53..677c985 100644
--- a/frontend/admin/css/auditorium-workload.css
+++ b/frontend/admin/css/auditorium-workload.css
@@ -654,32 +654,6 @@
gap: 0.45rem;
}
-.schedule-view-shell .btn-secondary {
- min-height: 42px;
- padding: 0.65rem 0.9rem;
- border: 1px solid var(--bg-card-border);
- border-radius: var(--radius-sm);
- background: var(--bg-input);
- color: var(--text-primary);
- font: inherit;
- font-size: 0.9rem;
- font-weight: 600;
- cursor: pointer;
- transition: background var(--transition), border-color var(--transition), color var(--transition), transform var(--transition);
-}
-
-.schedule-view-shell .btn-secondary:hover:not(:disabled) {
- background: var(--bg-hover);
- border-color: var(--accent);
- color: var(--accent-hover);
- transform: translateY(-1px);
-}
-
-.schedule-view-shell .btn-secondary:disabled {
- cursor: default;
- opacity: 0.45;
-}
-
.schedule-view-extra-filters {
margin-top: 0.9rem;
border-top: 1px solid var(--bg-card-border);
@@ -944,8 +918,8 @@
width: 100%;
}
- .schedule-view-period-buttons .btn-secondary,
- .schedule-view-result-actions .btn-secondary {
+ .schedule-view-period-buttons .btn,
+ .schedule-view-result-actions .btn {
flex: 1;
}
diff --git a/frontend/admin/css/components.css b/frontend/admin/css/components.css
index 446af8d..444e36c 100755
--- a/frontend/admin/css/components.css
+++ b/frontend/admin/css/components.css
@@ -1,3 +1,45 @@
+/* ===== Button Tokens ===== */
+:root {
+ --button-primary-bg: #8B5CF6;
+ --button-primary-bg-hover: #7C3AED;
+ --button-primary-text: #FFFFFF;
+ --button-secondary-bg: rgba(255, 255, 255, 0.04);
+ --button-secondary-bg-hover: rgba(255, 255, 255, 0.08);
+ --button-secondary-border: rgba(255, 255, 255, 0.10);
+ --button-secondary-text: #F8FAFC;
+ --button-ghost-bg-hover: rgba(255, 255, 255, 0.06);
+ --button-danger-bg: #DC2626;
+ --button-danger-bg-hover: #B91C1C;
+ --button-danger-subtle-bg: rgba(239, 68, 68, 0.13);
+ --button-danger-subtle-bg-hover: rgba(239, 68, 68, 0.20);
+ --button-danger-subtle-border: rgba(239, 68, 68, 0.25);
+ --button-danger-subtle-text: #FECACA;
+ --button-focus-ring: rgba(139, 92, 246, 0.45);
+ --button-disabled-bg: rgba(148, 163, 184, 0.16);
+ --button-disabled-text: #94A3B8;
+ --button-radius: 8px;
+}
+
+[data-theme="light"] {
+ --button-primary-bg: #4F46E5;
+ --button-primary-bg-hover: #4338CA;
+ --button-primary-text: #FFFFFF;
+ --button-secondary-bg: #FFFFFF;
+ --button-secondary-bg-hover: #F1F5F9;
+ --button-secondary-border: #CBD5E1;
+ --button-secondary-text: #334155;
+ --button-ghost-bg-hover: #F8FAFC;
+ --button-danger-bg: #DC2626;
+ --button-danger-bg-hover: #B91C1C;
+ --button-danger-subtle-bg: #FEF2F2;
+ --button-danger-subtle-bg-hover: #FEE2E2;
+ --button-danger-subtle-border: #FECACA;
+ --button-danger-subtle-text: #B91C1C;
+ --button-focus-ring: rgba(79, 70, 229, 0.35);
+ --button-disabled-bg: #CBD5E1;
+ --button-disabled-text: #64748B;
+}
+
/* ===== Cards ===== */
.card {
background: var(--bg-card);
@@ -48,6 +90,189 @@
letter-spacing: 0.04em;
}
+/* ===== Dashboard ===== */
+.dashboard-container {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.dashboard-metrics-grid {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(180px, 1fr));
+ gap: 1.25rem;
+}
+
+.dashboard-metric-card {
+ --metric-color: var(--accent);
+ --metric-bg: rgba(99, 102, 241, 0.1);
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ min-height: 112px;
+ padding: 1.25rem;
+ border-left: 4px solid var(--metric-color);
+}
+
+.dashboard-metric-card--students {
+ --metric-color: #10b981;
+ --metric-bg: rgba(16, 185, 129, 0.1);
+}
+
+.dashboard-metric-card--teachers {
+ --metric-color: #f59e0b;
+ --metric-bg: rgba(245, 158, 11, 0.1);
+}
+
+.dashboard-metric-card--classrooms {
+ --metric-color: #3b82f6;
+ --metric-bg: rgba(59, 130, 246, 0.1);
+}
+
+.dashboard-metric-card .metric-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 48px;
+ width: 48px;
+ height: 48px;
+ color: var(--metric-color);
+ background: var(--metric-bg);
+ border-radius: 12px;
+}
+
+.dashboard-middle {
+ display: grid;
+ grid-template-columns: minmax(0, 2fr) minmax(320px, 1fr);
+ gap: 1.25rem;
+ align-items: stretch;
+}
+
+.dashboard-monitor-card,
+.dashboard-compact-card {
+ display: flex;
+ flex-direction: column;
+}
+
+.dashboard-monitor-card {
+ min-height: 100%;
+}
+
+.dashboard-card-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+.dashboard-card-header h2 {
+ margin: 0;
+}
+
+.dashboard-time-slot {
+ flex: 0 0 auto;
+ padding: 0.35rem 0.75rem;
+ border-radius: 999px;
+ color: var(--accent-hover);
+ background: var(--bg-hover);
+ font-size: 0.85rem;
+ font-weight: 600;
+ white-space: nowrap;
+}
+
+.dashboard-monitor-table {
+ flex: 1;
+}
+
+.dashboard-side-stack {
+ display: grid;
+ grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
+ gap: 1.25rem;
+ min-height: 100%;
+}
+
+.dashboard-compact-card {
+ min-height: 0;
+ padding: 1.25rem;
+ gap: 0.75rem;
+}
+
+.dashboard-card-title {
+ margin: 0;
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--text-primary);
+}
+
+.dashboard-badge-list {
+ display: flex;
+ flex-wrap: wrap;
+ align-content: flex-start;
+ gap: 0.5rem;
+ margin-top: 0.25rem;
+}
+
+.dashboard-actions {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 0.65rem;
+ margin-top: auto;
+}
+
+.dashboard-action-link {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ min-height: 40px;
+ padding: 0.6rem 0.85rem;
+ text-align: center;
+ text-decoration: none;
+ font-size: 0.9rem;
+}
+
+.dashboard-action-link.btn-secondary {
+ color: var(--button-secondary-text);
+ background: var(--button-secondary-bg);
+ border: 1px solid var(--button-secondary-border);
+ border-radius: var(--button-radius);
+ box-shadow: none;
+}
+
+.dashboard-action-link.btn-secondary:hover {
+ color: var(--button-secondary-text);
+ background: var(--button-secondary-bg-hover);
+ border-color: var(--button-secondary-border);
+}
+
+@media (max-width: 1200px) {
+ .dashboard-metrics-grid {
+ grid-template-columns: repeat(2, minmax(180px, 1fr));
+ }
+
+ .dashboard-middle {
+ grid-template-columns: 1fr;
+ }
+
+ .dashboard-side-stack {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ grid-template-rows: auto;
+ }
+}
+
+@media (max-width: 700px) {
+ .dashboard-metrics-grid,
+ .dashboard-side-stack {
+ grid-template-columns: 1fr;
+ }
+
+ .dashboard-card-header {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+}
+
/* ===== Form Structure ===== */
.form-row {
display: flex;
@@ -167,14 +392,34 @@
gap: 1rem;
}
+.department-workspace-grid {
+ align-items: stretch;
+}
+
+.department-subject-import-card,
+.department-teachers-card {
+ display: flex;
+ flex-direction: column;
+ align-self: stretch;
+ min-height: 100%;
+}
+
+.department-teachers-card .card-header-row {
+ margin-bottom: 0.85rem;
+}
+
+.department-teachers-card .metric-grid {
+ margin-top: 0;
+}
+
.metric-grid {
display: grid;
- gap: 0.75rem;
+ gap: 0.6rem;
}
.metric-card,
.department-comment-item {
- padding: 0.85rem;
+ padding: 0.8rem 0.85rem;
background: var(--bg-input);
border: 1px solid var(--bg-card-border);
border-radius: var(--radius-sm);
@@ -183,7 +428,7 @@
.metric-card strong,
.department-comment-item strong {
display: block;
- margin-bottom: 0.35rem;
+ margin-bottom: 0.28rem;
color: var(--text-primary);
}
@@ -299,8 +544,9 @@
.subject-import-row {
display: grid;
- grid-template-columns: minmax(120px, 1fr) minmax(200px, 3fr) auto;
- gap: 0.75rem;
+ grid-template-columns: 160px minmax(260px, 1fr) auto;
+ column-gap: 0.65rem;
+ row-gap: 0.75rem;
align-items: end;
padding: 0.75rem;
background: var(--bg-input);
@@ -382,16 +628,97 @@
min-width: 260px;
}
-.schedule-slot-summary,
-.schedule-semester-line {
+.schedule-slot-summary {
margin-bottom: 0.35rem;
}
-.schedule-semester-line {
- display: flex;
+.academic-year-semesters {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(220px, 1fr));
+ gap: 0.35rem;
+ align-items: stretch;
+}
+
+.academic-years-table tbody td {
+ padding-top: 0.6rem;
+ padding-bottom: 0.6rem;
+ vertical-align: middle;
+}
+
+.academic-years-table thead th:first-child,
+.academic-years-table thead th:nth-child(2),
+.academic-years-table thead th:last-child {
+ text-align: center;
+}
+
+.academic-year-center-cell {
+ text-align: center;
+ font-weight: 700;
+}
+
+.academic-year-semesters-cell {
+ min-width: 520px;
+ vertical-align: middle;
+}
+
+.academic-year-actions-cell {
+ text-align: center;
+ vertical-align: middle;
+}
+
+.academic-year-actions {
+ display: inline-flex;
align-items: center;
- justify-content: space-between;
- gap: 0.5rem;
+ justify-content: center;
+ gap: 0.4rem;
+ min-height: 100%;
+ white-space: nowrap;
+}
+
+.academic-year-semester-item {
+ display: grid;
+ grid-template-columns: minmax(220px, 1fr) auto;
+ align-items: center;
+ gap: 0.65rem;
+ padding: 0.5rem 0.65rem;
+ background: var(--bg-input);
+ border: 1px solid var(--bg-card-border);
+ border-radius: var(--radius-sm);
+}
+
+.subject-import-code-field,
+.subject-import-name-field {
+ min-width: 0;
+}
+
+.subject-import-row .form-group label {
+ margin-bottom: 0.45rem;
+}
+
+@media (max-width: 900px) {
+ .academic-year-semesters {
+ grid-template-columns: 1fr;
+ }
+
+ .academic-year-semesters-cell {
+ min-width: 360px;
+ }
+}
+
+.academic-year-semester-meta {
+ display: grid;
+ gap: 0.2rem;
+}
+
+.academic-year-semester-type {
+ color: var(--text-primary);
+ font-size: 0.9rem;
+ font-weight: 700;
+}
+
+.academic-year-semester-period {
+ color: var(--text-secondary);
+ font-size: 0.82rem;
}
.schedule-inline-table {
@@ -403,34 +730,33 @@
top: 50%;
right: 0;
z-index: 905;
- width: 42px;
- height: 74px;
- border: 1px solid var(--bg-card-border);
+ width: 40px;
+ height: 40px;
+ border: 1px solid var(--button-secondary-border);
border-right: 0;
- border-radius: 10px 0 0 10px;
- background: color-mix(in srgb, var(--bg-card) 92%, var(--accent));
- color: var(--text-primary);
- font: inherit;
- font-size: 1.8rem;
- font-weight: 800;
- line-height: 1;
- cursor: pointer;
+ border-radius: var(--button-radius) 0 0 var(--button-radius);
+ background: var(--button-secondary-bg);
+ color: var(--button-secondary-text);
box-shadow: -8px 0 24px rgba(0, 0, 0, 0.2);
transform: translateY(-50%);
- transition: right var(--transition), background var(--transition), border-color var(--transition), color var(--transition);
+ transition: right var(--transition), background var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
.schedule-visual-handle:hover,
.schedule-visual-handle.open {
- border-color: var(--accent);
- background: color-mix(in srgb, var(--accent) 20%, var(--bg-card));
- color: var(--accent-hover);
+ border-color: var(--button-secondary-border);
+ background: var(--button-secondary-bg-hover);
+ color: var(--button-secondary-text);
}
.schedule-visual-handle.open {
right: min(92vw, 1180px);
}
+.schedule-visual-handle.open .schedule-visual-handle-icon {
+ transform: rotate(180deg);
+}
+
.schedule-visual-backdrop {
position: fixed;
inset: 0;
@@ -1868,108 +2194,222 @@ input[type="number"] {
}
/* ===== Buttons ===== */
-.btn-primary {
- position: relative;
- overflow: hidden;
- padding: 0.75rem 1.75rem;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- border: none;
- border-radius: var(--radius-sm);
- color: #fff;
+.btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.45rem;
+ min-width: 0;
+ border: 1px solid transparent;
+ border-radius: var(--button-radius);
+ background: transparent;
+ color: inherit;
font-family: inherit;
- font-size: 0.95rem;
+ font-size: 0.875rem;
font-weight: 600;
- letter-spacing: 0.02em;
- cursor: pointer;
+ line-height: 1;
+ text-align: center;
+ text-decoration: none;
white-space: nowrap;
- transition: all var(--transition);
- box-shadow: 0 4px 15px var(--accent-glow);
+ cursor: pointer;
+ user-select: none;
+ transition:
+ background var(--transition),
+ border-color var(--transition),
+ color var(--transition),
+ box-shadow var(--transition),
+ transform var(--transition);
}
-.btn-primary::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: linear-gradient(rgba(255, 255, 255, 0.2), transparent);
- border-radius: inherit;
- opacity: 0;
- transition: opacity var(--transition);
+.btn:hover:not(:disabled) {
+ transform: translateY(-1px);
}
-.btn-primary:hover {
- transform: translateY(-2px);
- box-shadow: 0 8px 25px var(--accent-glow);
+.btn:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 3px var(--button-focus-ring);
}
-.btn-primary:hover::before {
- opacity: 1;
+.btn:active:not(:disabled) {
+ transform: translateY(0);
}
-.btn-primary:active {
- transform: translateY(1px);
- box-shadow: 0 2px 10px var(--accent-glow);
+.btn:disabled,
+.btn[aria-disabled="true"] {
+ background: var(--button-disabled-bg);
+ border-color: transparent;
+ color: var(--button-disabled-text);
+ cursor: not-allowed;
+ opacity: 0.75;
+ transform: none;
}
-.btn-delete {
- padding: 0.35rem 0.7rem;
- background: rgba(248, 113, 113, 0.1);
- border: 1px solid rgba(248, 113, 113, 0.2);
- border-radius: var(--radius-sm);
- color: var(--error);
+.btn-sm {
+ min-height: 32px;
+ padding: 0 12px;
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.btn-md {
+ min-height: 40px;
+ padding: 0 16px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.btn-lg {
+ min-height: 48px;
+ padding: 0 20px;
+ font-size: 15px;
+ font-weight: 700;
+}
+
+.btn-icon-sm,
+.btn-icon-md {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 auto;
+ padding: 0;
+ border-radius: var(--button-radius);
+ line-height: 1;
+}
+
+.btn-icon-sm {
+ width: 32px;
+ height: 32px;
+}
+
+.btn-icon-md {
+ width: 40px;
+ height: 40px;
+}
+
+.btn-icon-sm svg {
+ width: 18px;
+ height: 18px;
+}
+
+.btn-icon-md svg {
+ width: 20px;
+ height: 20px;
+}
+
+.btn-primary {
+ background: var(--button-primary-bg);
+ border-color: transparent;
+ color: var(--button-primary-text);
+ box-shadow: none;
+}
+
+.btn-primary:hover:not(:disabled) {
+ background: var(--button-primary-bg-hover);
+ color: var(--button-primary-text);
+}
+
+.btn-secondary {
+ background: var(--button-secondary-bg);
+ border-color: var(--button-secondary-border);
+ color: var(--button-secondary-text);
+}
+
+.btn-secondary:hover:not(:disabled) {
+ background: var(--button-secondary-bg-hover);
+ border-color: var(--button-secondary-border);
+ color: var(--button-secondary-text);
+}
+
+.btn-ghost {
+ background: transparent;
+ border-color: transparent;
+ color: var(--text-secondary);
+}
+
+.btn-ghost:hover:not(:disabled) {
+ background: var(--button-ghost-bg-hover);
+ color: var(--text-primary);
+}
+
+.btn-danger {
+ background: var(--button-danger-bg);
+ border-color: transparent;
+ color: #FFFFFF;
+}
+
+.btn-danger:hover:not(:disabled) {
+ background: var(--button-danger-bg-hover);
+ color: #FFFFFF;
+}
+
+.btn-danger-subtle {
+ background: var(--button-danger-subtle-bg);
+ border-color: var(--button-danger-subtle-border);
+ color: var(--button-danger-subtle-text);
+}
+
+.btn-danger-subtle:hover:not(:disabled) {
+ background: var(--button-danger-subtle-bg-hover);
+ border-color: var(--button-danger-subtle-border);
+ color: var(--button-danger-subtle-text);
+}
+
+.group-actions-cell {
+ text-align: right;
+ white-space: nowrap;
+}
+
+.group-actions {
+ display: grid;
+ grid-template-columns: 88px 104px 104px 116px;
+ gap: 0.35rem;
+ justify-content: end;
+ align-items: center;
+}
+
+.group-action-btn {
+ width: 100%;
+}
+
+.btn-restore-group {
+ min-height: 32px;
+ padding: 0 12px;
+ border-radius: var(--button-radius);
font-family: inherit;
- font-size: 0.8rem;
+ font-size: 13px;
+ font-weight: 600;
cursor: pointer;
transition: background var(--transition), transform var(--transition);
position: relative;
overflow: hidden;
}
-.btn-delete:hover {
- background: rgba(248, 113, 113, 0.2);
+.btn-restore-group {
+ background: rgba(245, 158, 11, 0.1);
+ border: 1px solid rgba(245, 158, 11, 0.24);
+ color: var(--warning);
+}
+
+.btn-restore-group:hover {
+ background: rgba(245, 158, 11, 0.2);
transform: scale(1.05);
}
.btn-icon-toggle {
- background: transparent;
- border: 1px solid var(--bg-card-border);
- color: var(--text-secondary);
- width: 28px;
- height: 28px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 6px;
- cursor: pointer;
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
- padding: 0;
+ width: 32px;
+ height: 32px;
}
.btn-icon-toggle:hover {
- background: var(--bg-card);
- border-color: var(--accent);
- color: var(--accent);
- transform: rotate(45deg);
- box-shadow: 0 0 10px var(--accent-glow);
-}
-
-.btn-edit-classroom {
- padding: 0.35rem 0.7rem;
- background: rgba(99, 102, 241, 0.1);
- border: 1px solid rgba(99, 102, 241, 0.2);
- border-radius: var(--radius-sm);
- color: var(--accent-hover);
- cursor: pointer;
- transition: all var(--transition);
-}
-
-.btn-edit-classroom:hover {
- background: rgba(99, 102, 241, 0.2);
transform: translateY(-1px);
}
+.group-actions .group-action-btn {
+ min-height: 32px;
+ padding: 0 12px;
+ font-size: 13px;
+}
+
/* ===== Alerts ===== */
.form-alert {
display: none;
@@ -2341,20 +2781,19 @@ tbody tr:hover {
/* ===== Theme Toggle Button ===== */
.theme-toggle {
- width: 42px;
- height: 42px;
- border: none;
- border-radius: 50%;
- background: var(--bg-card);
- border: 1px solid var(--bg-card-border);
- color: var(--text-primary);
- cursor: pointer;
- display: flex;
+ width: 40px;
+ height: 40px;
+ border-radius: var(--button-radius);
+ background: var(--button-secondary-bg);
+ border: 1px solid var(--button-secondary-border);
+ color: var(--button-secondary-text);
+ display: inline-flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
- transition: background 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
+ padding: 0;
+ transition: background var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition), transform var(--transition);
z-index: 100;
flex-shrink: 0;
}
@@ -2366,12 +2805,18 @@ tbody tr:hover {
}
.theme-toggle:hover {
- transform: scale(1.1);
- box-shadow: 0 4px 16px var(--accent-glow);
+ background: var(--button-secondary-bg-hover);
+ border-color: var(--button-secondary-border);
+ transform: translateY(-1px);
}
.theme-toggle:active {
- transform: scale(0.95);
+ transform: translateY(0);
+}
+
+.theme-toggle:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 3px var(--button-focus-ring);
}
.theme-toggle--fixed {
diff --git a/frontend/admin/css/layout.css b/frontend/admin/css/layout.css
index 3265a1a..57bbc88 100755
--- a/frontend/admin/css/layout.css
+++ b/frontend/admin/css/layout.css
@@ -25,15 +25,7 @@
}
.sidebar-close-btn {
- background: transparent;
- border: none;
color: var(--text-secondary);
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 0.25rem;
- border-radius: var(--radius-sm);
transition: all var(--transition);
}
@@ -355,12 +347,7 @@
/* ===== Mobile Menu Toggle ===== */
.menu-toggle {
display: none;
- padding: 0.4rem;
- background: none;
- border: none;
color: var(--text-primary);
- cursor: pointer;
- border-radius: var(--radius-sm);
transition: background var(--transition);
}
diff --git a/frontend/admin/css/main.css b/frontend/admin/css/main.css
index a03d06e..cbfb555 100755
--- a/frontend/admin/css/main.css
+++ b/frontend/admin/css/main.css
@@ -51,9 +51,9 @@
--text-primary: #0f172a;
--text-secondary: #475569;
--text-placeholder: #94a3b8;
- --accent: #6366f1;
- --accent-hover: #4f46e5;
- --accent-glow: rgba(99, 102, 241, 0.3);
+ --accent: #4F46E5;
+ --accent-hover: #4338CA;
+ --accent-glow: rgba(79, 70, 229, 0.3);
--accent-secondary: #d946ef;
--error: #ef4444;
diff --git a/frontend/admin/index.html b/frontend/admin/index.html
index aebbf5d..6327494 100755
--- a/frontend/admin/index.html
+++ b/frontend/admin/index.html
@@ -49,7 +49,7 @@
Magistr
-