/* Палитра и правила — по образцу фронта track-share (референс Яндекс Трекера):
   тёплый светло-серый фон, белые карточки, синий primary, rounded-md на пиллах/полях,
   hover-подсветка кликабельных элементов, плавные transition-colors. */

:root {
    --background: 60 8% 96%;
    --foreground: 0 0% 15%;

    --card: 0 0% 100%;
    --card-foreground: 0 0% 15%;

    --primary: 220 91% 57%;
    --primary-foreground: 0 0% 100%;

    --secondary: 60 5% 93%;
    --secondary-foreground: 0 0% 20%;

    --muted: 60 5% 94%;
    --muted-foreground: 45 3% 50%;

    --accent: 60 5% 94%;
    --accent-foreground: 0 0% 20%;

    --destructive: 0 72% 51%;
    --destructive-foreground: 0 0% 100%;

    --border: 45 6% 88%;
    --input: 45 6% 84%;
    --ring: 220 91% 57%;

    --radius-lg: 0.625rem;
    --radius-md: calc(0.625rem - 2px);
    --radius-sm: calc(0.625rem - 4px);

    /* Статусные тона — как в StatusPill track-share */
    --status-open: 45 3% 52%;
    --status-progress: 220 91% 57%;
    --status-review: 35 100% 45%;
    --status-done: 145 63% 37%;
    --status-cancelled: 0 65% 55%;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --background: 250 6% 18%;
        --foreground: 260 14% 91%;

        --card: 250 7% 20%;
        --card-foreground: 260 14% 91%;

        --primary: 223 87% 63%;
        --primary-foreground: 0 0% 100%;

        --secondary: 249 6% 24%;
        --secondary-foreground: 260 14% 91%;

        --muted: 248 7% 21%;
        --muted-foreground: 262 7% 67%;

        --accent: 249 6% 24%;
        --accent-foreground: 260 14% 91%;

        --destructive: 0 54% 42%;
        --destructive-foreground: 0 0% 100%;

        --border: 255 6% 28%;
        --input: 249 6% 24%;
        --ring: 223 87% 63%;

        --status-open: 262 7% 67%;
        --status-progress: 223 87% 63%;
        --status-review: 45 99% 65%;
        --status-done: 145 48% 58%;
        --status-cancelled: 0 70% 68%;
    }
}

/* Явный выбор темы через переключатель в сайдбаре (rail-btn theme-toggle) —
   имеет приоритет над prefers-color-scheme */
:root[data-theme="dark"] {
    --background: 250 6% 18%;
    --foreground: 260 14% 91%;

    --card: 250 7% 20%;
    --card-foreground: 260 14% 91%;

    --primary: 223 87% 63%;
    --primary-foreground: 0 0% 100%;

    --secondary: 249 6% 24%;
    --secondary-foreground: 260 14% 91%;

    --muted: 248 7% 21%;
    --muted-foreground: 262 7% 67%;

    --accent: 249 6% 24%;
    --accent-foreground: 260 14% 91%;

    --destructive: 0 54% 42%;
    --destructive-foreground: 0 0% 100%;

    --border: 255 6% 28%;
    --input: 249 6% 24%;
    --ring: 223 87% 63%;

    --status-open: 262 7% 67%;
    --status-progress: 223 87% 63%;
    --status-review: 45 99% 65%;
    --status-done: 145 48% 58%;
    --status-cancelled: 0 70% 68%;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: hsl(var(--background));
    color: hsl(var(--foreground));
    margin: 0;
    -webkit-font-smoothing: antialiased;
}

a { transition: color .15s, background-color .15s; }

h1 { font-size: 20px; font-weight: 600; margin: 0 0 16px; letter-spacing: -0.01em; }

.container { max-width: 960px; margin: 0 auto; }

/* ——— Каркас приложения: узкий икон-рейл слева (по образцу AppLayout.tsx track-share) + контент ——— */

.app-shell { display: flex; height: 100vh; }

/* Ширина зарезервирована ЗАРАНЕЕ, до того как sidebar.js вставит .rail внутрь —
   иначе на каждой навигации (обычные переходы между страницами, не SPA) контент
   на долю секунды показывается во всю ширину и резко "прыгает" влево на 56px,
   когда рейл дорисовывается. */
#sidebar-root { width: 56px; flex-shrink: 0; }

.app-main { flex: 1; min-width: 0; overflow-y: auto; padding: 32px 24px; }

.rail {
    position: relative;
    z-index: 50;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    width: 56px;
    flex-shrink: 0;
    padding: 12px 0;
    background: hsl(var(--card));
    border-right: 1px solid hsl(var(--border));
}

.rail-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-bottom: 8px;
    border-radius: var(--radius-lg);
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    /* Две буквы в квадрате 32 px: кегль меньше одиночной буквы, межбуквенное поджато,
       иначе «ТТ» упирается в края. */
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
}

.rail-nav { display: flex; flex-direction: column; align-items: center; gap: 4px; }

.rail-spacer { flex: 1; }

.rail-btn {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: var(--radius-lg);
    background: transparent;
    color: hsl(var(--muted-foreground));
    text-decoration: none;
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.rail-btn:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.rail-btn.active { background: hsl(var(--accent)); color: hsl(var(--foreground)); }

.rail-tooltip {
    position: absolute;
    left: 100%;
    top: 50%;
    margin-left: 8px;
    transform: translate(-4px, -50%);
    white-space: nowrap;
    background: hsl(230 15% 22% / 0.95);
    color: #fff;
    font-size: 12px;
    font-weight: 500;
    padding: 4px 9px;
    border-radius: var(--radius-md);
    box-shadow: 0 8px 20px hsl(0 0% 0% / 0.18);
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s, transform .15s;
}

.rail-btn:hover .rail-tooltip { opacity: 1; transform: translate(0, -50%); }

/* ——— Экран запроса админ-пароля ——— */

.login-main {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.login-main .password-gate { margin: 0; }

.password-gate {
    width: min(380px, 100%);
    margin: 0 auto;
    padding: 34px 30px;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    text-align: center;
    box-shadow: 0 10px 34px hsl(0 0% 0% / 0.12);
}

.password-gate .gate-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    margin: 0 auto 16px;
    border-radius: var(--radius-lg);
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 0.5px;
    box-shadow: 0 6px 16px hsl(var(--primary) / 0.35);
}

.password-gate h2 { font-size: 19px; font-weight: 600; margin: 0 0 4px; color: hsl(var(--foreground)); }
.password-gate p { font-size: 13.5px; color: hsl(var(--muted-foreground)); margin: 0 0 22px; }

.password-gate form { display: flex; flex-direction: column; gap: 11px; }

.password-gate input {
    width: 100%;
    padding: 11px 13px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--background));
    color: hsl(var(--foreground));
    font-size: 14px;
    transition: border-color .15s, box-shadow .15s;
}

.password-gate input::placeholder { color: hsl(var(--muted-foreground)); }
.password-gate input:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 3px hsl(var(--ring) / 0.18); }

.password-gate .gate-error { color: hsl(var(--destructive)); font-size: 12.5px; min-height: 16px; text-align: left; }

.password-gate .primary { width: 100%; padding: 11px; font-size: 14px; margin-top: 4px; }
.password-gate a { color: hsl(var(--primary)); text-decoration: none; font-size: 13px; }
.password-gate a:hover { text-decoration: underline; }

.password-gate .gate-help {
    margin: 18px 0 0;
    font-size: 12.5px;
    color: hsl(var(--muted-foreground));
}
.password-gate .gate-help a { font-size: inherit; font-weight: 500; }

/* ——— Поля/результат в модалках (создание/сброс аккаунта) ——— */
.modal-field-label {
    display: block;
    text-align: left;
    font-size: 12.5px;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    margin: 12px 0 5px;
}
.modal-input {
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--background));
    color: hsl(var(--foreground));
    font-size: 14px;
    transition: border-color .15s, box-shadow .15s;
}
.modal-input:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 3px hsl(var(--ring) / 0.18); }
.modal-input-row { display: flex; gap: 8px; align-items: stretch; }
.modal-input-row .modal-input { flex: 1; }
.modal-error { color: hsl(var(--destructive)); font-size: 12.5px; min-height: 16px; margin-top: 8px; text-align: left; }

.credentials-box {
    background: hsl(var(--muted));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-md);
    padding: 12px 14px;
    margin: 4px 0 8px;
    text-align: left;
    font-size: 13.5px;
}
.credentials-box .cred-row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.credentials-box .cred-label { color: hsl(var(--muted-foreground)); }
.credentials-box .cred-value { font-weight: 600; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ——— Чек-лист фильтров (Выгрузка отчёта) ——— */

.filter-block { margin-bottom: 18px; }
.filter-block h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: hsl(var(--foreground)); }

.checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 240px;
    overflow-y: auto;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-md);
    padding: 8px;
    background: hsl(var(--card));
}

.checkbox-list label {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 6px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    cursor: pointer;
    transition: background-color .15s;
}

.checkbox-list label:hover { background: hsl(var(--accent)); }
.checkbox-list input[type=checkbox] { accent-color: hsl(var(--primary)); width: 15px; height: 15px; }

.placeholder-card {
    padding: 48px 24px;
    text-align: center;
    color: hsl(var(--muted-foreground));
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
}

.placeholder-card .gate-icon { margin: 0 auto 16px; width: 48px; height: 48px; }
.placeholder-card h2 { font-size: 17px; font-weight: 600; color: hsl(var(--foreground)); margin: 0 0 6px; }
.placeholder-card p { font-size: 13.5px; margin: 0; }

.search-field { position: relative; max-width: 360px; margin-bottom: 16px; }

.search-field-icon {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    color: hsl(var(--muted-foreground));
    pointer-events: none;
}

.search-field input {
    width: 100%;
    padding: 9px 12px 9px 34px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    font-size: 14px;
    transition: border-color .15s, box-shadow .15s;
}

.search-field input:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 2px hsl(var(--ring) / 0.2); }
.search-field input::placeholder { color: hsl(var(--muted-foreground)); }

.employee-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }

.employee-list a {
    display: block;
    padding: 14px 16px;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    text-decoration: none;
    color: hsl(var(--card-foreground));
    font-size: 14px;
    font-weight: 500;
    box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
    transition: background-color .15s, border-color .15s;
}

.employee-list a:hover { background: hsl(var(--accent)); border-color: hsl(var(--ring) / 0.4); }

.top-bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; flex-wrap: wrap; gap: 12px; }

.week-switcher { display: flex; align-items: center; gap: 8px; }

.custom-select-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: background-color .15s, border-color .15s, box-shadow .15s;
}

.custom-select-trigger:hover { background: hsl(var(--accent)); }
.custom-select-trigger:focus-visible {
    outline: none;
    border-color: hsl(var(--ring));
    box-shadow: 0 0 0 2px hsl(var(--ring) / 0.25);
}

.custom-select-trigger--sm { padding: 5px 8px; font-size: 13px; gap: 6px; }

.readonly-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--status-open) / 0.35);
    background: hsl(var(--card));
    color: hsl(var(--status-open));
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color .15s;
}

.readonly-badge:hover { background: hsl(var(--status-open) / 0.1); }

table {
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
}

/* Реальные названия категорий бывают длинными предложениями — table-layout: fixed
   заставляет колонки уважать эти пропорции вместо того, чтобы растягиваться под
   самый длинный текст; сам текст обрезается многоточием (см. .category-value,
   .task-title ниже), полная версия — во всплывающей подсказке (title) и в
   открытом меню выбора, где ширина не ограничена. */
.task-col { width: 18%; }
.category-col { width: 14%; }

/* vertical-align: middle — иначе ячейки равняются по базовой линии текста, и бейджи
   (inline-flex) визуально съезжают относительно соседних ячеек строки. */
th, td {
    padding: 10px 14px;
    text-align: left;
    font-size: 13.5px;
    vertical-align: middle;
    border-bottom: 1px solid hsl(var(--border));
    /* вертикальный разделитель между колонками; у последней его нет, иначе
       получилась бы лишняя линия вплотную к рамке таблицы */
    border-right: 1px solid hsl(var(--border));
}

th:last-child, td:last-child { border-right: none; }

.task-title { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Название задачи правится так же, как ФИО в админке (.editable-name). Здесь только
   обрезка: задач в неделе бывает две сотни, и длинное имя не должно ломать колонку. */
.task-cell .editable-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

th { background: hsl(var(--secondary)); font-weight: 600; color: hsl(var(--muted-foreground)); font-size: 12.5px; }

tbody tr { transition: background-color .15s; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: hsl(var(--accent) / 0.6); }

/* ——— Ячейки категорий (дерево, кастомный picker) и часов — своя красная заливка
   строго по площади КОНКРЕТНОЙ ячейки, не всей строки. Красный только у "достижимых"
   (родитель уже выбран/это 1-й уровень) и пока пустых ячеек. ——— */

td.category-cell, td.hours-cell { padding: 0; }

.category-cell-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    height: 100%;
    padding: 10px 14px;
    border: none;
    background: transparent;
    color: hsl(var(--foreground));
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color .15s;
}

.category-cell.is-filled .category-cell-inner:hover { background: hsl(var(--accent)); }

.category-cell.is-empty {
    background: hsl(var(--destructive) / 0.18);
    box-shadow: inset 3px 0 0 hsl(var(--destructive));
}
.category-cell.is-empty .category-cell-inner { color: hsl(var(--destructive)); font-weight: 600; }
.category-cell.is-empty .category-cell-inner:hover { background: hsl(var(--destructive) / 0.28); }
.category-cell.is-empty .category-chevron { color: hsl(var(--destructive)); }

.category-cell.is-disabled .category-cell-inner { cursor: not-allowed; color: hsl(var(--muted-foreground) / 0.55); }

.category-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.category-chevron { flex-shrink: 0; display: flex; color: hsl(var(--muted-foreground)); }
.category-cell.is-disabled .category-chevron { visibility: hidden; }

td.hours-cell input[type=number] {
    width: 100%;
    height: 100%;
    padding: 10px 14px;
    border: none;
    background: transparent;
    color: hsl(var(--foreground));
    font-size: 13.5px;
    transition: background-color .15s, box-shadow .15s;
}

td.hours-cell input[type=number]:hover { background: hsl(var(--accent)); }
td.hours-cell.is-empty {
    background: hsl(var(--destructive) / 0.18);
    box-shadow: inset 3px 0 0 hsl(var(--destructive));
}
td.hours-cell.is-empty input[type=number] { color: hsl(var(--destructive)); font-weight: 600; }
td.hours-cell.is-empty input[type=number]:hover { background: hsl(var(--destructive) / 0.28); }

td.hours-cell input[type=number]:focus {
    outline: none;
    box-shadow: inset 0 0 0 2px hsl(var(--ring) / 0.35);
}

td.readonly-cell {
    color: hsl(var(--foreground));
    max-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hours-col { width: 130px; }
.actions-col { width: 76px; }   /* две иконки: копия и удаление */

td.delete-cell {
    padding: 0;
    text-align: center;
    white-space: nowrap;
}

.delete-row-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.delete-row-btn:hover { background: hsl(var(--destructive) / 0.14); color: hsl(var(--destructive)); }
.delete-row-btn:disabled { opacity: 0.5; cursor: not-allowed; }

td.model-cell { padding: 0; }

td.model-cell input[type=text] {
    width: 100%;
    height: 100%;
    padding: 10px 14px;
    border: none;
    background: transparent;
    color: hsl(var(--foreground));
    font-size: 13.5px;
    transition: background-color .15s, box-shadow .15s;
}

td.model-cell input[type=text]:hover { background: hsl(var(--accent)); }
td.model-cell input[type=text]:focus {
    outline: none;
    box-shadow: inset 0 0 0 2px hsl(var(--ring) / 0.35);
}

td.model-cell.is-empty {
    background: hsl(var(--destructive) / 0.18);
    box-shadow: inset 3px 0 0 hsl(var(--destructive));
}
td.model-cell.is-empty input[type=text] { color: hsl(var(--destructive)); font-weight: 600; }
td.model-cell.is-empty input[type=text]:hover { background: hsl(var(--destructive) / 0.28); }

td.model-cell.is-disabled {
    display: flex;
    align-items: center;
    height: 100%;
    padding: 10px 14px;
    color: hsl(var(--muted-foreground) / 0.55);
}

.hours-summary {
    margin-top: 16px;
    padding: 10px 14px;
    border-radius: var(--radius-md);
    background: hsl(var(--accent));
    color: hsl(var(--foreground));
    font-size: 13.5px;
    font-weight: 500;
}

.hours-summary.is-short {
    background: hsl(var(--destructive) / 0.14);
    color: hsl(var(--destructive));
}

.add-task-form { margin-top: 12px; }

/* ——— Портальная панель выбора категории (по образцу SelectField track-share) ——— */

.category-menu {
    position: fixed;
    /* Выше .modal-backdrop (300). Меню кладётся в document.body, то есть оно СОСЕД
       затемнения, а не его потомок: при 200 оно открывалось под модалкой, клик по
       варианту перехватывало окно, и выпадашка недели в «Скопировать с другой недели»
       выглядела намертво заклинившей. */
    z-index: 400;
    width: 220px;
    max-height: 280px;
    overflow-y: auto;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 32px hsl(0 0% 0% / 0.16);
    padding: 4px;
}

.category-menu-option {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 8px;
    border: none;
    background: transparent;
    border-radius: var(--radius-md);
    font-size: 13.5px;
    text-align: left;
    color: hsl(var(--foreground));
    cursor: pointer;
    transition: background-color .15s;
}

.category-menu-option:hover,
.category-menu-option:focus-visible,
.category-menu-option:focus { background: hsl(var(--accent)); outline: none; }

.category-menu-check { display: flex; align-items: center; justify-content: center; width: 14px; flex-shrink: 0; color: hsl(var(--primary)); }

.category-menu-option-label { flex: 1; min-width: 0; white-space: normal; word-break: break-word; line-height: 1.35; }

.category-menu-clear {
    color: hsl(var(--muted-foreground));
    border-top: 1px solid hsl(var(--border));
    border-radius: 0;
    margin-top: 4px;
    padding-top: 9px;
}

.category-menu-empty { margin: 0; padding: 10px 8px; font-size: 13px; color: hsl(var(--muted-foreground)); }

.actions { margin-top: 18px; display: flex; align-items: center; gap: 12px; }

.primary {
    align-self: flex-start;
    padding: 9px 20px;
    border: none;
    border-radius: var(--radius-md);
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color .15s, opacity .15s;
}

.primary:hover { background: hsl(220 84% 50%); }
button.primary:disabled { background: hsl(var(--primary) / 0.45); cursor: default; }

button.danger {
    padding: 9px 20px;
    border: none;
    border-radius: var(--radius-md);
    background: hsl(var(--destructive));
    color: white;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: opacity .15s;
}
button.danger:hover { opacity: 0.88; }
button.danger:disabled { opacity: 0.5; cursor: default; }

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: hsl(0 0% 0% / 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 300;
}

.modal-card {
    width: min(380px, 90vw);
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    box-shadow: 0 20px 48px hsl(0 0% 0% / 0.28);
    padding: 22px 24px;
}

.modal-title {
    margin: 0 0 8px;
    font-size: 16px;
    font-weight: 600;
    color: hsl(var(--foreground));
}

.modal-message {
    margin: 0 0 18px;
    font-size: 13.5px;
    line-height: 1.4;
    color: hsl(var(--muted-foreground));
    /* переносы строк в тексте сообщения должны сохраняться (см. showMessage в ui.js) */
    white-space: pre-line;
}

.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* Окно-сообщение (одна кнопка): по центру и покомпактнее — правое выравнивание
   рассчитано на пару «Отменить / Удалить», а с одной кнопкой смотрится пусто.
   Текст здесь — основной контент, поэтому обычным цветом, а не приглушённым. */
.modal-card.message-card {
    width: min(340px, 90vw);
    padding: 26px 24px 20px;
    text-align: center;
}

.message-card .modal-title { margin-bottom: 6px; }

.message-card .modal-message {
    margin: 0 0 20px;
    font-size: 14px;
    color: hsl(var(--foreground));
}

.message-card .modal-actions { justify-content: center; }
.message-card .modal-actions .primary { min-width: 128px; }

/* ——— Модалка «Скопировать с прошлой недели» ——— */

.copy-tasks-card { width: min(480px, 92vw); }

.copy-tasks-week-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}
.copy-tasks-week-row label { font-size: 13.5px; color: hsl(var(--muted-foreground)); flex-shrink: 0; }
.copy-tasks-week-row .custom-select-trigger { flex: 1; }

.copy-task-select-all {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 2px 10px;
    font-size: 13px;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
}
.copy-task-select-all input[type=checkbox] { accent-color: hsl(var(--primary)); width: 15px; height: 15px; }

.copy-tasks-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 320px;
    overflow-y: auto;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-md);
    padding: 6px;
    margin-bottom: 18px;
}

.copy-task-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color .15s;
}
.copy-task-row:hover { background: hsl(var(--accent)); }
.copy-task-row input[type=checkbox] { accent-color: hsl(var(--primary)); width: 15px; height: 15px; margin-top: 2px; flex-shrink: 0; }

.copy-task-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.copy-task-title { font-size: 13.5px; font-weight: 500; color: hsl(var(--foreground)); }
.copy-task-path { font-size: 12px; color: hsl(var(--muted-foreground)); line-height: 1.4; }

.copy-tasks-empty {
    margin: 0;
    padding: 24px 10px;
    text-align: center;
    font-size: 13px;
    color: hsl(var(--muted-foreground));
}

.btn-icon-inline { display: inline-flex; vertical-align: middle; margin-right: 4px; }

/* Крутилка на кнопке, пока идёт запрос (кнопка при этом заблокирована) */
.btn-spinner {
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-right: 7px;
    vertical-align: -2px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: btn-spin 0.6s linear infinite;
}

@keyframes btn-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .btn-spinner { animation-duration: 1.6s; }
}

/* Роль и действия в колонке «Аккаунт» (вкладка «Сотрудники») */
.role-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: hsl(var(--primary) / 0.15);
    color: hsl(var(--primary));
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}

/* Таблица сотрудников: у table-layout:fixed без явных ширин три колонки делились
   поровну, и под маленький бейдж «Бот» уходила треть ширины. */
#tab-employees th:nth-child(1), #tab-employees td:nth-child(1) { width: 52%; }
#tab-employees th:nth-child(2), #tab-employees td:nth-child(2) { width: 34%; }
#tab-employees th:nth-child(3), #tab-employees td:nth-child(3) { width: 14%; text-align: center; }

/* плашка «Да/Нет» — по центру своей ячейки */
.bot-cell { white-space: nowrap; }

.role-badge.is-muted {
    background: hsl(var(--muted));
    color: hsl(var(--muted-foreground));
    font-weight: 500;
}

/* Логин + метки + меню действий — одной строкой, чтобы строки таблицы
   оставались низкими (сотрудников полторы сотни). */
.account-cell {
    display: flex;
    align-items: center;
    gap: 6px;
    /* без переноса: иначе длинная метка роняла кнопку «⋯» на вторую строку
       и строки таблицы прыгали по высоте */
    flex-wrap: nowrap;
    min-width: 0;
}

/* логин при нехватке места ужимается многоточием, метки и меню остаются на месте */
.account-login {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.account-menu-btn {
    margin-left: auto;
    padding: 2px 9px;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    background: transparent;
    color: hsl(var(--muted-foreground));
    font-size: 16px;
    line-height: 1.2;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}

.account-menu-btn:hover {
    background: hsl(var(--accent));
    border-color: hsl(var(--border));
    color: hsl(var(--foreground));
}

/* Счётчик доступных задач на кнопке «Добавить из Yonote» */
.btn-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    margin-left: 6px;
    border-radius: 999px;
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
}

.save-status {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 13px;
    color: hsl(var(--muted-foreground));
}
/* «Сохранено» — зелёным с галочкой. Прежде оно было того же серого цвета, что и
   «Сохранение…», и отличить состояния можно было только вчитавшись. */
.save-status.is-saved { color: hsl(142 55% 40%); }
.save-status.is-failed { color: hsl(var(--destructive)); }
.save-status-icon { display: inline-flex; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .save-status.is-saved { color: hsl(142 50% 55%); }
}
:root[data-theme="dark"] .save-status.is-saved { color: hsl(142 50% 55%); }

.empty-state {
    padding: 28px;
    text-align: center;
    color: hsl(var(--muted-foreground));
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    font-size: 14px;
}

a.back-link { color: hsl(var(--primary)); text-decoration: none; font-size: 13.5px; font-weight: 500; }
a.back-link:hover { text-decoration: underline; }

.tabs { display: flex; gap: 4px; margin-bottom: 22px; border-bottom: 1px solid hsl(var(--border)); flex-wrap: wrap; }

.tab-btn {
    padding: 10px 16px;
    border: none;
    background: transparent;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
    color: hsl(var(--muted-foreground));
    border-bottom: 2px solid transparent;
    transition: color .15s, border-color .15s;
}

.tab-btn:hover { color: hsl(var(--foreground)); }
.tab-btn.active { color: hsl(var(--primary)); border-bottom-color: hsl(var(--primary)); font-weight: 600; }

.tab-panel { display: flex; flex-direction: column; gap: 16px; }
.tab-panel[hidden] { display: none; }

.tab-panel > p { color: hsl(var(--muted-foreground)); font-size: 13.5px; line-height: 1.55; margin: 0; max-width: 720px; }
.tab-panel code {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.inline-form { display: flex; gap: 8px; align-items: center; }

.inline-form input[type=text] {
    padding: 8px 12px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    font-size: 13.5px;
    flex: 1;
    max-width: 320px;
    transition: border-color .15s, box-shadow .15s;
}

.inline-form input[type=text]:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 2px hsl(var(--ring) / 0.2); }

.editable-name {
    display: inline-block;
    padding: 3px 7px;
    margin: -3px -7px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color .15s;
}

.editable-name:hover { background: hsl(var(--accent)); }
/* Кнопка во всю ячейку: клик и фокус работают по всей области, как в остальных
   таблицах проекта (.category-cell-inner, td.task-cell input). */
.editable-name { width: 100%; text-align: left; border: none; background: none;
                 font: inherit; color: inherit; }

.editable-name-input {
    width: 100%;
    padding: 5px 7px;
    border-radius: var(--radius-sm);
    border: 1px solid hsl(var(--ring));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    font-size: 13.5px;
    font-family: inherit;
}

.editable-name-input:focus { outline: none; box-shadow: 0 0 0 2px hsl(var(--ring) / 0.2); }

button.secondary {
    padding: 6px 14px;
    border: 1px solid hsl(var(--primary) / 0.4);
    border-radius: var(--radius-md);
    background: hsl(var(--card));
    color: hsl(var(--primary));
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color .15s, border-color .15s;
}

button.secondary:hover { background: hsl(var(--accent)); border-color: hsl(var(--primary) / 0.6); }

.badge-yes, .badge-no {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: var(--radius-md);
    border: 1px solid;
    background: hsl(var(--card));
    font-size: 12.5px;
    font-weight: 500;
}

.badge-yes::before, .badge-no::before { content: ""; width: 6px; height: 6px; border-radius: 999px; flex-shrink: 0; }

.badge-yes { color: hsl(var(--status-done)); border-color: hsl(var(--status-done) / 0.35); }
.badge-yes::before { background: hsl(var(--status-done)); }

/* «Бот не подключён» — обычное состояние для большинства сотрудников, а не ошибка:
   красный на полутора сотнях строк создавал ощущение, что всё сломано. */
.badge-no { color: hsl(var(--muted-foreground)); border-color: hsl(var(--border)); }
.badge-no::before { background: hsl(var(--muted-foreground) / 0.6); }

pre.report-box {
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    padding: 14px;
    font-size: 12.5px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    white-space: pre-wrap;
    max-height: 400px;
    overflow-y: auto;
    color: hsl(var(--foreground));
}

.red-rows-employee {
    background: hsl(var(--card));
    border-radius: var(--radius-lg);
    padding: 14px 18px;
    margin-bottom: 10px;
    border: 1px solid hsl(var(--border));
    box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
}

.red-rows-employee h3 { margin: 0 0 8px; font-size: 14.5px; font-weight: 600; }
.red-rows-employee ul { margin: 0; padding-left: 18px; color: hsl(var(--foreground)); font-size: 13.5px; line-height: 1.6; }

.no-bot-warning {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: hsl(var(--status-cancelled));
    font-size: 12.5px;
    margin-bottom: 8px;
}

.no-bot-warning::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: hsl(var(--status-cancelled)); flex-shrink: 0; }

/* ——— Адаптивная вёрстка под телефоны ———
   Брейкпоинт 640px: рейл-сайдбар переезжает вниз (фикс. панель), паддинги сужаются.
   Брейкпоинт 720px: главная таблица недели (#week-table) превращается из строк в
   карточки — каждая ячейка получает подпись через data-label + ::before, т.к. на
   узком экране 8 колонок физически не помещаются рядом. Прочие (админские) таблицы
   просто скроллятся по горизонтали — им отдельная карточная вёрстка не нужна. */

@media (max-width: 640px) {
    .app-shell { flex-direction: column; height: auto; min-height: 100vh; }
    #sidebar-root { width: 0; }

    .rail {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        width: 100%;
        height: 56px;
        flex-direction: row;
        justify-content: space-evenly;
        padding: 0 8px;
        border-right: none;
        border-top: 1px solid hsl(var(--border));
    }
    .rail-logo, .rail-spacer, .rail-tooltip { display: none; }
    .rail-nav { flex-direction: row; gap: 4px; }

    .app-main { padding: 16px 14px 76px; }

    .top-bar { flex-direction: column; align-items: flex-start; }
    .week-switcher { width: 100%; flex-wrap: wrap; }
    .actions { flex-wrap: wrap; }
}

@media (max-width: 720px) {
    #week-table thead { display: none; }
    #week-table, #week-table tbody, #week-table tr, #week-table td {
        display: block;
        width: 100%;
    }

    #week-table tr {
        margin-bottom: 12px;
        border: 1px solid hsl(var(--border));
        border-radius: var(--radius-lg);
        overflow: hidden;
        box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
    }
    #week-table tr:last-child { margin-bottom: 0; }

    #week-table td { border-bottom: 1px solid hsl(var(--border)); }
    #week-table tr td:last-child { border-bottom: none; }
    #week-table td:empty { display: none; }

    #week-table td.task-cell {
        background: hsl(var(--secondary));
        padding: 12px 14px;
    }
    #week-table td.task-cell .task-title {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-weight: 600;
        font-size: 14px;
    }

    #week-table td[data-label] {
        position: relative;
        padding: 22px 14px 10px !important;
    }
    #week-table td[data-label]::before {
        content: attr(data-label);
        position: absolute;
        top: 5px;
        left: 14px;
        font-size: 10.5px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .02em;
        color: hsl(var(--muted-foreground));
    }

    #week-table td.readonly-cell {
        white-space: normal;
        max-width: none;
        overflow: visible;
        text-overflow: clip;
    }

    #week-table td.actions-col, #week-table td.delete-cell {
        text-align: right;
        padding: 6px 10px !important;
    }

    table:not(#week-table) {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        table-layout: auto;
    }
    table:not(#week-table) tr { white-space: nowrap; }
}

/* ——— Страница «Настройки»: секции, подключение бота, календарь отпуска ——— */

.settings-section { margin-bottom: 36px; }
.settings-section:last-child { margin-bottom: 0; }

.settings-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.section-title { font-size: 16px; font-weight: 600; margin: 0 0 6px; letter-spacing: -0.01em; }

.section-hint {
    margin: 0 0 14px;
    max-width: 720px;
    color: hsl(var(--muted-foreground));
    font-size: 13px;
    line-height: 1.55;
}

/* Название правится прямо в ячейке — как часы и категории рядом. Отступы обнуляем
   ТОЛЬКО у ячейки с полем ввода: своё поле рисует их само, на всю площадь ячейки.
   Класс .task-cell используется и в недельной таблице, где внутри обычный <span>, —
   там обнуление оставляло текст вплотную к рамке. Привязка по id таблиц, а не
   :has(): работает во всех браузерах и явно говорит, о каких таблицах речь.

   Обе таблицы настроек перечислены поимённо. Пока правило знало только про
   #templates-table, поле в «Шаблонах задач» оставалось с браузерной рамкой и
   выглядело чужеродно рядом с точно такой же строкой выше. */
#templates-table td.task-cell,
#task-templates-table td.task-cell { padding: 0; }

#templates-table td.task-cell input[type=text],
#task-templates-table td.task-cell input[type=text] {
    width: 100%;
    height: 100%;
    padding: 10px 14px;
    border: none;
    background: transparent;
    color: hsl(var(--foreground));
    font-size: 13.5px;
    transition: background-color .15s, box-shadow .15s;
}

#templates-table td.task-cell input[type=text]:hover,
#task-templates-table td.task-cell input[type=text]:hover { background: hsl(var(--accent)); }
#templates-table td.task-cell input[type=text]:focus,
#task-templates-table td.task-cell input[type=text]:focus { outline: none; box-shadow: inset 0 0 0 2px hsl(var(--ring) / 0.35); }

.settings-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }

.settings-row input[type=text] {
    padding: 8px 12px;
    border-radius: var(--radius-md);
    border: 1px solid hsl(var(--input));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    font-size: 13.5px;
    width: 260px;
    transition: border-color .15s, box-shadow .15s;
}

.settings-row input[type=text]:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 2px hsl(var(--ring) / 0.2); }

.bot-status { margin: 0; font-size: 13px; }
.bot-status.is-on { color: hsl(var(--status-done)); }
.bot-status.is-off { color: hsl(var(--muted-foreground)); }

.calendar {
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    padding: 14px;
    max-width: 340px;
    box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
}

.calendar-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.calendar-title { font-size: 14px; font-weight: 600; }

.cal-nav {
    width: 28px;
    height: 28px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: hsl(var(--muted-foreground));
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.cal-nav:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }

.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }

.cal-weekday {
    text-align: center;
    font-size: 11px;
    font-weight: 600;
    color: hsl(var(--muted-foreground));
    padding-bottom: 4px;
}

.cal-day {
    aspect-ratio: 1;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: hsl(var(--foreground));
    font-size: 13px;
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.cal-day:hover { background: hsl(var(--accent)); }
/* Пока сохраняется период отпуска, дни не кликаются: rangeStart уже сброшен, и
   следующий клик начинал бы НОВЫЙ период вторым запросом. */
.cal-grid.is-busy { opacity: 0.55; pointer-events: none; }
/* выходные и праздники: кликать можно (период их просто перешагнёт), но видно, что не в счёт */
.cal-day.is-off { color: hsl(var(--muted-foreground) / 0.65); }
.cal-day.in-vacation { background: hsl(var(--primary) / 0.16); color: hsl(var(--primary)); font-weight: 600; }
.cal-day.in-vacation:hover { background: hsl(var(--primary) / 0.26); }
.cal-day.is-start { box-shadow: inset 0 0 0 2px hsl(var(--ring)); }

.calendar-hint { margin: 10px 0 0; font-size: 12px; color: hsl(var(--muted-foreground)); }

.vacation-list { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; max-width: 480px; }

.vacation-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-md);
    font-size: 13.5px;
}

.vacation-dates { flex: 1; }
.vacation-hours { color: hsl(var(--muted-foreground)); font-size: 12.5px; }

/* ——— Подсказка с полным текстом обрезанной ячейки (см. static/js/tooltip.js) ———
   Названия категорий — длинные предложения, в ячейку не помещаются никогда.
   Нативный title показывал их серым системным окном через секунду-две; это —
   своя подсказка, в оформлении приложения и без задержки. */

.app-tooltip {
    position: fixed;
    z-index: 100;
    max-width: min(520px, 90vw);
    padding: 7px 11px;
    border-radius: var(--radius-md);
    background: hsl(230 15% 22% / 0.97);
    color: #fff;
    font-size: 12.5px;
    line-height: 1.45;
    /* длинные названия переносим, а не растягиваем подсказку на весь экран */
    white-space: normal;
    overflow-wrap: anywhere;
    box-shadow: 0 8px 22px hsl(0 0% 0% / 0.22);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;   /* подсказка не должна перехватывать наведение
                               и мигать, когда курсор доходит до неё */
    transition: opacity .12s;
}

.app-tooltip.is-visible { opacity: 1; visibility: visible; }

/* ——— Центр сотрудника (вкладка «Сотрудники») ———
   Плашка — контейнер с двумя кнопками внутри: название (сменить) и крестик
   (снять). Крестик раньше стоял рядом с плашкой и наследовал приглушённый цвет
   ячейки — его почти не было видно и в него было трудно попасть. */

.center-cell { white-space: nowrap; }

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 0 4px 0 0;
    border-radius: 999px;
    background: hsl(var(--primary) / 0.14);
    color: hsl(var(--primary));
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    transition: background-color .15s;
}

.tag-chip:hover { background: hsl(var(--primary) / 0.22); }

.tag-chip-label {
    padding: 4px 4px 4px 10px;
    border: none;
    border-radius: 999px 0 0 999px;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.tag-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: hsl(var(--primary));   /* именно цвет плашки, а не приглушённый цвет ячейки */
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.tag-chip-remove:hover {
    background: hsl(var(--destructive) / 0.18);
    color: hsl(var(--destructive));
}

.tag-chip-remove:disabled { opacity: 0.4; cursor: default; }

.tag-add-btn {
    padding: 3px 10px;
    border: 1px dashed hsl(var(--input));
    border-radius: 999px;
    background: transparent;
    color: hsl(var(--muted-foreground));
    font-size: 12px;
    cursor: pointer;
    transition: border-color .15s, color .15s;
}

.tag-add-btn:hover { border-color: hsl(var(--ring)); color: hsl(var(--foreground)); }

/* ——— Таблица сотрудников: своя раскладка колонок ———
   Колонок восемь (ФИО, логин, аккаунт, центр, команда, теги, бот, действия), и при
   table-layout: fixed они делили бы ширину поровну — «Бот» уезжал за край. Раздаём
   явно: ФИО и аккаунт длинные, логин/центр и команда — короткие, тегам нужен запас
   под несколько плашек. */

.employees-table .col-name    { width: 20%; }
.employees-table .col-login   { width: 120px; }
.employees-table .col-account { width: 20%; }
.employees-table .col-center  { width: 140px; }
.employees-table .col-tags    { width: 200px; }

/* Теги идут в несколько плашек, поэтому ячейке нужен перенос — в отличие от центра
   и команды, где значение ровно одно и всегда помещается в строку. */
.tags-cell { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.employees-table .col-bot     { width: 88px; }

.employees-table td.single-value-cell,
.employees-table td.bot-cell { text-align: center; }

/* Длинное значение не должно вылезать в соседнюю колонку. Команда «Модельные риски
   ДБ и ДЮЛ» наезжала на теги и читалась поверх них — две строки в одном месте.
   Обрезает ЯЧЕЙКА, плашка не выходит за её край; полное значение — в подсказке.

   Многоточия нет намеренно. Подпись плашки — это <button>, и overflow: hidden на нём
   ломает его собственный расчёт ширины: кнопка перестаёт растягиваться под текст, и
   даже короткое «ЦМРСБиЭ» обрезалось до «ЦМР…» при свободном месте вокруг. Проверены
   семь вариантов (min-width, flex, width: max-content на подписи и на плашке) —
   ни один этого не снимает. */
.employees-table td { overflow: hidden; }
.employees-table .tag-chip { max-width: 100%; }

/* Админская страница шире остальных: здесь широкие таблицы (сотрудники,
   несопоставленные), а 960px под них уже мало. */
body[data-page="upload"] .container { max-width: 1280px; }

/* Недельная таблица тоже широкая: восемь колонок (задача, четыре категории, id
   модели, часы, действия), а названия задач и категорий — длинные предложения.
   В 960px они сжимались до многоточий почти целиком. */
body[data-page="employees"] .container { max-width: 1440px; }

/* ——— Ручка изменения ширины колонки ———
   Полоса на всю высоту заголовка у правой границы. Узкая визуально (1px линия), но
   с запасом по области захвата: попасть мышью в один пиксель невозможно. */
th { position: relative; }

.col-resize-handle {
    position: absolute;
    top: 0;
    right: -4px;
    width: 9px;
    height: 100%;
    cursor: col-resize;
    z-index: 2;
    user-select: none;
}

.col-resize-handle::after {
    content: "";
    position: absolute;
    top: 20%;
    left: 4px;
    width: 1px;
    height: 60%;
    background: hsl(var(--border));
    transition: background-color .15s;
}

.col-resize-handle:hover::after,
body.is-resizing-column .col-resize-handle::after { background: hsl(var(--ring)); }

/* Во время перетаскивания курсор не должен «прыгать» над другими элементами, а
   выделение текста — мешать. */
body.is-resizing-column { cursor: col-resize; user-select: none; }

/* ——— Панель фильтра (static/js/filter-bar.js) ———
   Общая для всех экранов: сейчас фильтруют по центру, дальше тем же способом
   добавятся другие признаки. */

.search-row {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.search-row .search-field { flex: 1; min-width: 220px; max-width: 420px; margin-bottom: 0; }
.search-row .inline-form { margin-bottom: 0; }

.filter-bar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.filter-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid hsl(var(--border));
    border-radius: 999px;
    background: hsl(var(--card));
    color: hsl(var(--muted-foreground));
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color .15s, color .15s, background-color .15s;
}

.filter-btn:hover { border-color: hsl(var(--ring)); color: hsl(var(--foreground)); }

.filter-btn.is-active {
    border-color: transparent;
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
}

.filter-btn-count {
    padding: 1px 6px;
    border-radius: 999px;
    background: hsl(var(--muted-foreground) / 0.18);
    font-size: 11px;
    font-weight: 600;
}

.filter-btn.is-active .filter-btn-count { background: hsl(0 0% 100% / 0.25); }

/* На вкладке «Красные строки» панель стоит отдельной строкой над списком */
#red-rows-center-filter { margin: 0 0 16px; }

/* ——— Аналитика: горизонтальные полосы-доли ———
   Свои, без библиотек: страницы отдаются с жёстким CSP, внешний скрипт браузер
   всё равно не загрузил бы. */

.analytics-section { margin-bottom: 36px; }
#employee-filter { margin-bottom: 20px; }

.chart {
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg);
    padding: 6px 16px;
    box-shadow: 0 1px 2px hsl(0 0% 0% / 0.04);
}

.chart-row {
    display: grid;
    grid-template-columns: minmax(140px, 2fr) 3fr 110px;
    align-items: center;
    gap: 14px;
    padding: 9px 0;
    border-bottom: 1px solid hsl(var(--border));
}

.chart-row:last-child { border-bottom: none; }

.chart-label {
    font-size: 13.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chart-track {
    height: 10px;
    border-radius: 999px;
    background: hsl(var(--muted-foreground) / 0.14);
    overflow: hidden;
}

.chart-fill {
    height: 100%;
    border-radius: 999px;
    background: hsl(var(--primary));
    transition: width .25s;
}

.chart-value {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 8px;
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
}

.chart-share { color: hsl(var(--muted-foreground)); font-weight: 500; font-size: 12px; }


/* Шапка таблицы аналитики с переключателем разреза — внутри самой таблицы,
   потому что переключает именно её содержимое. */
.chart-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 0;
    border-bottom: 1px solid hsl(var(--border));
}

.chart-head-label { font-size: 12.5px; color: hsl(var(--muted-foreground)); }
.chart-head .filter-btn { padding: 5px 11px; font-size: 12.5px; }

/* Перевыполнение нормы и недобор в разрезе «кто сколько записывает» */
.chart-fill.is-over { background: hsl(var(--status-done)); }
.chart-share.is-under { color: hsl(var(--destructive)); font-weight: 600; }

/* Своя строка в списке сотрудников — админ заходит сюда чаще всего к себе */
.employee-list a.is-me {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-color: hsl(var(--primary) / 0.45);
    background: hsl(var(--primary) / 0.07);
}

.employee-list a.is-me:hover { background: hsl(var(--primary) / 0.12); }

.me-badge {
    padding: 2px 8px;
    border-radius: 999px;
    background: hsl(var(--primary) / 0.16);
    color: hsl(var(--primary));
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}

/* Копия строки недели — рядом с крестиком удаления */
.row-copy-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.row-copy-btn:hover { background: hsl(var(--primary) / 0.14); color: hsl(var(--primary)); }
.row-copy-btn:disabled { opacity: 0.5; cursor: not-allowed; }


/* ——— Панель отбора сотрудников (центр / команда / теги / сохранённые) ——— */
.employee-filter-panel { display: flex; flex-direction: column; gap: 6px; width: 100%; }

.employee-filter-panel .filter-row { display: flex; align-items: flex-start; gap: 10px; }

/* Подписи признаков одной ширины, чтобы ряды кнопок начинались по одной линии —
   иначе «Центр», «Команда» и «Теги» смещают друг друга и панель выглядит рваной. */
.employee-filter-panel .filter-row-label {
    flex: 0 0 72px;
    padding-top: 6px;
    font-size: 12px;
    color: hsl(var(--muted-foreground));
}

.employee-filter-panel .filter-bar { margin: 0; }

/* Сохранённые фильтры отделены линией: это не ещё один признак, а готовые наборы. */
.employee-filter-panel .saved-filters-row {
    border-top: 1px solid hsl(var(--border));
    padding-top: 8px;
    margin-top: 2px;
}

.saved-filter-chip .tag-chip-label { font-weight: 500; }


/* ——— Раскрытие задач сотрудника из аналитики ——— */
/* Полоска кликабельна — это должно быть видно до наведения, иначе функцию не найдут. */
.chart-row.is-clickable { cursor: pointer; border-radius: var(--radius-sm); }
.chart-row.is-clickable:hover { background: hsl(var(--accent)); }
.chart-row.is-clickable:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px hsl(var(--ring) / 0.35);
}

/* Окно шире обычного: внутри таблица с путём категорий, а он длинный.
   Именно width, а не max-width: у .modal-card ширина задана свойством width
   (min(380px, 90vw)), и max-width её не перебивает — окно оставалось узким,
   а названия задач обрезались до «Вал…». */
.employee-tasks-card { width: min(880px, 94vw); }

.employee-tasks-table { width: 100%; table-layout: fixed; margin-top: 12px; font-size: 13px; }
.employee-tasks-table th {
    text-align: left;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    padding: 7px 10px;                    /* заголовки без padding стояли вплотную к рамке */
}
.employee-tasks-table th:nth-child(1) { width: 38%; }
.employee-tasks-table th:nth-child(2) { width: 36%; }
.employee-tasks-table th:nth-child(3) { width: 120px; }
.employee-tasks-table th:nth-child(4) { width: 84px; text-align: right; }
.employee-tasks-table td { padding: 7px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.employee-tasks-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Список задач может быть длинным — прокручиваем ОБЁРТКУ, а не саму таблицу: шапка с
   итогом и кнопки остаются на виду, а table-layout:fixed продолжает работать. */
.employee-tasks-scroll { max-height: 52vh; overflow-y: auto; margin-top: 12px; }
.employee-tasks-scroll .employee-tasks-table { margin-top: 0; }

/* Кнопки не должны липнуть к таблице — иначе непонятно, относятся они к последней
   строке или ко всему окну. */
.employee-tasks-card .modal-actions { margin-top: 18px; }

/* Шапка таблицы липнет к верху при прокрутке — иначе, уехав вниз, не понять,
   в какой колонке что. */
.employee-tasks-table thead th {
    position: sticky;
    top: 0;
    background: hsl(var(--card));
    z-index: 1;
}

/* --- вкладка «Команды и фильтры» ------------------------------------------- */
.org-section { margin-bottom: 28px; }
.org-section .section-title { margin-bottom: 4px; }
.org-section .section-hint { margin: 0 0 14px; }

.org-center {
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-md);
    padding: 12px 14px;
    margin-bottom: 10px;
    background: hsl(var(--card));
}

.org-center-head { display: flex; align-items: center; gap: 10px; }
.org-center-name { font-weight: 600; font-size: 14.5px; }
.org-count { font-size: 12.5px; color: hsl(var(--muted-foreground)); }

/* Кнопки центра прижимаются вправо и проявляются на наведении: в спокойном
   состоянии карточка читается как список, а не как панель управления. */
.org-actions { margin-left: auto; display: flex; gap: 4px; opacity: 0; transition: opacity .12s; }
.org-center:hover .org-actions,
.org-center:focus-within .org-actions { opacity: 1; }

.org-teams { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

/* Кнопки ВНУТРИ плашки — часть плашки, а не отдельные кнопки: своя рамка и фон
   превращали команду в россыпь коробочек. Оформляем как крестик удаления рядом. */
.org-team-chip .icon-btn {
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    opacity: 0.55;
}
.org-team-chip .icon-btn:hover { opacity: 1; background: none; }

/* Пустой раздел не должен занимать полкарточки. */
.org-section .empty-state { padding: 14px 0; border: none; background: none; }

.org-builder-label {
    display: block;
    margin: 4px 0 10px;
    font-size: 12.5px;
    color: hsl(var(--muted-foreground));
}

/* Кнопка сохранения — отдельный блок с воздухом сверху. Без этого она вставала
   вплотную к последнему ряду условий и налезала на кнопку «Все». */
.org-save-btn { display: block; margin-top: 18px; }

/* «Фильтров пока нет» — по левому краю, как и всё остальное в разделе: .empty-state
   центрирует текст, и посреди левых подписей он выглядел случайно поставленным. */
.org-section .empty-state { text-align: left; }

/* Пояснение вместо пустого ряда фильтров — иначе строка выглядит поломкой. */
.filter-empty-note { font-size: 12.5px; color: hsl(var(--muted-foreground)); align-self: center; }

/* Выбранный набор видно: иначе не понять, действует ли он ещё — особенно когда его
   условия (например теги) на этой странице не показываются. */
.saved-filter-chip.is-active {
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
}
.saved-filter-chip.is-active:hover { background: hsl(var(--primary) / 0.9); }

/* Неделя начальника центра: задачи чужие, поэтому под названием — чей это. */
.task-performer { display: block; font-size: 12px; color: hsl(var(--muted-foreground)); }

.head-note {
    margin: 0 0 14px;
    padding: 10px 14px;
    border-radius: var(--radius-md);
    background: hsl(var(--primary) / 0.08);
    border-left: 3px solid hsl(var(--primary));
    font-size: 13px;
    color: hsl(var(--muted-foreground));
}

/* Начальник центра — рядом со счётчиком людей, а не в общем ряду команд:
   это свойство центра, а не одна из его команд. */
.org-head {
    margin-left: 10px;
    padding: 2px 9px;
    border: 1px solid hsl(var(--border));
    border-radius: 999px;
    background: hsl(var(--primary) / 0.12);
    color: hsl(var(--primary));
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}
.org-head:hover { background: hsl(var(--primary) / 0.2); }
.org-head.is-empty {
    background: none;
    color: hsl(var(--muted-foreground));
    border-style: dashed;
}

/* --- дерево категорий в аналитике ------------------------------------------ */
/* Отступ по уровню — на подписи, а не на всей строке: полоски долей остаются на
   одной вертикали, иначе сравнивать их глазами было бы невозможно.
   Сама строка не трогается: .chart-row — сетка из трёх колонок, и любой лишний
   элемент в ней сдвигает часы на следующую строку. */
.tree-row .chart-label { padding-left: calc(var(--depth, 0) * 18px); }

/* Треугольник — внутри подписи, строчным элементом: так он течёт вместе с текстом
   и не занимает колонку сетки. */
.tree-caret {
    display: inline-block;
    width: 13px;
    margin-right: 4px;
    vertical-align: -2px;
    color: hsl(var(--muted-foreground));
    transition: transform .15s;
}
.tree-caret.is-leaf { visibility: hidden; }
.tree-caret.is-open { transform: rotate(180deg); }
.tree-row.is-clickable:hover .tree-caret { color: hsl(var(--foreground)); }

/* Раскрытая ветка приглушается: её состав показан ниже, и читают именно его.
   Приглушение снимается при наведении — иначе по родителю невозможно попасть
   взглядом, когда надо его свернуть. */
.tree-row.is-context { opacity: 0.55; }
/* Всё, что не относится к выбранной ветке. Гаснет сильнее цепочки: цепочка нужна,
   чтобы понимать, где ты, а посторонние направления — только фон. */
.tree-row.is-dimmed { opacity: 0.28; }
.tree-row.is-context:hover,
.tree-row.is-dimmed:hover { opacity: 1; }

/* ── Скелетоны загрузки ───────────────────────────────────────────────────────
   Перенесено из track-share: там этот приём уже обкатан, и разъезжаться двум
   трекерам незачем.

   Серый блок в форме будущего контента вместо спиннера по центру пустого экрана.
   Спиннер не говорит, ЧТО грузится, и в момент появления данных страница резко
   «прыгает»; скелетон занимает то же место, что и контент, поэтому переход
   спокойный, а структура видна с первого кадра.

   Волна сделана псевдоэлементом, а не анимацией background-position: градиент
   двигается через transform, то есть на композиторе, без перерисовки слоя. */
.skeleton {
    position: relative;
    overflow: hidden;
    background-color: hsl(var(--secondary));
    border-radius: var(--radius-sm);
}

.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background-image: linear-gradient(90deg,
        transparent 0%, hsl(var(--foreground) / 0.06) 50%, transparent 100%);
    animation: skeleton-shimmer 1.8s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
    100% { transform: translateX(100%); }
}

/* Перелив — украшение, а не индикатор: при reduced-motion убираем его совсем.
   Сам серый блок остаётся и продолжает показывать, что контент грузится (в отличие
   от спиннера, который без вращения выглядит сломанным). */
@media (prefers-reduced-motion: reduce) {
    .skeleton::after { animation: none; }
}

/* Строки-скелетоны внутри обычных таблиц проекта: высота ячейки та же, что у
   настоящей строки, иначе таблица подпрыгнет при появлении данных. */
.skeleton-row td { padding: 10px 14px; }
.skeleton-line { height: 14px; }
.skeleton-list { display: flex; flex-direction: column; gap: 8px; }
.skeleton-list .skeleton { height: 38px; }

/* ── Жучок документации ───────────────────────────────────────────────────────
   Справа внизу, поверх содержимого. Приглушённый: это справка, а не действие —
   ярким он перетягивал бы внимание с недельной таблицы. */
.help-link {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 90;                  /* ниже модалок (300) и выпадашек (400) */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    color: hsl(var(--muted-foreground));
    box-shadow: 0 4px 14px hsl(0 0% 0% / 0.12);
    transition: color .15s, border-color .15s, transform .15s;
}
.help-link:hover {
    color: hsl(var(--primary));
    border-color: hsl(var(--primary) / 0.5);
    transform: translateY(-1px);
}
.help-link:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) { .help-link { transition: none; } }

/* На узком экране нижняя панель навигации занимает низ — поднимаем над ней. */
@media (max-width: 768px) { .help-link { bottom: 72px; } }

/* Недонабранный «Id модели»: шесть цифр ещё не введены, значение не принято.
   Отличается от .is-empty (пусто и так и надо) — здесь человек в процессе. */
.model-cell.is-invalid input { box-shadow: inset 0 0 0 2px hsl(var(--destructive) / 0.55); }

/* Строка «не уточнено» в дереве аналитики: часы есть, но категория выбрана не до
   конца. Приглушена — это не отдельная работа, а остаток узла. */
.tree-row-stopped .chart-label { color: hsl(var(--muted-foreground)); font-style: italic; }

/* ── Ретроспектива: сравнение недель ──────────────────────────────────────────
   Полоски, как в обычном разрезе, только их несколько в строке — по одной на
   неделю. Числа не потерялись: итог в правой колонке, часы недели — в подсказке.
   .chart-row — жёсткая сетка из трёх колонок, поэтому группа полосок занимает
   ровно одну ячейку (среднюю), а не добавляет четвёртую.

   Цвета РАЗНЫЕ, а не оттенки одного синего: оттенками соседние недели на глаз не
   различались, порядок приходилось считать сверху вниз. Подпись недели стоит
   слева у самой полоски — в длинном списке возвращаться к легенде наверх за каждой
   строкой невозможно. */
:root {
    --retro-c1: 220 70% 52%;
    --retro-c2: 172 55% 38%;
    --retro-c3: 38 85% 48%;
    --retro-c4: 272 52% 56%;
    --retro-c5: 348 68% 54%;
    --retro-c6: 142 42% 42%;
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --retro-c1: 220 80% 68%;
        --retro-c2: 172 60% 52%;
        --retro-c3: 38 90% 62%;
        --retro-c4: 272 65% 72%;
        --retro-c5: 348 78% 68%;
        --retro-c6: 142 50% 56%;
    }
}
:root[data-theme="dark"] {
    --retro-c1: 220 80% 68%;
    --retro-c2: 172 60% 52%;
    --retro-c3: 38 90% 62%;
    --retro-c4: 272 65% 72%;
    --retro-c5: 348 78% 68%;
    --retro-c6: 142 50% 56%;
}

.retro-bars { display: flex; flex-direction: column; gap: 4px; }
.retro-bar-line {
    display: grid;
    grid-template-columns: 34px 1fr;
    align-items: center;
    gap: 8px;
}
.retro-bar-week {
    font-size: 11px;
    color: hsl(var(--muted-foreground));
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}
.retro-bar {
    height: 9px;
    border-radius: 999px;
    background: hsl(var(--muted-foreground) / 0.14);
    overflow: hidden;
}
.retro-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: hsl(var(--retro-c1));
    transition: width .25s;
}
.retro-bar-fill.retro-c1 { background: hsl(var(--retro-c1)); }
.retro-bar-fill.retro-c2 { background: hsl(var(--retro-c2)); }
.retro-bar-fill.retro-c3 { background: hsl(var(--retro-c3)); }
.retro-bar-fill.retro-c4 { background: hsl(var(--retro-c4)); }
.retro-bar-fill.retro-c5 { background: hsl(var(--retro-c5)); }
.retro-bar-fill.retro-c6 { background: hsl(var(--retro-c6)); }

.retro-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    padding: 0 0 10px;
    font-size: 12px;
    color: hsl(var(--muted-foreground));
}
.retro-legend span { display: inline-flex; align-items: center; gap: 6px; }
.retro-legend span::before {
    content: "";
    width: 10px; height: 10px;
    border-radius: 3px;
    background: hsl(var(--retro-c1));
}
.retro-legend span.retro-c1::before { background: hsl(var(--retro-c1)); }
.retro-legend span.retro-c2::before { background: hsl(var(--retro-c2)); }
.retro-legend span.retro-c3::before { background: hsl(var(--retro-c3)); }
.retro-legend span.retro-c4::before { background: hsl(var(--retro-c4)); }
.retro-legend span.retro-c5::before { background: hsl(var(--retro-c5)); }
.retro-legend span.retro-c6::before { background: hsl(var(--retro-c6)); }

.retro-row .chart-value { line-height: 1.35; }
.retro-row .retro-delta { display: block; font-size: 11.5px; }
/* Рост и падение — цветом, но не «хорошо/плохо»: больше часов не значит лучше. */
.retro-delta.is-up { color: hsl(220 70% 52%); }
.retro-delta.is-down { color: hsl(28 75% 45%); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .retro-delta.is-up { color: hsl(220 80% 70%); }
    :root:not([data-theme="light"]) .retro-delta.is-down { color: hsl(30 80% 62%); }
}
:root[data-theme="dark"] .retro-delta.is-up { color: hsl(220 80% 70%); }
:root[data-theme="dark"] .retro-delta.is-down { color: hsl(30 80% 62%); }

/* Включённое сравнение — залитая кнопка. Правило висело на #retro-toggle, а кнопок
   с тех пор стало две (своя у каждого дашборда) с другими id: включённый режим
   выглядел ровно как выключенный, и понять, что он включён, можно было только по
   самим графикам. */
.retro-toggle.is-active {
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    border-color: hsl(var(--primary));
}
.retro-toggle.is-active:hover { background: hsl(var(--primary) / 0.9); }

/* Заголовок раздела с действием справа: кнопка относится к своему дашборду, а не ко
   всей странице, и стоять должна рядом с ним. */
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.section-head .section-title { margin: 0; }

/* Недоступная кнопка обязана ВЫГЛЯДЕТЬ недоступной. У .secondary состояния не было
   вовсе: «Ретроспектива» при одной выбранной неделе оставалась синей и звала нажать,
   хотя сравнивать было нечего. */
button.secondary:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    border-color: hsl(var(--border));
    color: hsl(var(--muted-foreground));
}

/* ── Календарь отпусков ───────────────────────────────────────────────────────
   Гантт: строка — сотрудник, колонка — день. Дни идут ПОДРЯД, включая выходные:
   иначе полоска рвалась бы на каждой субботе, хотя человек в отпуске все семь дней.
   Ширина дня задана переменной и продублирована в vacations.js (DAY) — полоски
   позиционируются в пикселях, и разъехаться этим двум числам нельзя. */
:root { --vac-day: 26px; --vac-name: 210px; }

.vac-scroll { overflow-x: auto; background: hsl(var(--card)); border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg); }
.vac-inner { min-width: calc(var(--vac-name) + var(--vac-w)); }

.vac-head { display: flex; position: sticky; top: 0; z-index: 3;
    background: hsl(var(--card)); border-bottom: 1px solid hsl(var(--border)); }
.vac-scale { width: var(--vac-w); }
.vac-months { display: flex; }
.vac-month { font-size: 12px; font-weight: 600; color: hsl(var(--foreground));
    padding: 8px 0 4px 6px; border-left: 1px solid hsl(var(--border)); box-sizing: border-box;
    white-space: nowrap; overflow: hidden; }
.vac-days { display: flex; }
.vac-day { width: var(--vac-day); flex: none; text-align: center; font-size: 10.5px;
    color: hsl(var(--muted-foreground)); padding-bottom: 6px; font-variant-numeric: tabular-nums; }
.vac-day.is-weekend { color: hsl(var(--muted-foreground) / 0.55); }
.vac-day.is-holiday { color: hsl(var(--destructive)); font-weight: 600; }

.vac-row { display: flex; border-bottom: 1px solid hsl(var(--border)); }
.vac-row:last-child { border-bottom: 0; }
.vac-row:hover .vac-name { background: hsl(var(--accent) / 0.5); }

/* Имя прилипает слева: при прокрутке на три месяца вправо без этого непонятно,
   чья это строка. */
.vac-name { width: var(--vac-name); flex: none; position: sticky; left: 0; z-index: 2;
    background: hsl(var(--card)); border-right: 1px solid hsl(var(--border));
    padding: 7px 12px; box-sizing: border-box; overflow: hidden; }
.vac-name-t { display: block; font-size: 13.5px; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; }
.vac-name-w { display: block; font-size: 11px; color: hsl(var(--muted-foreground));
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vac-name-head { display: flex; align-items: flex-end; font-size: 11px; font-weight: 600;
    letter-spacing: .04em; text-transform: uppercase; color: hsl(var(--muted-foreground)); }

.vac-track { width: var(--vac-w); display: flex; position: relative; }
.vac-cell { width: var(--vac-day); flex: none; height: 38px;
    border-right: 1px solid hsl(var(--border) / 0.5); box-sizing: border-box; }
.vac-cell.is-weekend { background: hsl(var(--muted-foreground) / 0.07); }
.vac-cell.is-holiday { background: hsl(var(--destructive) / 0.1); }

.vac-bar { position: absolute; top: 7px; height: 24px; border-radius: 6px;
    background: hsl(var(--primary)); margin-left: 2px; }
/* Период выходит за окно — срезаем угол, чтобы это не читалось как конец отпуска. */
.vac-bar.is-open-left { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: 0; }
.vac-bar.is-open-right { border-top-right-radius: 0; border-bottom-right-radius: 0; }

/* Полоса нагрузки: столбик и число — сколько человек в отпуске в этот день. */
.vac-load { background: hsl(var(--muted-foreground) / 0.04); }
.vac-load .vac-track { align-items: flex-end; }
.vac-load-cell { width: var(--vac-day); flex: none; height: 52px; position: relative;
    display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
    border-right: 1px solid hsl(var(--border) / 0.5); box-sizing: border-box; }
.vac-load-cell.is-weekend { background: hsl(var(--muted-foreground) / 0.07); }
.vac-load-cell.is-holiday { background: hsl(var(--destructive) / 0.1); }
.vac-load-bar { width: 12px; border-radius: 3px 3px 0 0; background: hsl(var(--primary) / 0.45); }
.vac-load-cell span { font-size: 10px; font-variant-numeric: tabular-nums;
    color: hsl(var(--muted-foreground)); line-height: 14px; }

.vac-table th:nth-child(1), .vac-table th:nth-child(2) { width: 27%; }
.vac-table th:nth-child(3) { width: 110px; text-align: right; }
.vac-table th:nth-child(4) { width: 72px; text-align: right; }
.vac-table th:nth-child(5) { width: auto; text-align: left; }
.vac-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Строка календаря кликабельна: за ней карточка со всеми отпусками человека. */
.vac-row.is-clickable { cursor: pointer; }
.vac-row.is-clickable:hover .vac-cell { background: hsl(var(--accent) / 0.35); }
.vac-row.is-clickable:hover .vac-cell.is-weekend { background: hsl(var(--muted-foreground) / 0.12); }
.vac-row.is-clickable:focus-visible { outline: 2px solid hsl(var(--primary)); outline-offset: -2px; }
/* Идущий сейчас отпуск в карточке — чтобы не искать его глазами среди прошлых. */
.employee-tasks-table tr.is-now td { color: hsl(var(--primary)); font-weight: 600; }
.employee-tasks-table td.when { color: hsl(var(--muted-foreground)); white-space: nowrap; }
.employee-tasks-table tr.is-now td.when { color: hsl(var(--primary)); }
