/* Грфк Джрств — стили. Спокойный деловой светлый интерфейс. */

:root {
    --color-primary-dark: #1f3a5f;
    --color-primary: #2f6fb1;
    --color-bg: #f4f6f9;
    --color-card: #ffffff;
    --color-border: #e1e7ee;
    --color-text: #1f2b3a;
    --color-muted: #6b7a8c;
    --badge-gray-bg: #eceff2;
    --badge-gray-text: #55606b;
    --badge-yellow-bg: #fdf3d6;
    --badge-yellow-text: #8a6d1a;
    --badge-green-bg: #dcf3e3;
    --badge-green-text: #1c7a41;
    --badge-red-bg: #fbe1e1;
    --badge-red-text: #a12727;
    --radius: 12px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 15px;
    line-height: 1.5;
}

.app-header {
    background: var(--color-primary-dark);
    color: #fff;
}
.app-header__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 14px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}
.app-header__brand { display: flex; flex-direction: column; }
.app-header__org { font-size: 13px; opacity: .8; }
.app-header__title { font-size: 19px; font-weight: 700; }
.app-header__user { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.app-header__role { background: rgba(255,255,255,.15); padding: 3px 10px; border-radius: 20px; font-size: 12px; }
.app-header__logout { color: #fff; text-decoration: none; border: 1px solid rgba(255,255,255,.4); padding: 5px 12px; border-radius: 8px; }
.app-header__logout:hover { background: rgba(255,255,255,.12); }

.app-main {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

.card {
    background: var(--color-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 20px 24px;
    margin-bottom: 20px;
    box-shadow: 0 2px 8px rgba(31,58,95,.04);
}
.card__title { margin-top: 0; color: var(--color-primary-dark); font-size: 18px; }

.login-page { display: flex; justify-content: center; padding-top: 40px; }
.login-card { width: 100%; max-width: 380px; }
.login-card__title { text-align: center; color: var(--color-primary-dark); }

.form { display: flex; flex-direction: column; gap: 6px; }
.form--inline { flex-direction: row; align-items: center; flex-wrap: wrap; gap: 10px; }
.form__label { font-size: 13px; color: var(--color-muted); margin-top: 8px; }
.form--inline .form__label { margin-top: 0; }
.form__input {
    padding: 9px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 14px;
    background: #fff;
    color: var(--color-text);
}
.form__input--small { padding: 6px 8px; }
.form__submit { margin-top: 14px; }

.btn {
    display: inline-block;
    border: none;
    border-radius: 8px;
    padding: 9px 18px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
}
.btn--primary { background: var(--color-primary); color: #fff; }
.btn--primary:hover { background: var(--color-primary-dark); }
.btn--secondary { background: #eef2f7; color: var(--color-primary-dark); }
.btn--secondary:hover { background: #dde5ee; }
.btn--confirm { background: var(--badge-green-bg); color: var(--badge-green-text); }
.btn--reject { background: var(--badge-red-bg); color: var(--badge-red-text); }
.btn--tiny { padding: 4px 10px; font-size: 12px; margin-left: 4px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.alert { padding: 10px 14px; border-radius: 8px; margin-bottom: 12px; font-size: 14px; }
.alert--error { background: var(--badge-red-bg); color: var(--badge-red-text); }
.alert--info { background: var(--badge-yellow-bg); color: var(--badge-yellow-text); }

.badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 600;
}
.badge--gray { background: var(--badge-gray-bg); color: var(--badge-gray-text); }
.badge--yellow { background: var(--badge-yellow-bg); color: var(--badge-yellow-text); }
.badge--green { background: var(--badge-green-bg); color: var(--badge-green-text); }
.badge--red { background: var(--badge-red-bg); color: var(--badge-red-text); }

.tabs { display: flex; gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
.tabs__btn {
    background: #eef2f7;
    border: none;
    padding: 9px 16px;
    border-radius: 8px 8px 0 0;
    cursor: pointer;
    font-size: 14px;
    color: var(--color-primary-dark);
    text-decoration: none;
    display: inline-block;
}
.tabs__btn.is-active { background: var(--color-primary); color: #fff; }
.tabs__btn--link { background: #eef2f7; }

.tab-panel { display: none; }
.tab-panel.is-active { display: block; }

.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { padding: 8px 10px; border-bottom: 1px solid var(--color-border); text-align: left; white-space: nowrap; }
.table tbody tr:nth-child(even) { background: #fafbfc; }
.table tbody tr.is-weekend,
.table tbody tr.is-weekend:nth-child(even) { background: #fdf3e6; }
.table tbody tr.is-weekend .cell-date { color: #b4530a; }
.cell-date { white-space: nowrap; }
.table th { color: var(--color-muted); font-weight: 600; font-size: 13px; }

.manager-info { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin-bottom: 8px; }
.manager-info__item { display: flex; flex-direction: column; gap: 2px; }
.manager-info__label { font-size: 12px; color: var(--color-muted); }
.manager-info__value { font-size: 16px; font-weight: 700; color: var(--color-primary-dark); }

.password-change { margin-top: 12px; }
.password-change summary { cursor: pointer; color: var(--color-primary); font-size: 14px; }

.period-select { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.filter-group { display: flex; align-items: center; gap: 8px; }

.admin-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.admin-toolbar__slots { font-size: 13px; color: var(--color-muted); margin-left: auto; }

.request-row { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; flex-wrap: wrap; }
.muted { color: var(--color-muted); font-size: 13px; }
.hint { color: var(--color-muted); font-size: 12px; margin-left: 6px; }

.assign-form { display: flex; gap: 4px; }

.tag-list { display: flex; gap: 6px; flex-wrap: wrap; }

.actions-cell { display: flex; gap: 4px; flex-wrap: wrap; }
.inline-form { display: inline; }

.edit-row td { background: #f7f9fb; }

@media (max-width: 700px) {
    .app-header__inner { flex-direction: column; align-items: flex-start; }
    .card { padding: 16px; }
    .period-select { flex-direction: column; align-items: stretch; }
    .filter-group { flex-direction: column; align-items: stretch; gap: 4px; width: 100%; }
    .filter-group .form__input { width: 100%; }
}

/* Поле формы: подпись всегда над своим полем и не отрывается при переносе */
.form--inline .field { display: flex; flex-direction: column; gap: 4px; min-width: 190px; }
.form--inline .field .form__label { margin: 0; }
.form--inline .btn { align-self: flex-end; }
@media (max-width: 640px) {
    .form--inline .field { min-width: 100%; }
    .form--inline .btn { width: 100%; }
}

/* Комментарий в таблицах обмена сменами: ограничиваем ширину, полный текст всплывающей подсказкой (title) */
.cell-comment {
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* V1.3: строка занятой чужой даты в «Моё расписание» — приглушённый жёлто-серый фон,
   чтобы визуально отличаться от своей заявки (badge--yellow) и от выходного (is-weekend). */
.is-taken { background: #f2eee6 !important; }
.is-taken .cell-date { color: var(--color-muted); }

/* V1.3: счётчик «Кол-во смен» > 2 — красным и жирным, и в карточке менеджера, и в сводке. */
.count-alert { color: var(--badge-red-text); font-weight: 700; }

/* V1.3: ФИО владельца кабинета в «Общем графике» — жирным, чтобы выделяться среди коллег. */
.is-me { font-weight: 700; }

/* V1.3: подсказка над таблицей «Моё расписание» о правиле смены из двух дней. */
.schedule-hint {
    background: var(--badge-yellow-bg);
    color: var(--badge-yellow-text);
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 13px;
    margin-bottom: 14px;
}

/* V1.3: подпись занятости чужой датой (ФИО + статус) рядом с заблокированным чекбоксом. */
.taken-by { color: var(--color-muted); font-size: 12px; margin-left: 6px; }

/* ==========================================================================
   V1.4 — вкладка «Дашборд» (список + календарь). Все новые классы —
   только добавление в конец файла, существующие правила не затронуты.
   ========================================================================== */

/* Короткая строка-легенда под заголовком дашборда. */
.dashboard-legend { color: var(--color-muted); font-size: 14px; margin-top: -4px; margin-bottom: 14px; }

/* Переключатели вида внутри дашборда: видима только активная панель. */
.dashboard-view { display: none; }
.dashboard-view.is-active { display: block; }

/* Компактная таблица вида «Списком» — уменьшенные отступы и шрифт, чтобы весь
   месяц помещался на экране без прокрутки на десктопе. Применяется только в
   паре с .table и только на дашборде — остальные таблицы не затронуты. */
.table--compact th, .table--compact td { padding: 4px 8px; font-size: 13px; }

/* Календарь: сетка 7 колонок (Пн..Вс), как в календаре телефона/трее Windows. */
.calendar-scroll { overflow-x: auto; }
.calendar {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 700px;
}
.calendar__row {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}
.calendar__row--head { margin-bottom: 2px; }
.calendar__headcell {
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-muted);
    padding: 4px 0;
}
.calendar__cell {
    aspect-ratio: 1 / 1;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: #fff;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow: hidden;
    box-sizing: border-box;
}
.calendar__cell--empty {
    border-color: transparent;
    background: transparent;
}
.calendar__cell--weekend { background: #fdf3e6; }
.calendar__cell--filled { background: var(--badge-green-bg); }
.calendar__cell--weekend.calendar__cell--filled {
    /* Мягкая смесь выходного и закрытой даты: оставляем зелёный фон ведущим —
       наличие дежурного важнее для читателя, чем выходной день. */
    background: var(--badge-green-bg);
}
.calendar__cell--today {
    border: 2px solid var(--color-primary);
    box-shadow: 0 0 0 1px var(--color-primary) inset;
}
.calendar__cell-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px;
}
.calendar__daynum {
    font-size: 15px;
    font-weight: 700;
    color: var(--color-primary-dark);
}
.calendar__weekday {
    font-size: 11px;
    color: var(--color-muted);
}
.calendar__duty {
    font-size: 12px;
    line-height: 1.25;
    color: var(--badge-green-text);
    font-weight: 600;
    /* Перенос только по словам (ФИО уже сокращено short_name() до
       «Фамилия И. О.», поэтому разрыв внутри слова не нужен — это исключает
       обрезание типа «Долгопят» вместо «Долгопятов». */
    overflow-wrap: normal;
    word-break: keep-all;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

@media (max-width: 700px) {
    /* Мобильная версия календаря: сетка 7 колонок сохраняется, ячейки и шрифт
       уменьшаются. min-width подобран так, чтобы все 7 колонок помещались
       в экран 375-390px без горизонтального скролла; на более узких экранах
       контейнер всё равно скроллится по горизонтали (см. .calendar-scroll). */
    .calendar { min-width: 490px; gap: 3px; }
    .calendar__row { gap: 3px; }
    .calendar__cell { padding: 3px; gap: 1px; border-radius: 5px; }
    .calendar__cell-head { flex-direction: column; align-items: flex-start; gap: 0; }
    .calendar__daynum { font-size: 12px; }
    .calendar__weekday { font-size: 8px; }
    .calendar__duty { font-size: 9px; line-height: 1.15; -webkit-line-clamp: 3; }
    .calendar__headcell { font-size: 10px; padding: 2px 0; }
    .dashboard-legend { font-size: 13px; }

    /* Мобильная версия списка: на узких экранах показываем сокращённое ФИО
       («Фамилия И. О.») вместо полного, чтобы вся строка помещалась без
       горизontального скролла; полное имя остаётся в title (см. разметку). */
    .table--compact th, .table--compact td { white-space: nowrap; }
    .dashboard-fullname { display: none; }
    .dashboard-shortname { display: inline; }
}
@media (min-width: 701px) {
    .dashboard-fullname { display: inline; }
    .dashboard-shortname { display: none; }
}

/* Визуальная подсказка о горизонтальном скролле на узких экранах — отдельный
   класс .dashboard-scroll-hint, применяется ТОЛЬКО внутри дашборда (навешивается
   рядом с .table-scroll/.calendar-scroll в dashboard.php), поэтому остальные
   страницы, использующие .table-scroll/.calendar-scroll, не затронуты. */
@media (max-width: 700px) {
    .dashboard-scroll-hint {
        position: relative;
        box-shadow: inset -8px 0 6px -6px rgba(31,58,95,.18);
    }
}

/* V1.4: вложенный ряд вкладок дашборда (вид списком / календарь) */
.tabs--sub { margin-top: -4px; }
.tabs--sub .tabs__btn { font-size: 13px; padding: 6px 14px; }

/* V1.5: блок жёстких условий на странице «Генерация».
   Отделён от остальных карточек цветной полосой слева и лёгкой подложкой,
   чтобы читалось как настройка перед генерацией, а не как часть графика. */
.constraints-block {
    border-left: 4px solid var(--color-primary);
    background: #fbfcfe;
}
.constraints-block__note {
    display: block;
    margin-left: 0;
    margin-bottom: 12px;
}
.constraints-form {
    align-items: flex-end;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--color-border);
}
.constraints-form__actions { gap: 8px; }
.constraints-empty td { padding: 10px 8px; }

/* V1.5: таблица черновика и отчёты на странице «Генерация».
   Ключевое: у .table по умолчанию white-space: nowrap, а обоснование
   генератора бывает до 500 символов — без переноса таблица расползается,
   поэтому ячейки с текстом переводим в обычный перенос и ограничиваем ширину. */
/* Специфичность важна: существующее правило «.table th, .table td»
   задаёт white-space: nowrap и весит больше одиночного класса,
   поэтому селектор обязан включать и .table, и td. */
.table td.draft-reason {
    white-space: normal;
    max-width: 460px;
    min-width: 220px;
    font-size: 13px;
    line-height: 1.45;
    color: #55606b;
}
.table td.draft-reason .reason-list li { white-space: normal; }
.draft-table .draft-assign { min-width: 190px; }
.draft-row--empty td { background: #fffaf0; }
.draft-row--diverged td { background: #fff6f6; }

.reason-list { margin: 0; padding-left: 18px; }
.reason-list li { margin: 2px 0; }

/* Блок последствий утверждения. */
.impact-block {
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-muted);
    border-radius: 8px;
    padding: 12px 14px;
    margin: 12px 0;
    background: #fafbfc;
}
.impact-block--warn {
    border-left-color: #d98324;
    background: #fdf6ec;
}
.impact-block__title { display: block; margin-bottom: 8px; font-size: 14px; }
.impact-block__list { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.6; }
.impact-block__details { margin-top: 8px; font-size: 13px; }
.impact-block__details summary { cursor: pointer; color: var(--color-primary); }

/* Пометки расхождений снимка и живого графика. */
.divergence {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.divergence--removed  { background: var(--badge-red-bg);    color: var(--badge-red-text); }
.divergence--replaced { background: var(--badge-yellow-bg); color: #6f560f; }
.divergence--added    { background: var(--badge-gray-bg);   color: var(--badge-gray-text); }

.generated-subtitle { margin-top: 20px; font-size: 15px; }

/* V1.5: метки источника смены в черновике.
   Раньше «пусто» и «генератор» использовали один и тот же .badge--gray
   и были неотличимы — поэтому у каждого источника свой цвет.
   Пары фон/текст подобраны светлый фон + тёмный текст. */
.source-badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.source-badge--generated { background: #e6eefb; color: #1f4d80; }
.source-badge--manual    { background: #fdf3d6; color: #7a5f13; }
.source-badge--empty     { background: #eceff2; color: #4c5661; }

/* Заблокированные элементы черновика на утверждённом месяце: должно быть
   очевидно, что правка недоступна, а не что интерфейс сломался. */
.draft-table .draft-assign:disabled {
    background: #f1f3f6;
    color: #55606b;
    cursor: not-allowed;
}
.btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
body.is-busy { cursor: progress; }
