:root {
    --lt-navy: #0F1053;
    --lt-white: #FEFEFE;
    --lt-border: #DADCE6;
    --lt-error: #C0392B;
    --lt-ok: #1F7A52;
    --lt-warn: #B4780F;
    --lt-bg: #F4F5F9;

    /* Семантические токены для текста/поверхностей (не бренд-заливок вроде
       сайдбара/кнопок, которые остаются --lt-navy в обеих темах) — только
       они переопределяются в тёмной теме, см. .admin-shell[data-theme="dark"]
       в конце файла. */
    --lt-surface: var(--lt-white);
    --lt-text: var(--lt-navy);
    --lt-text-muted: #6B6D8A;
    --lt-link: var(--lt-navy);

    /* Статусный цвет как текст/обводка НА поверхности (--lt-surface), а не
       как заливка бейджа с белым текстом — светлая тема совпадает с
       базовыми --lt-error/ok/warn, тёмная переопределяет светлее (см.
       .admin-shell[data-theme="dark"]). */
    --lt-error-text: var(--lt-error);
    --lt-ok-text: var(--lt-ok);
    --lt-warn-text: var(--lt-warn);

    /* Заливка активных элементов поверх контента: активная вкладка, баннер поддержки, полоса
       непрочитанного оповещения. Это бренд-заливка, как у кнопок и сайдбара, поэтому в тёмной
       теме она не переопределяется — белый текст на ней читается в обеих. */
    --lt-accent: var(--lt-navy);
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: "Golos Text", "Segoe UI", sans-serif;
    background: var(--lt-bg);
    color: var(--lt-text);
}

/* Базовый цвет для ссылок без собственного класса (таких много — «Журнал»,
   «Изменить», «Настройки триггеров» и т.п. в разных модулях просто <a>
   без стилизации) — без этого браузер подставляет свой синий по умолчанию,
   который не адаптируется под тему и выглядит чужеродно на тёмном фоне.
   Более специфичные правила (например .compact-day-table td a { color:
   inherit }) по специфичности всё равно перекрывают это. */
.admin-content a,
.admin-topbar-section a {
    color: var(--lt-link);
}

.login-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-card {
    background: var(--lt-white);
    border: 1px solid var(--lt-border);
    border-radius: 12px;
    padding: 32px;
    width: 320px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    box-shadow: 0 8px 24px rgba(15, 16, 83, 0.08);
}

.login-logo {
    height: 32px;
    align-self: center;
    margin-bottom: 8px;
}

.login-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 13px;
}

.login-field input {
    padding: 10px 12px;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    font-size: 14px;
}

.login-field input:focus {
    outline: 2px solid var(--lt-navy);
    outline-offset: 1px;
}

.login-error {
    background: #FBEAE8;
    color: var(--lt-error);
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 13px;
}

/* Плашка успешного действия. Раньше результат ассистента («создано записей: 37») уезжал в тот же
   параметр error и показывался красным — оператор читал успех как сбой. */
.admin-success {
    margin: 0 0 12px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid #b7e0c0;
    background: #eaf7ee;
    color: #1d6b33;
    font-size: 13px;
}

.login-button {
    background: var(--lt-navy);
    color: var(--lt-white);
    border: none;
    border-radius: 8px;
    padding: 12px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.login-button--secondary {
    background: var(--lt-white);
    color: var(--lt-navy);
    border: 1px solid var(--lt-border);
}

/* Переключатель «Ассистент» (автозаполнение журнала) — ТЗ: кнопка на экране журнала,
   подсвечивается синим (var(--lt-navy), тот же брендовый цвет, что у .responsible-badge/
   .login-button) при включённом состоянии. Один класс на все пять журналов — и для ссылки-
   индикатора на Index, и для submit-кнопки на Settings. */
/* !important на color: это отдельный компонент с собственными состояниями, ему нужно перебивать
   общее правило .admin-topbar-section a { color: var(--lt-link) } (выше по специфичности за счёт
   элемент+класс) — без этого текст кнопки в состоянии --on сливается с её собственным синим фоном. */
.assistant-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--lt-white);
    color: var(--lt-navy) !important;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
}

.assistant-toggle::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--lt-text-muted);
}

.assistant-toggle--on {
    background: var(--lt-navy);
    color: var(--lt-white) !important;
    border-color: var(--lt-navy);
}

.assistant-toggle--on::before {
    background: var(--lt-white);
}

.placeholder-page {
    max-width: 480px;
    margin: 64px auto;
    background: var(--lt-surface);
    border: 1px solid var(--lt-border);
    border-radius: 12px;
    padding: 32px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.placeholder-note {
    color: var(--lt-text-muted);
    font-size: 13px;
}

/* Каркас кабинета: сворачиваемое меню + компактная шапка (ТЗ п.11) */

.admin-shell {
    display: flex;
    min-height: 100vh;
    background: var(--lt-bg);
    color: var(--lt-text);
    --sidebar-width: 220px;
    --sidebar-width-collapsed: 60px;
}

.admin-sidebar {
    width: var(--sidebar-width);
    flex-shrink: 0;
    background: var(--lt-navy);
    color: var(--lt-white);
    display: flex;
    flex-direction: column;
    transition: width 0.15s ease;
    overflow: hidden;
}

.admin-shell.collapsed .admin-sidebar {
    width: var(--sidebar-width-collapsed);
}

/* Единственный @media в файле, и он намеренно узкий.
   Полноценный адаптив админки, которой пользуются с десктопа, сейчас не окупается — но на
   ноутбуке 1280px сайдбар в 220px отъедает шестую часть ширины у таблиц, где по 8 колонок.
   Здесь он просто сужается; всё остальное решает горизонтальная прокрутка таблиц
   (.compact-table-wrap), которая теперь есть у всех широких таблиц. */
@media (max-width: 1366px) {
    .admin-sidebar {
        width: 190px;
    }

    .admin-content {
        padding: 12px;
    }
}

.admin-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px;
    white-space: nowrap;
}

.admin-sidebar-mark {
    height: 24px;
    width: 24px;
    flex-shrink: 0;
}

.admin-shell.collapsed .admin-sidebar-wordmark {
    display: none;
}

.admin-nav {
    display: flex;
    flex-direction: column;
    padding: 8px;
    gap: 4px;
    /* У сайдбара overflow: hidden, поэтому не влезшие пункты не прокручивались, а просто
       пропадали — на ноутбуке с высотой окна ~620px нижние разделы были недостижимы вовсе.
       min-height: 0 обязателен: без него flex-элемент не сжимается ниже своего содержимого
       и прокрутка не включается. */
    overflow-y: auto;
    min-height: 0;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
}

.admin-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 8px;
    color: var(--lt-white);
    text-decoration: none;
    font-size: 13px;
    line-height: 1.25;
}

.admin-nav-item:hover {
    background: rgba(255, 255, 255, 0.12);
}

.admin-nav-glyph {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.14);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
}

.admin-nav-glyph svg {
    width: 16px;
    height: 16px;
}

.admin-shell.collapsed .admin-nav-label {
    display: none;
}

/* Группа «Журналы».

   Восемь журналов лежали в общем плоском списке вперемешку с кабинетом и сотрудниками — это и
   было главным расхождением с привычным видом: в старом кабинете они жили в одном сворачиваемом
   разделе. Слова взяты правильные, а не прежние: старые подписи местами вводили в заблуждение
   («Бактериологические журналы» у бактерицидных ламп — это разные вещи). */
.admin-nav-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.admin-nav-group-toggle {
    width: 100%;
    background: none;
    border: 0;
    font: inherit;
    font-size: 13px;
    color: var(--lt-white);
    cursor: pointer;
    text-align: left;
}

.admin-nav-caret {
    margin-left: auto;
    flex-shrink: 0;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    transform: rotate(-90deg);
    transition: transform 0.15s ease;
}

.admin-nav-group--open .admin-nav-caret {
    transform: none;
}

.admin-nav-sub {
    display: none;
    flex-direction: column;
    gap: 2px;
}

.admin-nav-group--open .admin-nav-sub {
    display: flex;
}

/* Иконка у вложенного пункта убрана намеренно: она занимала 34px из ~134px, доступных под текст,
   и полные названия уезжали на три строки. Вместо неё — направляющая слева. */
.admin-nav-subitem {
    /* 11 + 25 + отступ .admin-nav у края = 44px: ровно там, где начинается текст верхнего уровня.
       При меньшем отступе вложенные пункты начинались левее родителя и читались не как его
       содержимое, а как отдельный список. */
    margin-left: 11px;
    padding-left: 25px;
    border-left: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 0 8px 8px 0;
}

.admin-nav-subitem .admin-nav-glyph {
    display: none;
}

.admin-nav-item--active {
    background: rgba(255, 255, 255, 0.18);
    font-weight: 600;
}

.admin-nav-subitem.admin-nav-item--active {
    border-left-color: var(--lt-white);
}

/* В свёрнутом сайдбаре группировать нечего — подписей не видно. Заголовок группы прячется,
   журналы показываются одними значками, как было до группировки. */
.admin-shell.collapsed .admin-nav-group-toggle {
    display: none;
}

.admin-shell.collapsed .admin-nav-sub {
    display: flex;
}

.admin-shell.collapsed .admin-nav-subitem {
    margin-left: 0;
    padding-left: 12px;
    border-left: 0;
    border-radius: 8px;
}

.admin-shell.collapsed .admin-nav-subitem .admin-nav-glyph {
    display: flex;
}

.admin-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.admin-topbar {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px 20px;
    background: var(--lt-surface);
    border-bottom: 1px solid var(--lt-border);
}

.admin-toggle {
    background: transparent;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    width: 32px;
    height: 32px;
    cursor: pointer;
    font-size: 14px;
    flex-shrink: 0;
}

.admin-title {
    font-size: 16px;
    margin: 0;
    white-space: nowrap;
}

.admin-topbar-section {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    overflow-x: auto;
}

.admin-topbar-user {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    white-space: nowrap;
}

.admin-logout-btn {
    padding: 6px 12px;
    font-size: 12px;
}

.admin-content {
    padding: 20px;
    overflow-x: auto;
}

/* Компактные таблицы-журналы (У/В по дням месяца) — ТЗ п.11.3 */

.compact-table-wrap {
    overflow-x: auto;
}

.compact-day-table {
    border-collapse: collapse;
    font-size: 11px;
    white-space: nowrap;
}

.compact-day-table th,
.compact-day-table td {
    border: 1px solid var(--lt-border);
    padding: 3px 4px;
    text-align: center;
    min-width: 26px;
}

.compact-day-table th.row-label,
.compact-day-table td.row-label {
    position: sticky;
    left: 0;
    background: var(--lt-surface);
    min-width: 160px;
    text-align: left;
    font-weight: 600;
    z-index: 1;
}

.compact-day-table .shift-tag {
    display: inline-block;
    min-width: 14px;
    color: var(--lt-text-muted);
    font-size: 10px;
    font-weight: 700;
}

/* Список сотрудников: карточка + бейдж «Ответственный» */

.admin-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--lt-surface);
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    overflow: hidden;
}

.admin-table th,
.admin-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var(--lt-border);
    font-size: 13px;
}

.admin-table th {
    background: var(--lt-bg);
    font-weight: 600;
}

.admin-table tr:last-child td {
    border-bottom: none;
}

/* Колонка даты не должна переноситься: при тесноте браузер рвал «01.09.2026» на две строки
   и раздувал высоту всей строки. Требование ТЗ п.11 про узкие колонки дат до этого было
   выполнено только в месячных сетках (.compact-day-table), а в обычных таблицах-списках
   никакого правила не было вообще. */
.admin-table .cell-date {
    white-space: nowrap;
    width: 1%;
}

/* Колонка действий: прижимаем к содержимому и не даём ей растягивать таблицу. */
.admin-table .cell-actions {
    white-space: nowrap;
    width: 1%;
}

/* Форма выбора объекта в шапке. Класс использовался в 14 страницах, но правила под него не было:
   форма работала только потому, что родительский .admin-topbar-section — flex-контейнер.
   Объявляем явно, чтобы поведение не зависело от чужого контекста. */
.admin-object-form {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin: 0;
}

/* Адрес выбранного объекта под селектором. Список обрезается по ширине панели, и выбранная
   строка в нём может не поместиться целиком — здесь адрес виден всегда. */
.admin-object-address {
    max-width: 340px;
    color: var(--lt-text-muted);
    font-size: 11px;
    line-height: 1.3;
}

.responsible-badge {
    display: inline-block;
    background: var(--lt-navy);
    color: var(--lt-white);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 11px;
    font-weight: 700;
    margin-left: 6px;
}

.admin-disabled-row {
    color: var(--lt-text-muted);
}

.admin-form {
    background: var(--lt-surface);
    border: 1px solid var(--lt-border);
    border-radius: 12px;
    padding: 24px;
    max-width: 420px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Короткая форма в строку: два поля периода и кнопка. Обычная .admin-form ставит поля
   колонкой — для выбора «с … по …» это лишняя высота без всякой пользы. */
.admin-form--inline {
    flex-direction: row;
    align-items: flex-end;
    flex-wrap: wrap;
    max-width: none;
}

/* Ряд полей внутри обычной колоночной формы — для пары дат «с … по …». */
.admin-form-row {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.admin-form-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 13px;
}

/* Подсказка у графы формы: кружок «?» с нативным всплывающим title.
   Нативный title, а не собственный тултип на JS, — в админке нет ни одного скрипта интерфейса,
   и вводить его ради подсказок значит заводить новый фронтенд-паттерн в декомпилированном
   проекте. Нативная подсказка работает с клавиатуры и в скринридерах. */
.field-hint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    margin-left: 4px;
    border-radius: 50%;
    border: 1px solid var(--lt-border);
    background: var(--lt-bg);
    color: var(--lt-text-muted);
    font-size: 10px;
    font-weight: 700;
    cursor: help;
    vertical-align: middle;
}

.admin-toggle-field {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
}

.admin-object-select {
    max-width: 340px;
    padding: 6px 10px;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    font-size: 13px;
}

/* Тегово-чиповый мультивыбор ответственных */

.chip-multiselect {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.chip-multiselect-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--lt-border);
    border-radius: 999px;
    padding: 6px 12px;
    font-size: 12px;
    cursor: pointer;
    background: var(--lt-surface);
}

.chip-multiselect-item--checked {
    background: var(--lt-navy);
    color: var(--lt-white);
    border-color: var(--lt-navy);
}

.chip-multiselect-item input {
    margin: 0;
}

.chip-multiselect-empty {
    color: var(--lt-text-muted);
    font-size: 13px;
}

.admin-subheading {
    font-size: 14px;
    margin: 24px 0 12px;
}

/* Два смежных блока в ряд.

   Печатная форма и заполнение пропусков работают с одним и тем же периодом: держать их друг под
   другом означало прокручивать страницу между двумя действиями над одними и теми же датами.
   auto-fit, а не фиксированные две колонки: когда ассистент выключен, второго блока нет вовсе, и
   первый должен занять ряд целиком, а не половину. На узком экране колонки схлопываются в одну. */
.admin-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 0 24px;
    align-items: start;
}

.admin-link-button {
    background: none;
    border: none;
    padding: 0;
    color: var(--lt-link);
    text-decoration: underline;
    cursor: pointer;
    font-size: 13px;
}

.admin-month-nav {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;
}

.admin-month-nav a {
    color: var(--lt-link);
}

.compact-day-table td a {
    display: block;
    color: inherit;
    text-decoration: none;
}

.compact-day-table td a:hover {
    background: var(--lt-bg);
}

.admin-audit-details {
    margin-top: 24px;
}

.admin-audit-details summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 8px;
}

/* Общая сводка в реальном времени (`/Admin/Overview`) — карточки по всем
   точкам объекта сразу (Склады + ХМО), цвет статуса прямо на карточке. */

.overview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}

.overview-card {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    background: var(--lt-surface);
    border: 1px solid var(--lt-border);
    border-left: 4px solid var(--lt-border);
    border-radius: 8px;
    padding: 14px 16px;
    transition: border-color 0.15s ease;
}

.overview-card--ok {
    border-left-color: var(--lt-ok-text);
}

.overview-card--crit {
    border-left-color: var(--lt-error-text);
}

.overview-card--unknown {
    border-left-color: var(--lt-text-muted);
}

/* Предупреждение: ресурс лампы кончается. Отдельное состояние между «в норме» и «критично» —
   у температуры такого не было, там значение либо в диапазоне, либо нет, а у ресурса есть
   осмысленная середина: ещё работает, но менять пора. */
.overview-card--warn {
    border-left-color: var(--lt-warn-text);
}

.overview-card--warn .overview-card-reading {
    color: var(--lt-warn-text);
}

.overview-card-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background: var(--lt-navy);
    color: var(--lt-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
}

.overview-card-body {
    min-width: 0;
    flex: 1;
}

.overview-card-name {
    font-weight: 600;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.overview-card-zone {
    font-size: 11px;
    color: var(--lt-text-muted);
}

.overview-card-reading {
    margin-top: 6px;
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.overview-card--crit .overview-card-reading {
    color: var(--lt-error-text);
}

.overview-card-updated {
    margin-top: 2px;
    font-size: 11px;
    color: var(--lt-text-muted);
}

/* Тёмная тема кабинета — переключатель в топбаре, ключ localStorage
   `labtab-admin-theme` (см. _Layout.cshtml). Переопределяются только
   семантические токены текста/поверхности — --lt-navy/--lt-white как
   бренд-заливка (сайдбар, кнопки) остаются одинаковыми в обеих темах. */

.admin-shell[data-theme="dark"] {
    --lt-surface: #1B1C33;
    --lt-text: #E7E7F2;
    --lt-text-muted: #9698B8;
    --lt-link: #9FA3F5;
    --lt-border: #35365A;
    --lt-bg: #101124;
    /* --lt-error/ok/warn НЕ переопределяем здесь — они используются как
       заливка бейджей с белым текстом поверх (.responsible-badge и т.п.),
       и должны остаться достаточно тёмными/насыщенными для контраста с
       белым в обеих темах. Для случаев, где тот же статус нужен как ЦВЕТ
       ТЕКСТА/обводки на самой поверхности (недостаточно контраста с тёмным
       --lt-surface) — отдельные -text токены ниже. */
    --lt-error-text: #E58787;
    --lt-ok-text: #6FCB9F;
    --lt-warn-text: #E8B860;
}

/* Форма правки одного поля прямо в строке таблицы справочника: поле и кнопка в одну линию,
   без отступов обычной admin-form, иначе строка таблицы разъезжается по высоте. */
.admin-inline-form {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
}

.admin-inline-form input[type="text"] {
    min-width: 0;
    width: 100%;
    max-width: 220px;
}

/* Числовое поле в строке (выход порции) уже текстового: иначе колонка справочника блюд
   раздувается шире названия блюда. */
.admin-inline-form input[type="number"] {
    min-width: 0;
    width: 80px;
}


/* Сетка графика работы: сотрудники × дни месяца. Первая колонка липкая — при тридцати одном
   столбце без неё непонятно, чью строку размечаешь. */
.schedule-grid { font-size: 12px; }
.schedule-grid th, .schedule-grid td { padding: 3px 4px; text-align: center; }
.schedule-grid .schedule-name {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--lt-surface, #fff);
    text-align: left;
    white-space: nowrap;
    min-width: 190px;
}
.schedule-grid .schedule-position { display: block; color: var(--lt-text-muted); font-size: 10px; }
.schedule-grid .schedule-dow { display: block; color: var(--lt-text-muted); font-size: 9px; text-transform: lowercase; }
.schedule-grid .schedule-head { font-weight: 700; padding: 0; }
.schedule-grid .schedule-weekend { background: var(--lt-bg); }
.schedule-grid .schedule-cell label { display: block; cursor: pointer; padding: 2px 0; }
.schedule-grid .schedule-total { font-variant-numeric: tabular-nums; font-weight: 600; }


/* Второй шаг входа: пояснение, QR привязки и ключ ручного ввода. */
.login-note {
    margin: 0 0 10px;
    color: var(--lt-text-muted);
    font-size: 12px;
    line-height: 1.5;
    text-align: center;
}
.login-note code {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 6px;
    border: 1px solid var(--lt-border);
    border-radius: 4px;
    background: var(--lt-bg);
    font-size: 12px;
    letter-spacing: .08em;
}
.login-qr {
    display: block;
    width: 180px;
    height: 180px;
    margin: 0 auto 10px;
    border: 1px solid var(--lt-border);
    border-radius: 6px;
    background: #fff;
}

/* Карточка для форм с несколькими полями: узкая карточка входа под них тесна. */
.login-card--wide {
    max-width: 420px;
}
.login-card--wide .admin-form {
    width: 100%;
}
.login-note-sep {
    margin: 0 6px;
    opacity: .5;
}

/* Вкладки внутри раздела: пять категорий документов живут на одной странице, а не пятью
   пунктами меню, как было в старом кабинете. */
.admin-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--lt-border);
    padding-bottom: 8px;
}
.admin-content .admin-tab {
    padding: 7px 14px;
    border: 1px solid var(--lt-border);
    border-radius: 999px;
    color: var(--lt-text-muted);
    font-size: 13px;
    text-decoration: none;
    white-space: nowrap;
}
.admin-content .admin-tab:hover { border-color: var(--lt-accent); color: var(--lt-text); }
.admin-content .admin-tab--active {
    background: var(--lt-accent);
    border-color: var(--lt-accent);
    color: #fff;
}

/* Баннер поддержки. Закреплён в углу и не перекрывает содержимое: раздел с широкими таблицами
   прокручивается под ним. */
.chat-banner {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 40;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-radius: 999px;
    background: var(--lt-accent);
    color: #fff;
    font-size: 14px;
    text-decoration: none;
    box-shadow: 0 6px 18px rgba(20, 24, 60, .22);
}
.chat-banner:hover { filter: brightness(1.08); }
/* Баннер вынесен за пределы .admin-shell, где переключается тёмная тема, поэтому цвета здесь
   заданы бренд-заливкой и белым, а не токенами поверхности: они сюда не доходят. */
.chat-banner svg { width: 18px; height: 18px; }
.chat-banner-badge {
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #fff;
    color: var(--lt-accent);
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}

/* Переписка */
.chat-log {
    max-height: 420px;
    overflow-y: auto;
    padding: 12px;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    background: var(--lt-bg);
}
.chat-msg { margin-bottom: 10px; max-width: 72%; }
.chat-msg--mine { margin-left: auto; text-align: right; }
.chat-msg-body {
    display: inline-block;
    white-space: pre-wrap;
    padding: 8px 12px;
    border-radius: 10px;
    border: 1px solid var(--lt-border);
    background: var(--lt-surface);
    text-align: left;
    word-break: break-word;
}
.chat-msg--mine .chat-msg-body {
    background: var(--lt-accent);
    border-color: var(--lt-accent);
    color: #fff;
}
.chat-msg-time { margin-top: 2px; font-size: 11px; color: var(--lt-text-muted); }
.chat-send { display: flex; gap: 8px; margin-top: 12px; }
.chat-send textarea { flex: 1; padding: 8px; border: 1px solid var(--lt-border); border-radius: 8px; font: inherit; }
.admin-row--active { background: var(--lt-bg); }

/* Лента оповещений */
.feed-item {
    padding: 14px 16px;
    margin-bottom: 10px;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    background: var(--lt-surface);
}
.feed-item--unread { border-left: 3px solid var(--lt-accent); }
.feed-item-head { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.feed-item-date { color: var(--lt-text-muted); font-size: 12px; white-space: nowrap; }
.feed-item-body { margin: 8px 0 0; white-space: pre-wrap; }
.feed-item-author { margin: 8px 0 0; color: var(--lt-text-muted); font-size: 12px; }

/* Кнопка, которая существует только чтобы поймать Enter: первая submit-кнопка формы — это то,
   что срабатывает по неявной отправке. Скрыта от глаз и от программ чтения с экрана, но остаётся
   рабочей кнопкой для браузера. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Ссылка-кнопка на странице входа: по разметке это submit другой формы-обработчика, по виду —
   обычная ссылка, потому что рядом стоит настоящая. */
.login-link-button {
    padding: 0;
    border: 0;
    background: none;
    color: var(--lt-link);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Колокольчик оповещений в верхней панели, левее имени учётной записи. Это не раздел, куда ходят,
   а сигнал: он должен быть виден со всех страниц, поэтому и переехал из левого меню. */
.topbar-bell {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding: 6px;
    border-radius: 8px;
    color: var(--lt-text-muted);
    line-height: 0;
}
.topbar-bell:hover { color: var(--lt-text); background: var(--lt-bg); }
.topbar-bell svg { width: 20px; height: 20px; }
.topbar-bell-badge {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--lt-error);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

/* Второй уровень вкладок (категории документов внутри «Кабинета»). Две одинаковые полосы подряд
   читаются как соперничающие — этой оставляем только подчёркивание активной. */
.admin-tabs--sub {
    margin-top: -6px;
    border-bottom: 0;
}
.admin-content .admin-tabs--sub .admin-tab {
    padding: 4px 2px;
    margin-right: 12px;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
}
.admin-content .admin-tabs--sub .admin-tab--active {
    background: none;
    color: var(--lt-text);
    border-bottom-color: var(--lt-accent);
    font-weight: 600;
}


/* Сетка заполнения гигиенического журнала.

   Цвет статуса берётся из -text токенов: они рассчитаны как цвет НА поверхности и переопределены
   в тёмной теме, тогда как базовые --lt-ok/warn/error — заливки под белый текст. Подложка клетки
   замешивается из того же токена через color-mix; если браузер его не знает, объявление просто
   отбрасывается и остаётся обычная поверхность с цветной обводкой — сетка читается и так. */
.fill-grid-wrap {
    overflow-x: auto;
}

.fill-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(54px, 1fr));
    gap: 4px;
    max-width: 520px;
}

.fill-grid-weekday {
    font-size: 11px;
    color: var(--lt-text-muted);
    text-align: center;
}

.fill-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    min-height: 48px;
    padding: 6px 2px 4px;
    border: 1px solid var(--lt-border);
    border-radius: 8px;
    background: var(--lt-surface);
    color: var(--lt-text);
    text-decoration: none;
}

.fill-cell:hover {
    border-color: var(--lt-accent);
}

.fill-cell--blank {
    min-height: 0;
    border: 0;
    background: none;
}

.fill-cell-day {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
}

.fill-cell-count {
    font-size: 11px;
    color: var(--lt-text-muted);
    font-variant-numeric: tabular-nums;
}

.fill-cell-marks {
    display: flex;
    gap: 3px;
    min-height: 6px;
}

.fill-cell--full {
    border-color: var(--lt-ok-text);
    background: color-mix(in srgb, var(--lt-ok-text) 12%, var(--lt-surface));
}

.fill-cell--partial {
    border-color: var(--lt-warn-text);
    background: color-mix(in srgb, var(--lt-warn-text) 14%, var(--lt-surface));
}

.fill-cell--empty {
    border-color: var(--lt-error-text);
    background: color-mix(in srgb, var(--lt-error-text) 12%, var(--lt-surface));
}

/* День без смены и день, который ещё не наступил: пунктир вместо цвета — это не состояние
   журнала, а отсутствие повода для записи. */
.fill-cell--idle {
    border-style: dashed;
    color: var(--lt-text-muted);
}

.fill-cell--open {
    outline: 2px solid var(--lt-accent);
    outline-offset: 1px;
}

.fill-mark {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
}

.fill-mark--suspended {
    background: var(--lt-error-text);
}

.fill-mark--pending {
    background: var(--lt-warn-text);
}

/* Запись по человеку вне графика — не ошибка заполнения, а расхождение со сменой: отдельный
   знак, чтобы его не путали с отстранением и с неподтверждённой самозаписью. */
.fill-mark--unscheduled {
    background: var(--lt-surface);
    border: 1px solid var(--lt-text-muted);
}

.fill-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    align-items: center;
    margin-top: 10px;
}

.fill-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.fill-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 3px;
    border: 1px solid var(--lt-border);
}

.fill-swatch--full {
    border-color: var(--lt-ok-text);
    background: color-mix(in srgb, var(--lt-ok-text) 12%, var(--lt-surface));
}

.fill-swatch--partial {
    border-color: var(--lt-warn-text);
    background: color-mix(in srgb, var(--lt-warn-text) 14%, var(--lt-surface));
}

.fill-swatch--empty {
    border-color: var(--lt-error-text);
    background: color-mix(in srgb, var(--lt-error-text) 12%, var(--lt-surface));
}

.fill-swatch--idle {
    border-style: dashed;
}

/* Визард регистрации.

   Степпер здесь не украшение: форма из двенадцати шагов без видимого пути выглядит бесконечной, и
   её бросают на середине. Пройденное, текущее и пропущенное различаются цветом, чтобы в конце было
   видно, что осталось незаполненным. */
.wizard-shell {
    width: min(920px, 100%);
    margin: 24px auto;
    padding: 24px;
    background: var(--lt-surface);
    border: 1px solid var(--lt-border);
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.wizard-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 10px;
    list-style: none;
    margin: 0;
    padding: 0;
    border-bottom: 1px solid var(--lt-border);
    padding-bottom: 16px;
}

.wizard-step {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--lt-text-muted);
}

.wizard-step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 1px solid var(--lt-border);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.wizard-step--done .wizard-step-number {
    background: var(--lt-ok-text);
    border-color: var(--lt-ok-text);
    color: var(--lt-white);
}

.wizard-step--current {
    color: var(--lt-text);
    font-weight: 600;
}

.wizard-step--current .wizard-step-number {
    background: var(--lt-accent);
    border-color: var(--lt-accent);
    color: var(--lt-white);
}

/* Пропущенный шаг не ошибка — к нему можно вернуться из кабинета. Но отличать его от заполненного
   нужно: в итоговой сводке это единственный способ увидеть, чего не хватает. */
.wizard-step--skipped .wizard-step-number {
    border-style: dashed;
    border-color: var(--lt-warn-text);
    color: var(--lt-warn-text);
}

/* Пройденный шаг кликабелен — по нему возвращаются к уже заполненному. Подчёркивание появляется
   по наведению: тринадцать подчёркнутых строк подряд читаются как сплошная рябь. */
.wizard-step--back a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
}

.wizard-step--back a:hover .wizard-step-title,
.wizard-step--back a:focus-visible .wizard-step-title {
    text-decoration: underline;
}

/* Объяснение файла импорта. Показываем не правила словами, а сам лист Excel: вкладка снизу,
   буква колонки, номера строк. Человек сверяет картинку с тем, что у него открыто, и не
   переводит текст в действия. */
.import-guide {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-items: flex-start;
}

.import-guide-sheets {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.import-sheet {
    border: 1px solid var(--lt-border);
    border-radius: 4px;
    overflow: hidden;
    background: var(--lt-white);
}

.import-sheet-tab {
    background: var(--lt-accent);
    color: var(--lt-white);
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
}

.import-sheet-grid {
    border-collapse: collapse;
    font-size: 12px;
}

.import-sheet-grid th,
.import-sheet-grid td {
    border: 1px solid var(--lt-border);
    padding: 3px 8px;
    text-align: left;
}

.import-sheet-rownum,
.import-sheet-col {
    background: var(--lt-bg);
    color: var(--lt-text-muted);
    font-weight: 400;
    text-align: center;
    min-width: 22px;
}

.import-sheet-header {
    font-weight: 600;
}

.import-sheet-value {
    color: var(--lt-text-muted);
    font-style: italic;
    min-width: 180px;
}

/* Колонка примеров показана блёклой: её содержимое в справочник не попадает, и это должно быть
   видно раньше, чем человек прочтёт правило. */
.import-sheet-ignored {
    opacity: 0.55;
}

.import-guide-rules {
    flex: 1 1 280px;
    margin: 0;
    padding-left: 18px;
    font-size: 13px;
    color: var(--lt-text-muted);
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.wizard-back {
    font-size: 13px;
}

.wizard-back a {
    color: var(--lt-text-muted);
}

.wizard-body {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.wizard-body .admin-form {
    max-width: none;
}

.wizard-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.wizard-actions .login-button {
    width: auto;
}

.wizard-lead {
    font-size: 14px;
    color: var(--lt-text);
    margin: 0;
}
