/* ============================================================
   Цветовые темы через CSS-переменные.
   :root = тёмная тема (значения по умолчанию).
   Светлая — либо по явному выбору (:root[data-theme="light"]),
   либо по системной, если юзер не выбирал (prefers-color-scheme).
   ПРАВИЛО: hex-цвета в разметке не хардкодить, только var(--…).
   ============================================================ */
:root {
    /* Поверхности */
    --bg:              #2b3138;   /* фон страницы */
    --surface:         #333843;   /* панели, шапка, попапы, zag-строки */
    --surface-2:       #464f5a;   /* поля ввода, вторичные кнопки */
    --surface-2-hover: #555e69;
    --row-even:        #383f48;
    --row-odd:         #2f353d;
    --border:          #2b3138;   /* границы ячеек таблиц (в тёмной теме = фон) */
    --border-2:        #464f5a;   /* границы попапов/полей */

    /* Текст */
    --text:        #4db6bc;   /* основной текст (в тёмной теме совпадает с акцентом) */
    --text-muted:  #b4b5b6;   /* ссылки, вторичный текст */
    --text-dim:    #6a7078;   /* третичный/подсказки */
    --text-bright: #eeeeee;   /* текст в полях ввода */
    --text-strong: #ffffff;   /* самый яркий текст на поверхности */

    /* Акценты */
    --accent:       #4db6bc;
    --accent-hover: #5cc7cd;
    --on-accent:    #ffffff;   /* текст на кнопках акцентного цвета */
    --danger:       #b64d4d;
    --danger-hover: #c75c5c;
    --ok:           #5cb85c;
    --warn:         #e6a04d;

    /* Приглушённый красный для признака «заблокирован». Отдельно от --danger:
       тот кричит на кнопках удаления, а тут это спокойная пометка состояния.
       В светлой теме НЕ переопределяется намеренно — оттенок средний по светлоте
       и одинаково читается на обоих фонах. */
    --blocked:      #b06a6a;
}

:root[data-theme="light"] {
    --bg:              #f4f5f7;
    --surface:         #ffffff;
    --surface-2:       #e7e9ee;
    --surface-2-hover: #dadde4;
    --row-even:        #eef0f3;
    --row-odd:         #f7f8fa;
    --border:          #e2e4e9;
    --border-2:        #d5d8df;

    --text:        #2b3138;
    --text-muted:  #5a6270;
    --text-dim:    #8a909a;
    --text-bright: #1f2430;
    --text-strong: #000000;

    --accent:       #2e9ba1;
    --accent-hover: #38aeb4;
    --on-accent:    #ffffff;
    --danger:       #c0392b;
    --danger-hover: #d0483a;
    --ok:           #3d9140;
    --warn:         #b9791b;
}
@media (prefers-color-scheme: light) {
    :root:not([data-theme]) {
        --bg:              #f4f5f7;
        --surface:         #ffffff;
        --surface-2:       #e7e9ee;
        --surface-2-hover: #dadde4;
        --row-even:        #eef0f3;
        --row-odd:         #f7f8fa;
        --border:          #e2e4e9;
        --border-2:        #d5d8df;

        --text:        #2b3138;
        --text-muted:  #5a6270;
        --text-dim:    #8a909a;
        --text-bright: #1f2430;
        --text-strong: #000000;

        --accent:       #2e9ba1;
        --accent-hover: #38aeb4;
        --on-accent:    #ffffff;
        --danger:       #c0392b;
        --danger-hover: #d0483a;
        --ok:           #3d9140;
        --warn:         #b9791b;
    }
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: sans-serif;
    margin: 0;
}
h1, h2, h3, h4, p {
    background: transparent;
    color: var(--accent);
}
h2, h3 { padding: 6px 12px; }
/* Название открытой сущности (группы) — крупнее обычного заголовка раздела */
h2.title-lg { font-size: 28px; }

A          { color: var(--text-muted); text-decoration: none; }
A:visited  { color: var(--text-muted); }
A:active   { color: var(--text-muted); }
A:hover    { color: var(--accent); }

/* ============ Формы ============ */
form input[type=text],
form input[type=url],
form input[type=email],
form input[type=password],
form input[type=number] {
    background: var(--surface-2);
    color: var(--text-bright);
    border: 1px solid var(--surface-2);
    border-radius: 5px;
    padding: 4px 8px;
}
form input[type=submit] {
    background: var(--accent);
    color: var(--on-accent);
    border: 1px solid var(--accent);
    border-radius: 5px;
    padding: 4px 12px;
    cursor: pointer;
}
form input[type=submit]:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

select, form select {
    background: var(--accent);
    color: var(--on-accent);
    border: 1px solid var(--accent);
    border-radius: 5px;
    padding: 3px 6px;
}
form textarea, textarea {
    background: var(--surface-2);
    color: var(--text-bright);
    border: 1px solid var(--surface-2);
    border-radius: 5px;
    padding: 4px 8px;
}
/* Поля формы одинаковой ширины у input и textarea — через класс, не через size/cols */
.field { width: 400px; box-sizing: border-box; }
/* Поле фильтра в action-bar — отдельным классом, а не инлайновой шириной:
   инлайн не переопределить в мобильной media-query. */
.filter-input { width: 220px; box-sizing: border-box; }

/* ============ Таблицы ============ */
TR.even   { background: var(--row-even); color: var(--accent); }
TR.noeven { background: var(--row-odd);  color: var(--accent); }
TR.zag    { background: var(--surface);  color: var(--text-muted); font-size: large; font-weight: bold; }

.datalist        { border-collapse: collapse; }
.datalist td     { padding: 4px 10px; border-bottom: 1px solid var(--border); height: 22px; box-sizing: border-box; }
.datalist tr.zag td { font-weight: bold; }
/* Колонки офисных дней: узкие, галочка по центру. width:1px + nowrap — колонка
   сжимается по содержимому, остаток ширины забирают логин и ФИО. */
.daycell { width: 1px; white-space: nowrap; text-align: center; }
.daybox  { width: 18px; height: 18px; margin: 0; cursor: pointer; accent-color: var(--accent); }
/* Отчество в списке юзеров — правится прямо в ячейке. Узкое и без рамки, чтобы
   строка не рябила полями: рамка проявляется только под курсором и в фокусе.
   Класс назван по СМЫСЛУ поля, а не по виду: он же служит крючком скрипту
   в admin/users.php, который вешает на эти поля сохранение по blur. Поэтому .midname
   носят ТОЛЬКО поля отчества. До 28.09.2026 класс звался .midbox и означал «вид поля» —
   поле локального пароля взяло его ради вида и попало под то же сохранение: набранный
   пароль уезжал в /admin/middle.php, а поле обнулялось до отправки. */
.midname  { width: 130px; box-sizing: border-box; background: transparent;
            border: 1px solid transparent; border-radius: 4px;
            color: var(--accent); padding: 2px 6px; }
.midname:hover, .midname:focus { background: var(--surface-2); border-color: var(--surface-2);
                                 color: var(--text-bright); outline: none; }
/* Блокировка — не «ещё одна галочка», а пометка состояния: красит галочку и свой
   заголовок-замочек. Правило ниже .daybox, чтобы перебить его accent-color. */
.blockbox    { accent-color: var(--blocked); }
.ico-blocked { color: var(--blocked); }
/* Пометка «этот email закреплён за несколькими» в списке юзеров. Цвет предупреждающий,
   а не красный: красный в проекте означает «удалить», а тут ничего не сломано —
   просто такой адрес не пустит никого, пока админ не оставит одного незаблокированным. */
.ico-dup     { color: var(--warn); }

/* Локальный пароль в списке юзеров — колонка «Локальный вход» (28.09.2026).
   Кнопка-состояние «задать»/«задан», по клику раскрывается поле с «ок» и «снять».
   Само поле — вид как у .midname (отчество), но своим правилом; .locbox нужен
   и как отдельный признак для скрипта, и чтобы поле нельзя было спутать с отчеством. */
.locpick       { display: none; align-items: center; gap: 4px; }
.locpick.on    { display: inline-flex; }
/* Поле локального пароля. Вид — как у .midname (отчество), но своим правилом, а не чужим
   классом: классы в этом проекте поведенческие, а .midname — крючок скрипта отчества.
   28.09.2026 поле пароля носило то же имя ради вида, попало под сохранение по blur —
   и набранное уезжало в /admin/middle.php, а поле возвращалось к пустому значению
   до отправки. Своё поле — свой класс. */
.locbox        { width: 130px; box-sizing: border-box; background: transparent;
                 border: 1px solid transparent; border-radius: 4px;
                 color: var(--accent); padding: 2px 6px; }
.locbox:hover, .locbox:focus { background: var(--surface-2); border-color: var(--surface-2);
                               color: var(--text-bright); outline: none; }
/* Капкан тот же, что у .vac-card ниже: правило .btn { display: inline-block } перебивает
   браузерное [hidden] { display: none }, поэтому кнопке «снять» правило нужно своё —
   без него она осталась бы на виду и тогда, когда пароля нет. */
.locdrop[hidden] { display: none; }
/* Светодиод локального входа — гаснет и зажигается рядом с кнопкой. Горит зелёным,
   только когда человек РЕАЛЬНО может войти по короткому логину: пароль задан, учётка
   не удалена в центре и не заблокирована. Погасший — серая точка с ободком, а не пустое
   место: колонка читается и без огонька, а причина видна в подсказке.
   Цвет — из --ok: в проекте он и значит «всё в порядке». Без свечения он был бы неотличим
   от просто зелёной точки в соседних строках. */
.locled          { display: inline-block; width: 9px; height: 9px; margin-right: 6px;
                   border-radius: 50%; vertical-align: middle; box-sizing: border-box;
                   background: var(--surface-2-hover); box-shadow: inset 0 0 0 1px var(--border); }
.locled.on       { background: var(--ok); box-shadow: 0 0 6px var(--ok); }

/* Обёртка широких списков: пока таблица влезает — ничего не меняется, а на узком
   экране скроллится она сама, а не вся страница. Ставится вокруг таблиц со списками. */
.table-scroll { overflow-x: auto; max-width: 100%; }

/* ============ Верхнее меню / sidebar ============ */
#gormenutbl {
    background: var(--surface);
    border-bottom: 1px solid var(--bg);
}
#gormenutd    { padding-right: 12px; }
#gormenuul td { padding: 0 6px; }
#gormenuul a  { color: var(--text-muted); padding: 6px 12px; border-radius: 4px; display: inline-block; }
#gormenuul a:hover  { color: var(--accent); }
#gormenuul a.active { color: var(--accent); background: var(--bg); }
/* Разделы в верхнем меню — только иконка, подпись в title.
   Иконки из icons/*.svg тащат инлайновый margin-right для соседства с текстом — здесь он лишний. */
#gormenuul a.navico     { padding: 7px 9px; display: inline-flex; align-items: center; }
#gormenuul a.navico svg { margin: 0 !important; width: 20px; height: 20px; }
#tdname       { color: var(--text-muted); padding-right: 12px; }
#tdexit a     { color: var(--text-muted); }
#tdexit a:hover { color: var(--accent); }

.greyblock0 { padding: 8px 12px; }
.greyblock1 {
    background: var(--surface);
    border-radius: 6px;
    padding: 8px 12px;
}
.greyblock1 h3 { margin: 4px 0; font-size: 15px; }
.greyblock1 h4 { margin: 2px 0; font-size: 14px; font-weight: normal; }

/* Выбранный пункт sidebar — той же подсветкой, что активный раздел в верхнем меню
   (#gormenuul a.active): цвет акцента на затемнённом фоне. Прежняя полоска слева
   убрана по просьбе юзера. Отступы и скругление — чтобы фон не лип к тексту. */
.greyblock1 a.sb-active { color: var(--accent); background: var(--bg);
                          border-radius: 4px; padding: 2px 6px; margin-left: -6px; }

/* table-layout: fixed — обязателен. При `auto` ячейка #mainblock растягивается по
   самому широкому содержимому, и `max-width:100%` у внутренних .table-scroll /
   .vac-scroll упирается в уже разъехавшуюся ячейку: вместо внутренней прокрутки
   уезжает ВСЯ страница. Ширины колонок заданы в разметке (#sidebar width=180),
   fixed берёт их и оставляет остаток второй ячейке.
   Следствие: всё, что шире ячейки, обязано лежать в .table-scroll — иначе вывалится
   за край. Поэтому обёрнуты все списочные таблицы, а не только длинные.
   На телефоне правило не работает и не нужно: там ячейки переведены в display:block. */
#layout       { table-layout: fixed; }
#mainblock    { padding: 10px 20px; }
#mainblockdiv { min-height: 200px; }

/* ============ Кнопки ============ */
/* font наследуем явно: <button> иначе берёт системный (Arial 13.3px), а <a> — шрифт body,
   и одинаково размеченные кнопки расходятся по размеру текста */
.btn { display: inline-block; padding: 6px 14px; border-radius: 5px; cursor: pointer; text-decoration: none;
       font-family: inherit; font-size: inherit; }
.btn-primary   { background: var(--accent); color: var(--on-accent) !important; border: 1px solid var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-danger    { background: var(--danger); color: var(--on-accent) !important; border: 1px solid var(--danger); }
.btn-danger:hover { background: var(--danger-hover); border-color: var(--danger-hover); }
.btn-secondary { background: var(--surface-2); color: var(--text-muted) !important; border: 1px solid var(--surface-2); }
.btn-secondary:hover { background: var(--surface-2-hover); border-color: var(--surface-2-hover); color: var(--on-accent) !important; }
.btn:disabled, button.btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.btn:disabled:hover { background: inherit; }
.btn.busy { opacity: 0.7; pointer-events: none; cursor: wait; }
.btn-lg { padding: 8px 16px; font-size: 15px; }
.btn-block { display: block; width: 100%; box-sizing: border-box; }
/* Кнопка с одной иконкой (без текста) — убираем правый отступ у SVG */
.btn-icon      { padding: 4px 8px; }
.btn-icon svg  { margin-right: 0 !important; display: block; }

/* Вкладки внутри страницы (журнал: «Дежурства | Отпуска»). Оформлены КАК МЕНЮ,
   а не кнопками: невыбранное серое, выбранное — акцентом на затемнённом фоне,
   ровно как активный раздел в верхнем меню и выбранный пункт sidebar. Указание
   юзера 27.08.2026; залитые кнопки рядом с заголовком перетягивали внимание. */
.tabs          { display: inline-flex; gap: 4px; }
.tabs a        { color: var(--text-muted); padding: 6px 12px; border-radius: 4px;
                 text-decoration: none; }
.tabs a:hover  { color: var(--accent); }
.tabs a.active { color: var(--accent); background: var(--bg); }

/* Сегментированный переключатель — кнопки без промежутка */
.seg { display: inline-flex; }
.seg .btn { border-radius: 0; padding: 4px 12px; }
.seg .btn:first-child { border-radius: 5px 0 0 5px; }
.seg .btn:last-child  { border-radius: 0 5px 5px 0; }

/* action-bar — все элементы на одной линии по центру */
.action-bar      { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.action-bar form { margin: 0; }

/* Двухколоночная раскладка: форма слева, список справа. При узком окне колонки перескакивают. */
.two-col      { display: flex; gap: 40px; align-items: flex-start; flex-wrap: wrap; }
.two-col-left { flex: 0 0 auto; }
.two-col-main { flex: 1 1 auto; min-width: 400px; }

/* Спиннер для «идёт долгая операция» — вращающееся кольцо в цвете кнопки */
.spinner {
    display: inline-block; width: 14px; height: 14px;
    border: 2px solid currentColor; border-top-color: transparent;
    border-radius: 50%; vertical-align: middle;
    animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ============ Логин ============ */
body.text-center { text-align: center; }
.form-signin {
    display: inline-block;
    width: 100%;
    max-width: 340px;
    padding: 30px 20px;
    margin-top: 80px;
    background: var(--surface);
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0,0,0,0.3);
    text-align: left;
}
.form-signin h1 {
    text-align: center;
    font-size: 18px;
    color: var(--accent);
    margin-bottom: 20px;
}
.form-control {
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 10px;
    padding: 8px 10px;
    background: var(--surface-2) !important;
    color: var(--text-bright) !important;
    border: 1px solid var(--surface-2) !important;
    border-radius: 5px;
    font-size: 14px;
}

/* Flash-уведомление: фиксировано в правом нижнем углу, контент не сдвигает. */
.flash-toast {
    position: fixed;
    bottom: 16px;
    right: 16px;
    padding: 5px 12px;
    background: var(--surface);
    color: var(--accent);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    font-size: 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
    z-index: 1000;
    transition: opacity 0.5s;
}
.flash-toast.fade-out { opacity: 0; pointer-events: none; }
.flash-toast.err { color: var(--danger-hover); border-left-color: var(--danger-hover); }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
.text-muted { color: var(--text-dim); text-align: center; font-size: 12px; }
.hint  { color: var(--text-dim); font-size: 12px; }
.mt-5 { margin-top: 24px; }
.mb-3 { margin-bottom: 12px; }

/* ============ Помощь ============ */

.help-lead  { max-width: 720px; color: var(--text-muted); }
.help-note  { max-width: 720px; color: var(--text-muted); font-size: 14px; }

/* Текст справки. Заголовки h3 в проекте акцентного цвета — здесь этого достаточно,
   чтобы делить страницу на части без рамок и подложек. */
.help-body            { max-width: 720px; }
.help-body h3         { margin: 22px 0 6px; padding-left: 0; font-size: 17px; }
.help-body p          { margin: 6px 0; color: var(--text-muted); font-size: 14px; }
.help-body ul,
.help-body ol         { margin: 6px 0; padding-left: 22px; }
.help-body li         { margin: 4px 0; color: var(--text-muted); font-size: 14px; }
.help-body b          { color: var(--text-bright); }
.help-body a          { color: var(--accent); }

/* Перечень страниц раздела на заглавной */
.help-index    { display: flex; flex-wrap: wrap; gap: 12px; margin: 12px 0; }
.help-card     { display: flex; gap: 10px; align-items: flex-start; max-width: 420px;
                 background: var(--surface); border-radius: 8px; padding: 12px 16px; }
.help-card:hover   { background: var(--surface-2); }
.help-card-ico svg { width: 22px; height: 22px; margin-right: 0 !important; }
.help-card-txt     { font-size: 14px; }

/* Установка на телефон: QR слева, шаги справа; на узком экране одно под другим. */
.app-top     { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start; margin: 12px 0 20px; }
.app-qr      { flex: 0 0 auto; text-align: center; }
.app-steps   { flex: 1 1 320px; display: flex; flex-direction: column; gap: 12px; }
.step-block  { background: var(--surface); border-radius: 8px; padding: 12px 16px; }
.step-block h4  { margin: 0 0 8px; font-size: 14px; padding-left: 0; }
.step-block ol  { margin: 0; padding-left: 20px; }
.step-block li  { margin: 4px 0; font-size: 14px; color: var(--text-muted); }

/* Единственный жёстко заданный цвет в проекте: подложка под QR всегда белая.
   Сканеру нужен светлый фон, и в тёмной теме код на тёмном попросту не читается. */
.qr-card     { --qr-bg: #ffffff; background: var(--qr-bg); padding: 12px;
               border-radius: 10px; display: inline-block; line-height: 0; }
.qr-card img { width: 210px; height: 210px; display: block; }
.qr-link     { display: block; margin-top: 8px; color: var(--accent); font-size: 14px; }
.qr-hint     { color: var(--text-dim); font-size: 12px; margin-top: 2px; }

/* ============ Календарь дежурств ============ */

/* Стрелки по бокам от названия месяца. h3 внутри флекса гасим по вертикали,
   иначе его собственные отступы разносят строку. */
.month-nav    { margin: 10px 0 6px; }
.month-nav h3 { margin: 0; }

/* Сетка месяца: 7 равных колонок, недели с понедельника. */
.cal            { border-collapse: collapse; table-layout: fixed; width: 100%; max-width: 720px; }
.cal td         { border: 1px solid var(--border-2); vertical-align: top; padding: 3px;
                  width: 14.28%; height: 72px; }
.cal tr.zag td  { height: auto; text-align: center; font-weight: bold; padding: 4px 3px; }
.cal td.wend    { background: var(--row-odd); }
/* Клетки-заполнители по краям сетки. Границы у них НЕ красим в цвет фона, а убираем
   стилем: при border-collapse общую границу двух соседей выигрывает верхняя/левая
   клетка, поэтому крашеная граница пустой клетки съедала левый край 1-го числа.
   `none` — низший приоритет при схлопывании, так что побеждает рамка соседа.
   Именно `none`, не `hidden`: `hidden` наоборот убил бы границу с обеих сторон. */
.cal td.empty   { background: transparent; border-style: none; }
.cal td.today   { outline: 2px solid var(--accent); outline-offset: -2px; }
/* День, которым снимок в журнале расходится с текущей раскладкой. Внутренняя рамка,
   а не outline: иначе спорила бы с обводкой «сегодня», когда обе на одной клетке. */
.cal td.changed { box-shadow: inset 0 0 0 2px var(--warn); }
/* Число дня — не подсказка, а ориентир по сетке, поэтому --text-muted, а не --text-dim */
.daynum         { font-size: 15px; color: var(--text-muted); line-height: 1; margin-bottom: 4px; }

.chip {
    display: inline-block;
    padding: 1px 5px;
    margin: 0 2px 2px 0;
    border-radius: 4px;
    font-size: 11px;
    line-height: 16px;
    color: #ffffff;
    cursor: default;
    user-select: none;
    -webkit-user-select: none;
}
/* Хват курсором и перехват тача — только в редактируемом календаре. Для того, кто
   правами не обладает, сетка обычная таблица: touch-action:none у него отнимал бы
   прокрутку страницы пальцем по плашке, ничего не давая взамен. */
.cal.editable .chip { cursor: grab; touch-action: none; }
/* Рядовой участник группы правит только свои дни: хват и перехват тача остаются
   лишь на его плашках, чужие ведут себя как обычный текст. Классы вешает
   duty_grid_html(), жест глушит swap.js, право проверяет сервер. */
.cal.editable.self-edit .chip      { cursor: default; touch-action: auto; }
.cal.editable.self-edit .chip-mine { cursor: grab; touch-action: none; }
/* Плашка в клетке календаря — вдвое крупнее базовой и по центру клетки.
   Отдельным классом, а не селектором `.cal .chip`: призрак при перетаскивании
   висит в body, вне таблицы, и по вложенности размер бы потерял. В легенде
   плашки остаются базового размера. */
.chip-day {
    display: block;
    width: fit-content;
    margin: 2px auto 0;
    font-size: 22px;
    line-height: 26px;
    padding: 3px 9px;
    border-radius: 5px;
}
/* «ОТПУСК» в клетке календаря дежурств: дежурство попало на отпуск этого человека.
   Красный тут уместен, хотя в остальном проекте он означает «удалить»: это не
   пометка состояния, а «так дежурства не будет» — прямое указание юзера. */
.on-vac { display: block; text-align: center; color: var(--danger);
          font-size: 10px; font-weight: bold; letter-spacing: 0.5px; line-height: 12px; }

.chip-over     { outline: 2px dashed var(--text-strong); outline-offset: 1px; }
.chip-dragging { opacity: 0.35; }
/* Призрак под курсором: не должен перехватывать elementFromPoint, иначе цель
   всегда находилась бы под самим призраком. */
.chip-ghost {
    position: fixed;
    z-index: 1200;
    pointer-events: none;
    transform: translate(-50%, -50%);
    opacity: 0.9;
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}

/* Отступы строки легенды и gap подобраны в паре: подложка у сегодняшнего дежурного
   (.legend-now) не должна липнуть к тексту, а расстояние между строками — остаться
   прежним. Меняешь одно — пересчитай второе: 4px gap + 2×5px padding = прежние 14px. */
.legend        { display: flex; flex-wrap: wrap; gap: 2px 4px; margin: 8px 0; font-size: 12px; }
.legend-item   { display: inline-flex; align-items: center; gap: 5px; padding: 2px 5px; color: var(--text-muted); }
/* Вся строка легенды кликабельна — по ней показываются контакты человека.
   Курсор задаётся на .legend-item, а не на .chip: плашка внутри строки, и своё
   `cursor: default` перебивало бы указатель ровно там, куда целятся в первую очередь. */
.legend-item   { cursor: pointer; }
.legend .chip  { margin: 0; }
.legend-picked { color: var(--text-strong); }

/* Кто дежурит прямо сейчас (дежурные сутки идут с 9 утра до 9 утра). В сетке этот
   день обведён рамкой, но в легенде обводка встала бы вплотную к плашке и читалась
   бы как ещё одна рамка вокруг цвета — поэтому здесь подложка акцентом на прозрачном:
   она ложится на любой фон и не требует своего цвета в каждой теме. */
.legend-now    { background: color-mix(in srgb, var(--accent) 20%, transparent);
                 border-radius: 4px; color: var(--text-strong); font-weight: 600; }

/* Карточка контактов под легендой. Одна на всех, см. скрипт в calendar/duty.php. */
.contact-card {
    display: inline-block; margin: 2px 0 8px; padding: 8px 12px;
    background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 6px;
    font-size: 13px; line-height: 1.5;
}
.contact-card b { display: block; color: var(--text-strong); }
/* Счётчик дней: замена баланс ломает намеренно, и перекос должен быть заметен. */
.daycount      { color: var(--text-strong); }

/* Список замены — один на страницу, JS кладёт его поверх кликнутой клетки.
   min-width, чтобы ФИО читались: клетка ~50px, список в неё не поместился бы. */
.repl-sel { position: fixed; z-index: 1300; min-width: 160px; max-width: 90vw; }

/* Палитра дежурных: 12 цветов, закреплены за юзером по id. Красного нет намеренно —
   в проекте он означает «удалить». Одинаковы в обеих темах: текст на плашках белый,
   и эти оттенки достаточно тёмные, чтобы читаться и на светлом, и на тёмном фоне. */
.duty-c0  { background: #2a9d8f; }
.duty-c1  { background: #3d7ea6; }
.duty-c2  { background: #4c6fbf; }
.duty-c3  { background: #5f5fae; }
.duty-c4  { background: #7a5aa8; }
.duty-c5  { background: #9161a8; }
.duty-c6  { background: #6b8e23; }
.duty-c7  { background: #3f8f5a; }
.duty-c8  { background: #2f8f8f; }
.duty-c9  { background: #5b7083; }
.duty-c10 { background: #8a6d3b; }
.duty-c11 { background: #4f7942; }


/* Перетаскивание строк за ручку (состав группы в админке). touch-action:none —
   иначе палец скроллит страницу вместо перетаскивания; висит только на ручке,
   по остальной строке прокрутка работает как обычно. */
.row-drag { width: 24px; text-align: center; color: var(--text-dim);
            cursor: grab; touch-action: none; }
.row-drag:hover      { color: var(--text-muted); }
tr.row-dragging      { opacity: 0.5; }
tr.row-dragging .row-drag { cursor: grabbing; }

/* ============================================================
   Отпуска — лента год × человек (calendar/vacation.php).
   Строка на человека, колонка на день: отпуска накладываются, и параллельные
   дорожки показывают это сразу, а отпуск через границу месяца остаётся одной
   полосой. Год в экран не влезает принципиально, поэтому лента прокручивается
   вбок, а колонка с людьми стоит на месте (sticky).
   ============================================================ */

/* Ширина дня — единственная ручка, которой лента настраивается под экран,
   и правится она ТОЛЬКО здесь. На телефоне она БОЛЬШЕ, чем на десктопе:
   там в неё целятся пальцем (нужно ~15 дней в поле зрения), а на большом
   экране ценнее обзор. */
.vac-scroll { --vac-day: 20px; --vac-name: 185px;
              overflow-x: auto; overflow-y: hidden; max-width: 100%; }

/* separate, а не collapse: у схлопнутых границ липкая колонка теряет свою рамку
   при прокрутке — общая граница достаётся соседу, который уезжает. */
.vac    { border-collapse: separate; border-spacing: 0; table-layout: fixed; }
.vac td { padding: 0; height: 28px; box-sizing: border-box; }

.vac .vac-name {
    position: sticky; left: 0; z-index: 2;
    width: var(--vac-name); min-width: var(--vac-name); max-width: var(--vac-name);
    background: var(--surface); border-right: 1px solid var(--border-2);
    padding: 0 6px; white-space: nowrap; overflow: hidden;
}
/* Строка колонки — flex: плашка, «Фамилия И.» и счётчик в один ряд. Счётчик стоял
   на float:right и у длинной фамилии («Правдолюбов А.») срывался на вторую строку,
   разгоняя дорожку по высоте. Flex — на вложенном div, а не на самой ячейке: у td
   он ломает табличную раскладку и липкость колонки. */
.vac .vac-name-in { display: flex; align-items: center; gap: 6px; }
.vac .vac-name .chip { margin: 0; flex: none; }
/* «Фамилия И.» должна влезать в одну строку — под это и подобрана --vac-name.
   Появится фамилия длиннее — увеличивать переменную, а не резать текст: по колонке
   ищут свою дорожку, обрезанная фамилия для этого бесполезна. Полное ФИО остаётся
   в title ячейки. */
.vac .vac-fio        { color: var(--text-muted); flex: 1 1 auto;
                       overflow: hidden; text-overflow: ellipsis; }
.vac .vac-name .daycount { flex: none; color: var(--text-dim); }

.vac .d, .vac-ticks td { width: var(--vac-day); min-width: var(--vac-day); }
/* Сетка: черта между днями и между дорожками. Берём --border-2, а НЕ --border:
   в тёмной теме --border совпадает с фоном страницы (так задумано для обычных
   таблиц), и линии были бы невидимы. */
.vac .d, .vac-ticks td { border-right: 1px solid var(--border-2); }
.vac .vac-row td       { border-bottom: 1px solid var(--border-2); }
.vac .vac-row:last-child td { border-bottom: none; }
/* Выходные. НЕ --row-odd, как в сетке дежурств: там клетка крупная и еле заметного
   оттенка хватает, а в ленте колонка шириной в два десятка пикселей — полоса из него
   просто не читается. Берём нейтральный серый поверх фона: color-mix сам подстроится
   под тему, а строкой выше лежит запасной вариант для браузеров без него. */
.vac .wend   { background: var(--row-even); }
.vac .wend   { background: color-mix(in srgb, var(--text-dim) 18%, transparent); }
/* «Сегодня» — вертикальная черта, а не заливка: заливка спорила бы с полосой отпуска. */
.vac .today  { box-shadow: inset 2px 0 0 var(--accent); }

.vac-months td { text-align: center; font-size: 14px; color: var(--text-muted);
                 border-right: 1px solid var(--border-2); padding: 3px 0; }
/* Число в КАЖДОЙ клетке — иначе по ленте не сориентироваться. Отсюда и мелкий
   кегль с центрированием: двузначное число должно влезать в --vac-day. Станет день
   уже — числа придётся прореживать обратно. */
.vac-ticks  td { text-align: center; font-size: 10px; color: var(--text-dim);
                 height: 16px; overflow: hidden; padding: 0; }
.vac-months .vac-name, .vac-ticks .vac-name { border-right: 1px solid var(--border-2); }

/* Полоска отпуска. Лежит ВНУТРИ клетки, потому что фон клетки занят выходными.
   Скругляются только края отрезка — иначе полоса рассыпается на таблетки. */
.vbar { display: block; height: 18px; margin: 5px 0; }
.v-start .vbar { border-radius: 9px 0 0 9px; margin-left: 1px; }
.v-end   .vbar { border-radius: 0 9px 9px 0; margin-right: 1px; }

/* Выделяемый отрезок. Рисуем фоном самой клетки, а не полоской внутри: полоска
   занята отпуском, и выделение поверх неё читалось бы как второй отпуск. */
.vac .d.sel { background: var(--accent); opacity: 0.55; }

/* Курсор и перехват тача — только там, где жест вообще возможен. У не-редактора
   ленты `editable` нет, у участника чужие дорожки помечены классом на строке. */
.vac.editable .d { cursor: crosshair; touch-action: pan-x pan-y; }

.vac-hint { color: var(--accent); }

/* Карточка отпуска: одна на страницу, правит и новый отрезок, и существующий.
   Не модальное окно с подложкой — она перекрыла бы ленту, а по ленте в этот момент
   как раз и сверяются. */
.vac-card {
    position: sticky; bottom: 8px; z-index: 1200;
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin: 10px 0; padding: 10px 12px;
    background: var(--surface); border: 1px solid var(--border-2); border-radius: 8px;
}
/* Правило `display:flex` выше перебивает браузерное `[hidden]{display:none}` —
   оно специфичнее. Без этой строки карточка висит внизу всегда, с пустыми датами. */
.vac-card[hidden] { display: none; }
.vac-card label { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
.vac-card input[type=date] { width: auto; }

/* Своя дорожка — чтобы в куче чужих полос сразу находить себя. */
.vac .vac-row.mine .vac-name { background: var(--row-even); }
.vac .vac-row.mine .vac-fio  { color: var(--text-strong); }

/* ============================================================
   Мобильная раскладка (телефон в портрете — до 700px).
   Каркас страницы табличный и с фиксированными width=180/110 в разметке,
   поэтому ячейки переводятся в display:block — иначе ширины не отдать.
   Что меняется: sidebar встаёт горизонтальной строкой под шапку,
   подписи в шапке прячутся (остаются иконки), поля занимают всю ширину,
   широкие списки скроллятся внутри .table-scroll.
   Всё, что шире 700px, этой секции не видит и выглядит как раньше.
   ============================================================ */
@media (max-width: 700px) {

    /* --- Шапка --- */
    #gormenutbl { height: auto; }
    /* Ячейка логотипа: width=180 из разметки прижимаем к содержимому */
    #gormenutbl > tbody > tr > td:first-child { width: 1px; padding: 4px 8px !important; }
    #gormenutd { padding-right: 4px; }
    #gormenuul td { padding: 0 2px; }
    #gormenuul a { padding: 6px 8px; }
    #gormenuul a.navico { padding: 8px 7px; }
    #tdname, #tdexit { width: 1px; padding-right: 4px; }
    #tdexit a { display: inline-flex; align-items: center; padding: 6px; }
    /* Подписи скрыты — иконкам правый отступ из SVG больше не нужен */
    .hide-narrow { display: none; }
    #tdname svg, #tdexit svg { margin-right: 0 !important; }

    /* --- Каркас: sidebar над контентом, а не слева --- */
    #layout, #layout > tbody, #layout > tbody > tr,
    #layout > tbody > tr > td { display: block; width: auto !important; }
    /* #layout впереди — иначе правило выше (#layout > tbody > tr > td) специфичнее и вернёт display:block */
    #layout #sidebar { display: flex; flex-wrap: wrap; align-items: flex-start; }
    #sidebar .greyblock0 { padding: 8px 4px 0 8px; }
    #sidebar .greyblock1 { display: flex; flex-wrap: wrap; gap: 2px 14px; padding: 6px 10px; }
    #sidebar h3, #sidebar h4 { margin: 0; }
    #mainblock { padding: 8px 10px; }

    /* --- Формы --- */
    .field, .filter-input { width: 100%; }
    .two-col { gap: 16px; }
    .two-col-main { min-width: 0; }
    /* 16px обязательны: при меньшем размере iOS зумит страницу на фокусе в поле */
    input, select, textarea { font-size: 16px; }
    /* select шириной с самый длинный вариант («логин — ФИО») распирает страницу вбок */
    select, .action-bar > * { max-width: 100%; }
    /* Пальцем попасть: цель не меньше ~36px по высоте */
    .btn { padding: 8px 14px; }
    .seg .btn { padding: 8px 12px; }
    form input[type=submit] { padding: 8px 14px; }

    /* --- Таблицы --- */
    .datalist td { padding: 4px 8px; }
    /* Галочку офисного дня надо попадать пальцем; колонки при этом жмём плотнее */
    .datalist td.daycell { padding: 4px 5px; }
    .daybox { width: 22px; height: 22px; }

    /* --- Помощь --- */
    /* QR ужимаем: 210px на 390-м экране с полями смотрится враспор, а сканируется
       код и в меньшем размере. */
    .qr-card img { width: 170px; height: 170px; }
    .app-top     { gap: 16px; }
    .help-card   { max-width: 100%; }

    /* --- Календарь --- */
    /* 7 колонок на ~390px — это ~52px на клетку. Ужимаем всё, что можно,
       и не даём таблице скроллиться вбок: месяц должен быть виден целиком. */
    .cal        { table-layout: fixed; }
    .cal td     { padding: 2px; height: 64px; }
    .cal tr.zag td { font-size: 12px; padding: 3px 2px; }
    .daynum     { font-size: 14px; }
    .chip       { font-size: 10px; padding: 1px 3px; margin: 0 1px 2px 0; line-height: 15px; }
    /* На ~52px клетки двум буквам при 20px остаётся ещё запас на паддинги */
    .chip-day   { font-size: 20px; line-height: 24px; padding: 2px 5px; margin: 1px auto 0; }
    /* Клетка тут 46×64px: полноразмерная надпись из неё вылезала. */
    .on-vac     { font-size: 8px; letter-spacing: 0; line-height: 10px; }

    /* Лента отпусков: ширина дня та же, что на десктопе (в неё целятся пальцем,
       нужно около 15 дней в поле зрения), а в колонке остаются ОДНИ ПЛАШКИ
       с инициалами — фамилия съедала треть экрана, который тут и так узкий.
       Решение юзера 27.08.2026; на компьютере фамилия остаётся. */
    .vac-scroll { --vac-name: 46px; }
    .vac .vac-fio            { display: none; }
    .vac .vac-name .chip     { display: inline-block; margin: 0; }
    .vac .vac-name .daycount { display: none; }   /* счётчик в колонку такой ширины не влезет */

    /* --- Прочее --- */
    h2 { font-size: 20px; }
    h2.title-lg { font-size: 24px; }
    .form-signin { margin-top: 24px; }
    /* Тост во всю ширину — в углу на телефоне он половину экрана не занимает, а мажет */
    .flash-toast { left: 12px; right: 12px; bottom: 12px; text-align: center; }
}
