:root {
    --px-per-minute: 0.25px;
    --day-height: calc(1440 * var(--px-per-minute));
    --hour-gutter-width: 42px;
    --radius-card: 12px;
    --radius-seg: 8px;
    --card-shadow: 0 1px 4px rgba(0,0,0,0.07), 0 0 0 1px rgba(0,0,0,0.04);
    --card-shadow-dark: 0 1px 6px rgba(0,0,0,0.35), 0 0 0 1px rgba(255,255,255,0.04);
    --text-primary: var(--tg-theme-text-color, #374151);
    --text-muted: var(--tg-theme-hint-color, #6B7280);
    --app-safe-top: 90px;
}

[x-cloak] { display: none !important; }

/* ── Базовый фон ────────────────────────────────── */

/* DaisyUI при открытой модалке вешает на :root `overflow: hidden;
   scrollbar-gutter: stable`. Второе здесь вредно: страница сама по себе не
   прокручивается никогда — и в месяце, и в дне прокрутка живёт во внутренних
   контейнерах (.month-scroll, .day-detail-scroll), а body всегда ровно по
   высоте экрана. Полосы прокрутки на руте не бывает, компенсировать нечего:
   `stable` просто отъедал ~15 px справа, а при открытии модалки этот гаттер
   появлялся с нуля и дёргал весь фон влево.

   Поэтому гаттер отключаем, а `overflow: hidden` оставляем — он безвреден
   ровно по той же причине. Если когда-нибудь страница начнёт прокручиваться
   целиком, рывок вернётся, и тогда правильным решением будет убрать саму
   прокрутку рута, а не резервировать полосу. */
:root:has(:is(.modal-open, .modal:target, .modal-toggle:checked + .modal, .modal[open])) {
    scrollbar-gutter: auto;
}

body {
    background-color: var(--tg-theme-secondary-bg-color, #F0F1F5);
    color: var(--text-primary);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

[data-theme="dark"] body {
    background-color: var(--tg-theme-secondary-bg-color, #1C1C1E);
}

.app-container {
    width: 100%;
    padding: var(--app-safe-top) 6px 24px;
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

/* ── Переключатель Месяц / Неделя ───────────────── */

.view-toggle {
    display: flex;
    background: rgba(0,0,0,0.07);
    border-radius: 10px;
    padding: 3px;
    gap: 3px;
    margin-bottom: 10px;
}

[data-theme="dark"] .view-toggle {
    background: rgba(255,255,255,0.08);
}

.view-toggle button {
    flex: 1;
    padding: 6px 8px;
    border-radius: 8px;
    font-size: 0.8rem;
    font-weight: 600;
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: all 0.18s;
}

.view-toggle button.active {
    background: var(--tg-theme-bg-color, #fff);
    color: var(--text-primary);
    box-shadow: 0 1px 4px rgba(0,0,0,0.13);
}

/* ── Слайдер видов (Месяц / Неделя) ─────────────── */

.views-container {
    overflow: hidden;
}

.views-track {
    display: flex;
    width: 200%;
    transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    align-items: flex-start;
}

.view-panel {
    width: 50%;
    flex-shrink: 0;
    min-width: 0;
}

/* ── Навигация по неделе ────────────────────────── */

.week-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
    padding: 0 2px;
}

.week-label {
    font-size: 0.88rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    color: var(--text-primary);
}

.day-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
    padding: 0 2px;
}

.day-nav-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
}

/* ── Сетка расписания ───────────────────────────── */

.schedule-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 8px;
}

/* ── Карточка дня ───────────────────────────────── */

.day-column {
    background: var(--tg-theme-bg-color, #FFFFFF);
    border-radius: var(--radius-card);
    box-shadow: var(--card-shadow);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

[data-theme="dark"] .day-column {
    box-shadow: var(--card-shadow-dark);
}

.day-header {
    text-align: center;
    padding: 6px 4px 4px;
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--tg-theme-bg-color, #FFFFFF);
    border-bottom: 2px solid rgba(148,163,184,0.12);
    line-height: 1.2;
}

[data-theme="dark"] .day-header {
    border-bottom-color: rgba(255,255,255,0.07);
}

.day-header.is-today {
    border-bottom-color: var(--tg-theme-link-color, #3b82f6);
}

.day-name {
    display: block;
    font-size: 0.74rem;
    font-weight: 700;
    color: var(--text-muted);
}

.day-date {
    display: block;
    font-size: 0.64rem;
    color: var(--text-muted);
    opacity: 0.7;
    margin-top: 1px;
}

.day-header.is-today .day-name,
.day-header.is-today .day-date {
    color: var(--tg-theme-link-color, #3b82f6);
    opacity: 1;
}

.day-body {
    position: relative;
    height: var(--day-height);
}

/* ── Базовый сегмент ────────────────────────────── */

.segment-card {
    position: absolute;
    left: 5px;
    right: 5px;
    z-index: 2;
    border-radius: var(--radius-seg);
    padding: 4px 6px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 2px;
}

/* ── Свободные слоты ────────────────────────────── */

.free-slot {
    cursor: pointer;
    overflow: hidden;
    padding: 4px 8px;
    justify-content: center;
    background: rgba(148,163,184,0.16);
    backdrop-filter: blur(1.5px);
    -webkit-backdrop-filter: blur(1.5px);
    transition: background-color 0.12s;
}

[data-theme="dark"] .free-slot {
    background: rgba(148,163,184,0.22);
}

.free-slot:hover {
    background: rgba(148,163,184,0.26);
}

[data-theme="dark"] .free-slot:hover {
    background: rgba(148,163,184,0.32);
}

.slot-past {
    opacity: 0.35;
    cursor: default;
    pointer-events: none;
}

/* ── Подписи в свободных слотах ─────────────────── */

.seg-time {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.1;
}

/* ── Назначенные смены ──────────────────────────── */

.shift-block {
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    transition: filter 0.12s;
    justify-content: center;
    gap: 1px;
}

/* Полностью непрозрачно: дорожки накладываются друг на друга, и даже 5%
   прозрачности давали просвечивающую нижнюю плитку в месте наложения. */
[data-theme="dark"] .shift-block {
    background-color: rgb(var(--shift-rgb)) !important;
}

[data-theme="dark"] .shift-block:hover {
    background-color: rgba(var(--shift-rgb), 1) !important;
}

.shift-block.shift-selected {
    box-shadow: 0 2px 8px rgba(var(--shift-rgb), 0.35);
    background-color: rgba(var(--shift-rgb), 1) !important;
}

.shift-name {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
}

.shift-time {
    font-size: 0.8rem;
    color: var(--text-primary);
    opacity: 0.6;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1;
}

/* Блок смены залит цветом менеджера, поэтому подпись на нём не может зависеть
   от темы Telegram: --shift-text приходит из slotStyle и подобран по яркости
   заливки (тёмный на светлой, светлый на тёмной). Без этого в тёмной теме
   светлый --text-primary ложился на светлый пастельный фон. */
.shift-block .shift-name,
.shift-block .shift-time {
    color: var(--shift-text, var(--text-primary));
}

.shift-selected .shift-name,
.shift-selected .shift-time {
    opacity: 1 !important;
}

/* ≤90 мин в детальном виде дня: имя и время в одну строку */
.shift-compact {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 0 4px;
}
.shift-compact .shift-name {
    flex-shrink: 1;
    min-width: 0;
}
.shift-compact .shift-time {
    flex-shrink: 0;
    white-space: nowrap;
}

/* ── Скелетон-загрузка ──────────────────────────── */

@keyframes shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-bar {
    border-radius: 8px;
    background: linear-gradient(90deg, rgba(0,0,0,0.04) 25%, rgba(0,0,0,0.09) 50%, rgba(0,0,0,0.04) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.6s infinite;
}

[data-theme="dark"] .skeleton-bar {
    background: linear-gradient(90deg, rgba(255,255,255,0.05) 25%, rgba(255,255,255,0.11) 50%, rgba(255,255,255,0.05) 75%);
    background-size: 200% 100%;
}

/* ── Оверлей начальной загрузки ─────────────────── */

.app-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 250;
    background: var(--tg-theme-secondary-bg-color, #F0F1F5);
    padding: var(--app-safe-top) 6px 24px;
    overflow: hidden;
    pointer-events: all;
}

[data-theme="dark"] .app-loading-overlay {
    background: var(--tg-theme-secondary-bg-color, #1C1C1E);
}

.app-overlay-leave {
    transition: opacity 0.25s ease;
}

/* ── Месячный вид: контейнер ────────────────────── */

.month-view-container {
    display: flex;
    flex-direction: column;
    height: calc(100svh - var(--app-safe-top, 90px) - 24px);
    background: var(--tg-theme-bg-color, #fff);
    border-radius: var(--radius-card);
    box-shadow: var(--card-shadow);
    overflow: hidden;
}

[data-theme="dark"] .month-view-container {
    box-shadow: var(--card-shadow-dark);
}

/* ── Шапка месяца (не прокручивается) ────────────── */

.month-header-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 10px 7px;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(148,163,184,0.1);
}

.month-header-left,
.month-header-right {
    min-width: 72px;
    display: flex;
    align-items: center;
}

.month-header-right {
    justify-content: flex-end;
}

.month-label {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text-primary);
    text-align: center;
    flex: 1;
}

/* ── Индикатор блокировки слева ──────────────────── */

/* У обычного менеджера это не кнопка, а метка, и показывается она только для
   закрытого месяца — значит выглядит так же заметно, как закрытая кнопка. */
.month-lock-indicator {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 6px 9px;
    border-radius: 9px;
    background: #ef4444;
    color: #fff;
    font-size: 0.72rem;
    font-weight: 800;
    line-height: 1;
}

/* ── Кнопка блокировки (справа, только для админа) ── */

/* Открытый месяц — норма, и подсвечивать её незачем: кнопка выглядит как
   тихая подпись. Закрытый — исключение, которое должно бросаться в глаза,
   поэтому он заливается красным. Так в шапке остаётся ровно одно яркое
   пятно-действие («Отпуск»), а состояние месяца кричит только когда оно
   нештатное. */
.month-lock-btn {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 6px 9px;
    border-radius: 9px;
    border: none;
    background: transparent;
    font-size: 0.82rem;
    cursor: pointer;
    transition: background 0.15s, filter 0.15s;
    line-height: 1;
    white-space: nowrap;
}

.month-lock-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-muted);
}

.month-lock-btn:hover {
    background: rgba(148,163,184,0.14);
}

.month-lock-btn--locked {
    background: #ef4444;
}

.month-lock-btn--locked .month-lock-label {
    color: #fff;
    font-weight: 800;
}

.month-lock-btn--locked:hover {
    background: #ef4444;
    filter: brightness(1.06);
}


[data-theme="dark"] .month-lock-btn {
    background: rgba(255,255,255,0.07);
    border-color: rgba(255,255,255,0.15);
}

[data-theme="dark"] .month-lock-btn:hover {
    background: rgba(255,255,255,0.12);
}

[data-theme="dark"] .month-lock-btn--locked {
    background: #dc2626;
}

/* ── Строка дней недели (не прокручивается) ──────── */

.month-weekday-headers {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border-bottom: 1px solid rgba(148,163,184,0.12);
    flex-shrink: 0;
}

.month-weekday-header {
    text-align: center;
    padding: 6px 2px 5px;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

/* ── Прокручиваемая область месяцев ──────────────── */

.month-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    -webkit-overflow-scrolling: touch;
    /* Место под полосу прокрутки зарезервировано всегда: при блокировке
       (см. ниже) она исчезает, и без гаттера сетка дёргалась бы по ширине. */
    scrollbar-gutter: stable;
    /* Прокрутка не уходит наверх, когда внутренний список докручен до края */
    overscroll-behavior: contain;
}

/* Шит «Отпуска» открыт — месяц под ним стоит: прокручивать фон, глядя в
   панель, незачем, а чужое движение под пальцем читается как сбой. */
.month-scroll.is-locked {
    overflow-y: hidden;
}

/* ── Секция одного месяца ─────────────────────────── */

.month-section {
    display: flex;
    flex-direction: column;
}

.month-section-label {
    font-size: 1rem;
    font-weight: 800;
    color: var(--text-primary);
    padding: 12px 10px 4px;
    letter-spacing: -0.01em;
}

/* ── Строки недель ────────────────────────────────── */

.month-week-row {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border-bottom: 1px solid rgba(148,163,184,0.08);
    height: 120px;
    flex-shrink: 0;
}

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

.month-cell {
    position: relative;  /* якорь для значка отпуска в углу */
    padding: 2px 2px 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    min-height: 0;
    overflow: hidden;
    border-right: 1px solid rgba(148,163,184,0.06);
}

.month-cell:last-child {
    border-right: none;
}

.month-cell:not(.out-of-month) {
    cursor: pointer;
    transition: background 0.1s;
    border-radius: 4px;
}

/* Подсветка наведения. Два ограничения, оба обязательны:

   `@media (hover: hover)` — на тач-экране `:hover` залипает на последнем
   тронутом элементе и остаётся, пока не тронут другой; в режиме выбора отпуска
   это читалось как «день выделился серым» поверх синего диапазона.

   `:not(.sel-*)` — на мыши: наведение на выбранный день не должно перебивать
   цвет диапазона, у hover иначе специфичность выше. */
@media (hover: hover) {
    .month-cell:not(.out-of-month):not(.sel-mid):not(.sel-start):not(.sel-end):not(.sel-single):hover {
        background: rgba(0,0,0,0.05);
    }

    [data-theme="dark"] .month-cell:not(.out-of-month):not(.sel-mid):not(.sel-start):not(.sel-end):not(.sel-single):hover {
        background: rgba(255,255,255,0.07);
    }
}

.month-cell.out-of-month .month-day-num {
    opacity: 0.28;
}

.month-day-num {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-primary);
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    line-height: 1;
    flex-shrink: 0;
}

.month-cell.is-today .month-day-num {
    background: var(--tg-theme-link-color, #3b82f6);
    color: #f9fafb;
}

/* ── Кнопка «Отпуск» и выбор диапазона ──────────── */

/* Форма как у кнопок-действий, но заливка приглушённая: шапка — не место для
   яркого пятна, а единственное цветное здесь и так закрытый месяц. Цветным
   остаётся только смайлик. */
.month-absence-btn {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 6px 10px;
    border-radius: 9px;
    border: none;
    background: rgba(45,212,191,0.16);
    color: var(--text-primary);
    font-size: 0.82rem;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s;
}

[data-theme="dark"] .month-absence-btn {
    background: rgba(45,212,191,0.2);
}

.month-absence-btn:hover {
    background: rgba(45,212,191,0.26);
}

.month-absence-btn.is-open {
    background: rgba(45,212,191,0.34);
}

.month-absence-btn-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: inherit;
}

.absence-select-bar {
    /* Якорь для выпадающего списка имён: он прижат к левому краю полосы, а не
       к кнопке, — под кнопкой у правого края ему не хватало места. */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 9px 10px;
    background: rgba(45,212,191,0.14);
    border-bottom: 1px solid rgba(45,212,191,0.45);
    flex-shrink: 0;
}

/* Верхняя строка: даты с количеством дней слева, сообщение — справа. */
.absence-select-top {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

/* Сдвигает даты на базовую линию первой строки сообщения */
.absence-select-emoji,
.absence-select-title {
    padding-top: 1px;
}

.absence-select-emoji {
    font-size: 1rem;
    line-height: 1.3;
    flex-shrink: 0;
}

/* Даты и под ними количество дней. Высоту полосы это не меняет: справа блок
   сообщения и так зарезервирован под три строки. Сами даты не переносятся —
   «14.10 – 24.10» в две строки читается как две разные даты. */
.absence-select-title {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-primary);
    white-space: nowrap;
}

.absence-select-days {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-muted);
}

/* Сообщение об ошибке. Высота фиксированная — под три строки: текст появляется
   и исчезает по ходу выбора, а тексты разной длины меняли бы её каждый раз, и
   полоса прыгала бы, утаскивая за собой сетку месяца. Что длиннее трёх строк —
   прокручивается внутри блока, а не раздвигает его. */
.absence-select-msg {
    margin-left: auto;
    min-width: 0;
    max-width: 58%;
    height: 4.05em;
    overflow-y: auto;
    text-align: right;
    font-size: 0.68rem;
    line-height: 1.35;
    color: #ef4444;
}

/* Нижняя строка: имя слева, кнопки прижаты вправо. */
.absence-select-foot {
    display: flex;
    align-items: center;
    gap: 8px;
}

.absence-select-cancel {
    margin-left: auto;
}

.absence-select-cancel,
.absence-select-save {
    flex-shrink: 0;
    min-height: 32px;
    padding: 0 12px;
    border-radius: 8px;
    font-size: 0.75rem;
    font-weight: 700;
    cursor: pointer;
}

.absence-select-cancel {
    border: 1px solid rgba(148,163,184,0.4);
    background: transparent;
    color: var(--text-muted);
}

.absence-select-save {
    border: none;
    background: var(--tg-theme-button-color, #3b82f6);
    color: var(--tg-theme-button-text-color, #fff);
}

/* Подсветка выбранного диапазона. Скругление только по краям — внутри дни
   идут сплошной полосой, как в любом выборе периода. */
.month-cell.sel-mid,
.month-cell.sel-start,
.month-cell.sel-end,
.month-cell.sel-single {
    background: rgba(59,130,246,0.20);
}

.month-cell.sel-start { border-radius: 10px 0 0 10px; }
.month-cell.sel-end { border-radius: 0 10px 10px 0; }
.month-cell.sel-single { border-radius: 10px; }

/* Число в выбранных днях. Края диапазона выглядят как его середина: сплошной
   синий кружок на них повторял отметку «сегодня» и читался как она. Подложка
   своя — полупрозрачный синий диапазона, заметно отличный от кружка. */
.month-cell.sel-mid .month-day-num,
.month-cell.sel-start .month-day-num,
.month-cell.sel-end .month-day-num,
.month-cell.sel-single .month-day-num {
    background: rgba(59,130,246,0.38);
    color: var(--text-primary);
}

/* ── Отпуска в месячной сетке ───────────────────── */

/* Правый верхний угол ячейки: левый занят числом дня. Овал без рамки — плашка
   под значками нужна, чтобы они не сливались с цветными блоками смен, но
   обводка спорила бы с ними. Слева отпуск (и число, если людей больше одного),
   справа — ожидание согласования; без него овал короче. */
.month-absence-badge {
    position: absolute;
    top: 3px;
    right: 2px;
    display: flex;
    align-items: center;
    gap: 5px;
    line-height: 1;
    pointer-events: none;
}

.month-absence-count {
    display: none;
}

.month-absence-side {
    display: flex;
    align-items: center;
    gap: 2px;
}

.month-absence-emoji {
    font-size: 0.62rem;
    line-height: 1;
    display: flex;
    align-items: center;
}

.month-absence-count {
    font-size: 0.62rem;
    font-weight: 800;
    color: var(--text-primary);
}

/* На широком экране ячейка просторнее — значок можно дать крупнее, он читается
   с расстояния и не спорит с плашками смен. */
@media (min-width: 600px) {
    /* На широком экране значку есть где развернуться: овал с фоном, число
       людей и отдельный значок ожидания — прозрачность тогда не нужна. */
    .month-absence-badge {
        top: 4px;
        right: 4px;
        gap: 6px;
        padding: 3px 7px;
        border-radius: 999px;
        background: rgba(45,212,191,0.20);
    }

    [data-theme="dark"] .month-absence-badge {
        background: rgba(45,212,191,0.24);
    }

    .month-absence-count {
        display: inline;
    }

    .month-absence-emoji {
        font-size: 0.8rem;
    }

    .month-absence-count {
        font-size: 0.72rem;
    }
}

/* ── Смены в месячной сетке ─────────────────────── */

.month-shifts {
    display: flex;
    flex-direction: column;
    gap: 1px;
    width: 100%;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.month-shift-pill {
    display: flex;
    align-items: flex-start;
    gap: 2px;
    padding: 2px 3px 0;
    border-radius: 3px;
    font-size: 0.58rem;
    line-height: 1.25;
    overflow: hidden;
    min-height: 26px;
    border-left: 2px solid var(--shift-color, #9CA3AF);
}

/* Внутренняя обёртка плашки: сама плашка — flex-контейнер, а содержимое
   приходит одним из взаимоисключающих шаблонов (одна смена / группа), которым
   нужен общий корень. */
.month-pill-body {
    display: flex;
    align-items: flex-start;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.month-shift-emoji {
    display: none;
    flex-shrink: 0;
    line-height: 1.25;
}

/* Значок группы нужен и на мобиле, где обычные эмодзи смен скрыты: он несёт
   смысл «здесь несколько человек», а не украшение. */
.month-shift-emoji.month-group-icon {
    display: inline;
}

/* Компактный вид группы: значок с количеством сверху, время под ними — от
   левого края плашки, как у обычной смены. */
.month-group-compact {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.month-group-head {
    display: flex;
    align-items: center;
    gap: 2px;
    min-width: 0;
}

/* Построчный состав группы (двое на десктопе) */
.month-group-rows {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.month-group-row {
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
}

.month-group-row .month-shift-name {
    flex: 1;
}

.month-group-row .month-shift-time {
    margin-left: auto;
    flex-shrink: 0;
}

.month-shift-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.month-shift-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
    opacity: 0.9;
}

.month-shift-time {
    white-space: nowrap;
    color: var(--text-muted);
    font-size: 0.9em;
    opacity: 0.85;
}

/* Плашка залита цветом менеджера с альфой, то есть в тёмной теме она
   получается заметно светлее фона страницы. Приглушённый --text-muted на ней
   почти не читается (особенно время), поэтому на плашках смен подписи берём
   не из темы, а фиксированные под заливку. */
[data-theme="dark"] .month-shift-pill .month-shift-name {
    color: #F9FAFB;
    opacity: 1;
}

[data-theme="dark"] .month-shift-pill .month-shift-time {
    color: rgba(249, 250, 251, 0.82);
    opacity: 1;
}

.month-shift-pill .month-shift-time {
    color: rgba(31, 41, 55, 0.78);
    opacity: 1;
}

.month-free-pill {
    display: flex;
    align-items: flex-start;
    padding: 2px 3px 0;
    border-radius: 3px;
    font-size: 0.58rem;
    line-height: 1.25;
    overflow: hidden;
    min-height: 14px;
    white-space: nowrap;
    background: rgba(148, 163, 184, 0.22);
    color: var(--text-muted);
    border-left: 2px solid rgba(148, 163, 184, 0.45);
}

.month-more-count {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--text-muted);
    opacity: 0.7;
    min-height: 18px;
    flex-shrink: 0;
    width: 100%;
}

/* ── Уведомления (DaisyUI override) ─────────────── */

.alert {
    font-size: 0.8rem;
}

.alert-error {
    background-color: rgba(248,113,113,0.12) !important;
    border: 1px solid rgba(248,113,113,0.35) !important;
    color: var(--text-primary) !important;
}

.alert-warning {
    background-color: rgba(251,191,36,0.12) !important;
    border: 1px solid rgba(251,191,36,0.4) !important;
    color: var(--text-primary) !important;
}

.alert-error svg, .alert-warning svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    stroke: currentColor;
    opacity: 0.75;
}

/* ── Шит «Отпуска» ──────────────────────────────── */

/* Выбор «кому отпуск» — только у админа, в полосе выбора рядом с кнопками:
   он относится к тому, что сейчас сохранится. Раскрывается поверх календаря,
   как фильтр в шите. */
.absence-who-wrap {
    flex-shrink: 0;
}

.absence-select-who {
    display: flex;
    align-items: center;
    gap: 3px;
    max-width: 130px;
    min-height: 32px;
    padding: 0 8px 0 10px;
    border-radius: 8px;
    border: 1px solid rgba(148,163,184,0.4);
    background: transparent;
    color: var(--text-primary);
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
}

.absence-select-who span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.absence-select-who svg {
    width: 13px;
    height: 13px;
    flex-shrink: 0;
    color: var(--text-muted);
}

.absence-select-who.is-open {
    border-color: rgba(59,130,246,0.7);
}

.absence-who {
    position: absolute;
    top: calc(100% - 4px);
    left: 10px;
    box-sizing: border-box;
    z-index: 10;
    min-width: 200px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    border-radius: 12px;
    border: 1px solid rgba(148,163,184,0.28);
    background: var(--tg-theme-bg-color, #fff);
    box-shadow: 0 10px 30px rgba(0,0,0,0.25);
}

/* Без backdrop-filter: размытие пересчитывается на каждый кадр прокрутки
   списка, и на десктопе, где за шитом лежит вся сетка месяца, это заметно
   тормозило. Затемнения достаточно. */
.absence-sheet-overlay {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(0,0,0,0.55);
}

@media (min-width: 600px) {
    .absence-sheet-overlay {
        align-items: center;
    }
}

.absence-sheet {
    width: 100%;
    max-width: 460px;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    border-radius: 18px 18px 0 0;
    background: var(--tg-theme-bg-color, #fff);
    padding: 10px 14px 16px;
    box-shadow: 0 -8px 40px rgba(0,0,0,0.3);
}

[data-theme="dark"] .absence-sheet {
    background: #232326;
}



.absence-sheet-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 10px;
    flex-shrink: 0;
}

.absence-sheet-emoji { font-size: 1rem; }

.absence-sheet-title {
    flex: 1;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
}

.absence-sheet-close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.absence-sheet-close svg { width: 16px; height: 16px; }

.absence-sheet-error {
    font-size: 0.74rem;
    color: #ef4444;
    padding-bottom: 8px;
    line-height: 1.4;
}

.absence-cols {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.absence-col {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
    /* Прокручивается контейнер, а не колонки: без этого flex сжимал их ниже
       высоты содержимого, и карточки вылезали одна на другую. */
    flex-shrink: 0;
}

.absence-col-body {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.absence-grid {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.absence-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 10px;
    flex-shrink: 0;
}

/* На телефоне «Новый отпуск» живёт внизу широкой кнопкой — в панели он бы
   отобрал место у переключателя и фильтра. */
.absence-new-inline {
    display: none;
    align-items: center;
    gap: 6px;
    min-height: 34px;
    padding: 0 12px;
    border: none;
    border-radius: 9px;
    background: var(--tg-theme-button-color, #3b82f6);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
}

.absence-new-inline svg { width: 14px; height: 14px; }

.absence-month-label {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.3px;
    color: var(--text-muted);
    padding: 4px 0 6px;
}

.absence-month + .absence-month { margin-top: 4px; }

.absence-card-now {
    font-size: 0.72rem;
    font-weight: 700;
    color: #0f766e;
    padding-top: 4px;
}

[data-theme="dark"] .absence-card-now { color: #5eead4; }

.absence-card--past {
    opacity: 0.55;
}

.absence-past { padding-top: 4px; }



.absence-sheet-cap {
    margin-bottom: 2px;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--text-muted);
    padding-top: 2px;
}

.absence-scope {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

.absence-scope-btn,
.absence-filter-btn {
    min-height: 32px;
    padding: 0 12px;
    border-radius: 8px;
    border: 1px solid rgba(148,163,184,0.3);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.74rem;
    font-weight: 700;
    cursor: pointer;
}

.absence-filter-btn {
    margin-left: auto;
}

.absence-scope-btn.is-active,
.absence-filter-btn.is-active {
    border-color: rgba(45,212,191,0.6);
    background: rgba(45,212,191,0.16);
    color: var(--text-primary);
}

.absence-filter-wrap {
    position: relative;
}

/* Поверх содержимого, под кнопкой: список не должен раздвигать панель и
   сдвигать колонки вниз. */
/* Раскрывается вниз, а если под кнопкой не помещается — вверх (класс `is-up`,
   ставится в dropdownPlacement по месту на экране). Максимальную высоту тоже
   считает он: списку остаётся столько, сколько реально влезает. */
.absence-filter {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 40;
    width: 240px;
    /* Рамка и отступы входят в max-height: она считается от места на экране */
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    border-radius: 12px;
    border: 1px solid rgba(148,163,184,0.25);
    background: var(--tg-theme-bg-color, #fff);
    box-shadow: 0 10px 30px rgba(0,0,0,0.28);
}

.absence-filter.is-up,
.absence-who.is-up {
    top: auto;
    bottom: calc(100% + 6px);
}

[data-theme="dark"] .absence-filter {
    background: #2A2A2E;
}

.absence-filter-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
    /* min-height: 0 обязателен: без него flex-элемент не сжимается ниже своего
       содержимого, и прокрутка внутри списка не включается. */
    min-height: 0;
    overflow-y: auto;
}

.absence-filter-item {
    width: 100%;
    justify-content: flex-start;
}

.absence-filter-item {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 30px;
    padding: 0 9px;
    border-radius: 999px;
    border: 1px solid rgba(148,163,184,0.3);
    background: transparent;
    color: var(--text-primary);
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
}

.absence-filter-item.is-on {
    border-color: rgba(45,212,191,0.7);
    background: rgba(45,212,191,0.18);
}

.absence-filter-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

.absence-filter-actions {
    display: flex;
    gap: 8px;
    width: 100%;
}

.absence-card {
    border-radius: 12px;
    border: 1px solid rgba(148,163,184,0.2);
    background: rgba(148,163,184,0.07);
    padding: 10px 11px;
}

.absence-card + .absence-card { margin-top: 8px; }

.absence-card-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* В списках отпусков менеджер обозначается кружком: прямоугольники нужны были
   только в узкой строке дня, где рядом стоит десяток плашек. */
.absence-av {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.68rem;
    font-weight: 800;
    color: #14141B;
    flex-shrink: 0;
}

.absence-card-body { min-width: 0; }

/* Имя ужимается, метка — нет: иначе длинный юзернейм выдавливал статус за
   границу карточки, а «на одобрении» ломалось на две строки. */
.absence-card-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--text-primary);
}

/* Дата слева, длительность прижата вправо: в списке из нескольких отпусков
   так сравниваются и периоды, и их длина — глаз идёт по двум колонкам. */
.absence-card-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding-top: 6px;
}

.absence-card-range {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
}

.absence-card-days {
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.absence-card-meta {
    font-size: 0.72rem;
    color: var(--text-muted);
    padding-top: 2px;
}

.absence-card-actions {
    display: flex;
    gap: 8px;
    padding-top: 10px;
}

.absence-btn {
    flex: 1;
    min-height: 38px;
    padding: 0 12px;
    border-radius: 10px;
    border: 1px solid rgba(148,163,184,0.35);
    background: rgba(148,163,184,0.10);
    color: var(--text-primary);
    font-size: 0.76rem;
    font-weight: 700;
    cursor: pointer;
}

.absence-btn:disabled { opacity: 0.5; }

.absence-btn.is-active {
    border-color: rgba(45,212,191,0.6);
    background: rgba(45,212,191,0.18);
}

.absence-confirm {
    margin-top: 9px;
    padding: 9px 10px;
    border-radius: 10px;
    background: rgba(239,68,68,0.10);
    border: 1px solid rgba(239,68,68,0.3);
}

.absence-confirm-text {
    font-size: 0.74rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.35;
}

.absence-confirm .absence-card-actions {
    padding-top: 8px;
}

.absence-btn--approve {
    border-color: rgba(45,212,191,0.5);
    background: rgba(45,212,191,0.18);
}

.absence-btn--reject {
    border-color: rgba(239,68,68,0.45);
    background: rgba(239,68,68,0.12);
    color: #ef4444;
}

.absence-sheet-empty {
    font-size: 0.76rem;
    color: var(--text-muted);
    line-height: 1.45;
    padding: 6px 2px;
}

.absence-sheet-more {
    border: none;
    background: none;
    color: var(--tg-theme-link-color, #3b82f6);
    font-size: 0.74rem;
    font-weight: 600;
    padding: 6px 0;
    cursor: pointer;
}

.absence-sheet-new {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 46px;
    margin-top: 12px;
    border: none;
    border-radius: 12px;
    background: var(--tg-theme-button-color, #3b82f6);
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
}

.absence-sheet-new svg { width: 16px; height: 16px; }

/* ── Факт смены в модалке (опоздание/переработка) ── */

.modal-fact-box {
    display: flex;
    flex-direction: column;
    gap: 4px;
    border-radius: 8px;
    background: rgba(148,163,184,0.12);
    padding: 7px 10px;
    margin-bottom: 12px;
}

.modal-fact-item {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 0.75rem;
    line-height: 1.35;
}

/* Точка цветом штриховки на графике — чтобы строка и полоса читались как одно
   и то же событие. */
.modal-fact-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    align-self: center;
}

.modal-fact-dot--late {
    background: #f59e0b;
}

.modal-fact-dot--over {
    background: #38bdf8;
}

.modal-fact-label {
    font-weight: 700;
    color: var(--text-primary);
}

.modal-fact-detail {
    color: var(--text-muted);
}

/* ── Блок предупреждений в модалке ──────────────── */

.modal-warning-box {
    background: rgba(251,191,36,0.13);
    border: 1px solid rgba(251,191,36,0.38);
    border-radius: 8px;
    padding: 8px 10px;
    margin-top: 10px;
}

.modal-warning-item {
    font-size: 0.76rem;
    color: var(--text-primary);
    line-height: 1.45;
}

/* ── Блок предупреждений в модалке ──────────────── */

.modal-warning-box {
    background: rgba(251,191,36,0.13);
    border: 1px solid rgba(251,191,36,0.38);
    border-radius: 8px;
    padding: 8px 10px;
    margin-top: 10px;
}

.modal-warning-item {
    font-size: 0.76rem;
    color: var(--text-primary);
    line-height: 1.45;
}

/* Общий соседний селектор (~), а не смежный (+): Alpine вставляет элементы
   x-if/x-for СЛЕДОМ за своим <template>, так что между двумя предупреждениями
   всегда стоит служебный <template> и «+» не совпадал бы вообще. С «~»
   разделитель получает каждое предупреждение, кроме первого — а первое его не
   получает, даже если предшествующие ему предупреждения не выводятся. */
.modal-warning-item ~ .modal-warning-item {
    margin-top: 5px;
    padding-top: 5px;
    border-top: 1px solid rgba(251,191,36,0.25);
}

/* ── Детальный вид дня ──────────────────────────── */

.day-detail-overlay {
    position: fixed;
    inset: 0;
    z-index: 110;
}

.day-detail--mobile {
    background: var(--tg-theme-secondary-bg-color, #F0F1F5);
    display: flex;
    flex-direction: column;
    padding-top: var(--app-safe-top);
    padding-bottom: env(safe-area-inset-bottom, 8px);
}

.day-detail--desktop {
    background: rgba(0,0,0,0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.day-detail-box {
    position: relative;  /* якорь для щита отпуска поверх шкалы */
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.day-detail--mobile .day-detail-box {
    flex: 1;
    overflow: hidden;
    padding: 0 6px;
}

.day-detail--desktop .day-detail-box {
    background: var(--tg-theme-bg-color, #fff);
    border-radius: 16px;
    width: 100%;
    /* Широкий и невысокий: внутри горизонтальный таймлайн — сутки идут по
       ширине, а строк ровно столько, сколько менеджеров вышло в этот день.
       Прежние 520px × 95vh были под вертикальную шкалу. */
    max-width: 1120px;
    max-height: 92vh;
    box-shadow: 0 8px 40px rgba(0,0,0,0.28);
    padding: 12px 16px 16px;
}

[data-theme="dark"] .day-detail--desktop .day-detail-box {
    background: #2C2C2E;
    box-shadow: 0 8px 40px rgba(0,0,0,0.55);
}

/* Ни линии, ни заметного отступа снизу: под шапкой идёт строка отпусков, а
   каждый лишний пиксель здесь — это пиксель, которого не хватает шкале суток,
   чтобы поместиться целиком без прокрутки. */
.day-detail-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0 5px;
    flex-shrink: 0;
    margin-bottom: 0;
}

/* В дне на десктопе таблица уже в собственной рамке — вторая линия над ней
   лишняя. */
.day-detail--desktop .day-detail-header {
    border-bottom: none;
    margin-bottom: 8px;
}

.day-detail-title {
    flex: 1;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
    text-align: center;
}

.day-detail--desktop .day-detail-title {
    text-align: left;
}

/* ── Отпуска в дне ──────────────────────────────── */

/* Якорь для выпадающего списка: он рисуется поверх дня, а не раздвигает его. */
.day-absence-row {
    position: relative;
    z-index: 20;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    /* Отступ сверху — под значок ожидания: он выступает над кружком, и без
       запаса его срезала бы граница строки. */
    padding: 8px 2px 5px;
}

.day-absence-chip {
    display: flex;
    align-items: center;
    gap: 7px;
    width: 100%;
    min-height: 34px;
    padding: 0 10px 0 9px;
    border-radius: 999px;
    border: 1px solid rgba(148,163,184,0.28);
    background: rgba(148,163,184,0.08);
    color: var(--text-primary);
    cursor: pointer;
}

.day-absence-emoji {
    font-size: 0.85rem;
    line-height: 1;
    flex-shrink: 0;
}

.day-absence-label {
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--text-muted);
}

.day-absence-avatars {
    display: flex;
    align-items: center;
    padding-left: 3px;
}

/* Плашки менеджеров. Нахлёст — чтобы читались одной группой; обводка цветом
   фона отделяет соседей. На телефоне это кружки с буквой (места на имя нет),
   на широком экране — прямоугольники с юзернеймом. */
.day-absence-av {
    min-width: 21px;
    width: 21px;
    height: 21px;
    padding: 0;
    box-sizing: border-box;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-size: 0.62rem;
    font-weight: 800;
    color: #14141B;
    border: 1.5px solid var(--tg-theme-bg-color, #fff);
    flex-shrink: 0;
    overflow: hidden;
}

.day-absence-av-name {
    display: none;
}

.day-absence-av + .day-absence-av {
    margin-left: -7px;
}

@media (min-width: 600px) {
    /* Десять плашек в строке: ниже минимума имя не читается, выше максимума
       они вытесняют друг друга. Буква не нужна — видно имя целиком. */
    .day-absence-av {
        min-width: 64px;
        width: auto;
        max-width: 110px;
        height: 23px;
        padding: 0 8px 0 6px;
        border-radius: 8px;
        font-size: 0.66rem;
    }

    .day-absence-av-letter {
        display: none;
    }

    .day-absence-av-name {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-weight: 700;
    }

    /* Нахлёст побольше: плашки шире кружков, и группа иначе растягивается */
    .day-absence-av + .day-absence-av {
        margin-left: -8px;
    }
}

.day-absence-av--rest {
    background: rgba(148,163,184,0.45) !important;
    color: var(--text-primary);
}

/* Крестик поверх списка в углу: своей строки-заголовка у списка нет — её роль
   играет чип над ним. */
.day-absence-close {
    position: absolute;
    top: 4px;
    right: 6px;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.day-absence-close svg {
    width: 15px;
    height: 15px;
}

.day-absence-chevron {
    width: 14px;
    height: 14px;
    margin-left: auto;
    color: var(--text-muted);
    flex-shrink: 0;
}

/* Щит на всю зону дня. inset считается от .day-detail-box, поэтому шапка и
   строка отпусков остаются доступны — закрывается только шкала со сменами. */
/* Закрываем только шкалу: шапка с датой и стрелками, строка отпусков и кнопка
   «ОК» остаются рабочими — иначе из такого дня нельзя выйти привычным жестом. */
.day-absence-shield {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 52px;
    top: 92px;
    z-index: 15;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    background: rgba(28,28,30,0.55);
    backdrop-filter: blur(2px);
    border-radius: 12px;
}

.day-absence-shield-card {
    text-align: center;
    max-width: 280px;
    border-radius: 14px;
    background: var(--tg-theme-bg-color, #fff);
    border: 1px solid rgba(45,212,191,0.5);
    padding: 16px 18px;
    box-shadow: 0 8px 28px rgba(0,0,0,0.25);
}

[data-theme="dark"] .day-absence-shield-card {
    background: #2A2A2E;
}

.day-absence-shield-emoji {
    font-size: 1.5rem;
    line-height: 1;
}

.day-absence-shield-title {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--text-primary);
    padding-top: 8px;
}

.day-absence-shield-range {
    font-size: 0.78rem;
    color: var(--text-muted);
    padding-top: 4px;
}

.day-absence-shield-btn {
    margin-top: 12px;
    min-height: 38px;
    padding: 0 16px;
    border-radius: 10px;
    border: 1px solid rgba(148,163,184,0.35);
    background: rgba(148,163,184,0.12);
    color: var(--text-primary);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
}

.day-absence-shield-hint {
    font-size: 0.72rem;
    color: var(--text-muted);
    padding-top: 8px;
    line-height: 1.4;
}

/* На десктопе кнопки «ОК» внизу нет — щит доходит до низа карточки. */
@media (min-width: 600px) {
    .day-absence-shield {
        bottom: 0;
        top: 104px;
    }
}

/* Поверх дня: список не должен сдвигать шкалу — она и так еле помещается. */
.day-absence-sheet {
    position: absolute;
    top: calc(100% - 2px);
    left: 0;
    right: 0;
    z-index: 30;
    border-radius: 12px;
    border: 1px solid rgba(148,163,184,0.22);
    background: var(--tg-theme-secondary-bg-color, #F0F1F5);
    box-shadow: 0 8px 24px rgba(0,0,0,0.28);
    padding: 6px 10px 8px;
    max-height: 60vh;
    overflow-y: auto;
}

[data-theme="dark"] .day-absence-sheet {
    background: #2A2A2E;
}

.day-absence-chip.is-open .day-absence-chevron {
    transform: rotate(90deg);
}

.day-absence-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 5px 0;
}

.day-absence-item-body {
    min-width: 0;
}

.day-absence-item-name {
    font-size: 0.78rem;
    font-weight: 700;
}

.day-absence-item-range {
    font-size: 0.7rem;
    color: var(--text-muted);
    padding-top: 1px;
}

/* Заявка отличается пунктирным кружком и подписью, а не отдельной секцией:
   в списке на два-три имени секции выглядели бы тяжелее самих данных. */
/* Заявка помечена значком ожидания на обоих экранах: приглушённая плашка на
   телефоне читалась как бледный кружок и о статусе ничего не говорила. */
.day-absence-av.is-pending {
    position: relative;
    z-index: 2;
    overflow: visible;
}

.day-absence-av.is-pending::after {
    content: "⏳";
    position: absolute;
    top: -6px;
    right: -4px;
    font-size: 10px;
    line-height: 1;
    z-index: 3;
    text-shadow: 0 0 3px var(--tg-theme-bg-color, #fff);
}

@media (min-width: 600px) {
    /* Плашка шире кружка — значок садится ближе к её углу */
    .day-absence-av.is-pending::after {
        top: -2px;
        right: -3px;
    }
}

.day-detail-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    -webkit-overflow-scrolling: touch;
}

/* Таймлайну нужна горизонтальная прокрутка: если окно уже min-width суток,
   часы не сжимаются до нечитаемого, а уезжают под прокрутку. */
.day-detail--desktop .day-detail-scroll {
    overflow-x: auto;
}

.day-detail-ok-wrap {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    padding: 4px 0 2px;
}

.day-detail-ok-btn {
    min-width: 132px;
    padding: 5px 26px;
    border: none;
    border-radius: 999px;
    background: var(--tg-theme-button-color, var(--tg-theme-link-color, #3b82f6));
    color: var(--tg-theme-button-text-color, #fff);
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.12s;
}

.day-detail-ok-btn:active {
    filter: brightness(0.9);
}

/* ── День: полосы стандартных смен, шкала часов, "сейчас" ── */

.day-body--detail {
    padding-top: 8px;
    /* Ширина полосы кнопок «+» (см. .day-slot-rail) — от неё же считается
       левая граница области смен. */
    --slot-rail-width: 22px;
}

/* Дорожки смен прокручиваются по горизонтали независимо от шкалы часов: при
   четырёх и более одновременных сменах плитки перестают влезать по ширине, и
   вместо того чтобы сжимать их до нечитаемых, даём им минимальную ширину и
   уводим лишнее под прокрутку. Шкала при этом остаётся на месте. */
.day-lanes-scroll {
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(var(--hour-gutter-width) + var(--slot-rail-width));
    right: 0;
    overflow-x: auto;
    overflow-y: hidden;
}

.day-lanes {
    position: relative;
    height: 100%;
    /* Пока дорожки помещаются — ровно ширина экрана, как раньше. Не
       помещаются — контейнер расширяется, и появляется прокрутка. */
    min-width: 100%;
    width: max(100%, calc(var(--lanes-count, 1) * var(--lane-min, 112px)));
}

/* Подсказка «справа есть ещё» — отдельным слоем поверх неподвижного тела дня,
   а не внутри прокрутки: там она уезжала бы вместе с содержимым. */
.day-lanes-hint {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 26px;
    background: linear-gradient(to left, rgba(100, 116, 139, 0.25), rgba(100, 116, 139, 0));
    pointer-events: none;
    z-index: 5;
}

.day-body--detail .segment-card {
    left: 9px;
    right: 11px;
}

/* Смена на дорожке: номер дорожки и их количество приходят из dayShiftStyle
   (--lane-i / --lane-n), а ширину и смещение считает CSS — только ему известна
   реальная ширина полосы дня, поэтому перекрытие соседних плиток можно задать
   в пикселях (ровно внутренний отступ карточки), а не долей ширины. Крайние
   плитки при этом точно упираются в границы полосы. */
.day-body--detail .shift-lane {
    --day-track: calc(100% - 20px);
    --lane-overlap: 6px;
    --lane-width: calc(var(--day-track) / var(--lane-n) + var(--lane-overlap));
    left: calc(
        9px
        + (var(--day-track) - var(--lane-width)) * var(--lane-i) / max(var(--lane-n) - 1, 1)
    );
    width: var(--lane-width);
    right: auto;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.16);
}

.day-bands {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.day-band {
    position: absolute;
    left: 0;
    right: 0;
}

.day-band-night   { background: rgba(99,102,241,0.09); }
.day-band-day     { background: rgba(234,88,12,0.07); }
.day-band-evening { background: rgba(139,92,246,0.09); }

[data-theme="dark"] .day-band-night   { background: rgba(99,102,241,0.17); }
[data-theme="dark"] .day-band-day     { background: rgba(234,88,12,0.15); }
[data-theme="dark"] .day-band-evening { background: rgba(139,92,246,0.17); }

.hour-gutter {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--hour-gutter-width);
    height: 100%;
    z-index: 1;
    pointer-events: none;
}

/* Линии часов живут внутри .day-lanes и тянутся на всю его ширину — вместе с
   дорожками, а не только по видимой части. */
.hour-lines {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 100%;
    z-index: 1;
    pointer-events: none;
}

.hour-row {
    position: absolute;
    left: 0;
    right: 0;
    height: 0;
    border-top: 1px solid rgba(148,163,184,0.28);
}

[data-theme="dark"] .hour-row {
    border-top-color: rgba(255,255,255,0.14);
}

.hour-row-label {
    position: absolute;
    left: 4px;
    top: -7px;
    width: calc(var(--hour-gutter-width) - 8px);
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--text-muted);
    line-height: 1;
}

.current-time-line {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    background: #ef4444;
    /* Выше плиток на дорожках (их z-index растёт с номером дорожки, см.
       dayShiftStyle) — линия текущего времени должна оставаться видна. */
    z-index: 20;
    pointer-events: none;
}

/* Метка времени на шкале часов (мобильный вид). Линия рисуется отдельно, в
   области смен: там ей место по смыслу, а подпись на сменах перекрывала бы их
   собственные надписи. */
.current-time-badge {
    position: absolute;
    left: 2px;
    right: 2px;
    transform: translateY(-50%);
    text-align: center;
    padding: 1px 2px;
    border-radius: 4px;
    background: #ef4444;
    color: #fff;
    font-size: 0.6rem;
    font-weight: 700;
    line-height: 1.3;
    z-index: 3;
}

/* Подпись у вертикальной линии времени в таймлайне (десктоп) */
.timeline-now-badge {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, -100%);
    padding: 1px 5px;
    border-radius: 4px;
    background: #ef4444;
    color: #fff;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1.4;
    white-space: nowrap;
}

.current-time-label {
    position: absolute;
    left: 4px;
    top: -8px;
    padding: 1px 4px;
    border-radius: 4px;
    background: #ef4444;
    color: #fff;
    font-size: 0.6rem;
    font-weight: 700;
    line-height: 1.3;
}

/* ── Кнопки модалки ──────────────────────────────── */

.modal-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 16px;
}

.modal-action-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.modal-action-row + .modal-action-row {
    padding-top: 6px;
    border-top: 1px solid rgba(148,163,184,0.15);
}

[data-theme="dark"] .modal-action-row + .modal-action-row {
    border-top-color: rgba(255,255,255,0.08);
}

/* ── Панель отдачи смены ────────────────────────── */

.release-section {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(0,0,0,0.04);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

[data-theme="dark"] .release-section {
    background: rgba(255,255,255,0.06);
}

.release-divider {
    text-align: center;
    font-size: 0.7rem;
    opacity: 0.5;
    letter-spacing: 0.02em;
}

/* ── Расхождение плана и факта ───────────────────── */

/* Опоздание и переработка рисуются штриховкой поверх шкалы: план остаётся как
   есть (он не перезаписывается фактом), а отклонение видно глазом. Клики
   насквозь — под штриховкой лежит сама смена. */
/* Хвост переработки — отдельный элемент рядом с плашкой. Селекторы из двух
   классов намеренно: у .segment-card и .timeline-bar тот же вес, и при одном
   классе z-index проигрывал бы им по порядку в файле. Скругление — только на
   внешнем углу: со стороны смены штриховка стыкуется с ней встык. */
.segment-card.shift-hatch,
.timeline-bar.timeline-hatch {
    pointer-events: none;
    z-index: 14;
    border-radius: 0 0 var(--radius-seg) var(--radius-seg);
}

.timeline-bar.timeline-hatch {
    border-radius: 0 6px 6px 0;
    /* Подсказка по наведению нужна и здесь, поэтому события не отключаем:
       под хвостом переработки в строке менеджера ничего нет. */
    pointer-events: auto;
}

/* У смены, которая продолжается штриховкой переработки, конец не скругляем —
   скругление даёт сам хвост, иначе на стыке получается «пузырь». */
.timeline-shift.bar-continues {
    border-radius: 6px 0 0 6px;
}

.shift-block.bar-continues {
    border-radius: var(--radius-seg) var(--radius-seg) 0 0;
}

/* Опоздание — внутри самой плашки, под её подписью: подпись лежит выше по
   z-index, поэтому штриховка её не перекрывает. Ориентация зависит от вида:
   в таймлайне время идёт по горизонтали, в мобильном дне — по вертикали. */
.shift-late-fill {
    position: absolute;
    z-index: 0;
    top: 0;
    left: 0;
}

.timeline-shift .shift-late-fill {
    bottom: 0;
    width: calc(var(--late-frac, 0) * 100%);
}

.shift-block .shift-late-fill {
    right: 0;
    height: calc(var(--late-frac, 0) * 100%);
}

.timeline-shift > span,
.shift-block > .shift-name,
.shift-block > .shift-time {
    position: relative;
    z-index: 1;
}

.hatch-late {
    background-image: repeating-linear-gradient(
        45deg, rgba(239, 68, 68, 0.55) 0 5px, rgba(239, 68, 68, 0.12) 5px 10px
    );
    border: 1px dashed rgba(239, 68, 68, 0.85);
}

.hatch-over {
    background-image: repeating-linear-gradient(
        45deg, rgba(245, 158, 11, 0.55) 0 5px, rgba(245, 158, 11, 0.12) 5px 10px
    );
    border: 1px dashed rgba(245, 158, 11, 0.9);
}

/* ── Горизонтальный таймлайн дня (десктоп) ───────── */

.day-timeline {
    /* Ширина колонки с именами и минимальная ширина суток: если диалог уже,
       включается горизонтальная прокрутка родителя (.day-detail-scroll), а не
       сжимаются часы до нечитаемого. */
    --tl-label: 156px;
    --tl-sidebar-bg: rgba(148, 163, 184, 0.07);
    min-width: 780px;
    display: flex;
    flex-direction: column;
    /* Таблица в рамке со скруглением по внешним углам; overflow скругляет и
       содержимое, поэтому внутренним элементам радиусы не нужны. */
    border: 1px solid var(--border-soft, rgba(148, 163, 184, 0.28));
    border-radius: 8px;
    overflow: hidden;
}

.timeline-row {
    display: flex;
    align-items: stretch;
    min-height: 44px;
}

/* Разделители — под каждой строкой, включая шапку: таблица ресурсов, как в
   макете. У последней строки линию снимаем, её роль играет рамка таблицы. */
.timeline-row {
    border-bottom: 1px solid var(--border-soft, rgba(148, 163, 184, 0.22));
}

/* Линию под последней строкой не снимаем: ниже неё почти всегда остаётся
   пустое место (тело не короче 12 строк), и без линии таблица выглядела бы
   оборванной. */

/* Колонка имён — своя подложка и правая граница, как сайдбар в макете.
   Ниже последней строки её продолжает фон .timeline-body. */
.timeline-row-label {
    background: var(--tl-sidebar-bg);
    border-right: 1px solid var(--border-soft, rgba(148, 163, 184, 0.22));
}

[data-theme="dark"] .day-timeline {
    --tl-sidebar-bg: rgba(255, 255, 255, 0.04);
}

.timeline-head-label {
    font-size: 0.82rem;
    color: var(--text-muted);
}

.timeline-row-label {
    width: var(--tl-label);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px 0 14px;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    white-space: nowrap;
}

/* Обрезать нужно сам текст, а не flex-контейнер: иначе длинный ник просто
   выезжает за колонку вместо многоточия. */
.timeline-row-label > span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.timeline-label-muted {
    font-weight: 500;
    color: var(--text-muted);
}

.timeline-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.timeline-track {
    position: relative;
    flex: 1;
    min-width: 0;
}

.timeline-head {
    min-height: 44px;
}

/* Стандартные 8-часовые блоки на шкале времени — кликабельные: одно нажатие
   ставит смену на весь блок. Подсветка та же, что у полос суток в теле дня,
   чтобы шкала и фон читались как одно целое. */
/* Блок суток идёт на всю высоту шапки, включая полосу часов: заливка не
   разрывается, а цифры читаются за счёт своей подложки поверх неё. Подпись
   центрируется в части над часами — отступы сверху и снизу одинаковые. */
.timeline-slot-zone {
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-bottom: 18px;
    border: none;
    border-radius: 0;
    font: inherit;
    /* Наравне с заголовком колонки менеджеров — это тоже заголовок */
    font-size: 0.9rem;
    color: var(--text-muted);
    cursor: pointer;
}

.timeline-slot-zone:disabled {
    cursor: default;
}

/* Ховер общий у заголовка блока и его заливки под строками: наводишь на
   «Ночь» — подсвечивается весь ночной блок сверху донизу. Подсветка — не
   filter, а сплошная накладка: заливки блоков полупрозрачные (7–9%), и
   brightness на них почти не виден. */
.timeline-slot-zone.band-hover,
.timeline-band.band-hover {
    box-shadow: inset 0 0 0 9999px rgba(100, 116, 139, 0.18);
}

/* Подпись блока на ховере становится контрастнее — сигнал, что по нему кликают */
.timeline-slot-zone.band-hover .slot-zone-label {
    color: var(--text-primary);
    font-weight: 600;
}

[data-theme="dark"] .timeline-slot-zone.band-hover,
[data-theme="dark"] .timeline-band.band-hover {
    box-shadow: inset 0 0 0 9999px rgba(255, 255, 255, 0.09);
}

/* Подложка под цифрами: полупрозрачная с блюром — заливка блока просвечивает,
   но цифры остаются читаемыми. */
.timeline-hours-strip {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 18px;
    background: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    pointer-events: none;
}

[data-theme="dark"] .timeline-hours-strip {
    background: rgba(28, 28, 30, 0.72);
}

/* Полоса кнопок «+» между шкалой часов и сменами: по кнопке на каждый
   стандартный 8-часовой блок. На телефоне нет ховера, поэтому кликабельность
   нужно показывать явно, а внутри самой шкалы «+» спорил бы с подписями. */
.day-slot-rail {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--hour-gutter-width);
    width: var(--slot-rail-width);
    z-index: 2;
}

.slot-rail-btn {
    position: absolute;
    left: 1px;
    right: 1px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 6px;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
}

.slot-rail-btn:active {
    filter: brightness(0.92);
}

.slot-rail-btn:disabled {
    cursor: default;
    opacity: 0.45;
}

/* Навигация по дням в шапке дня. Класс намеренно не `.day-nav` — он занят
   навигацией недельного вида, и её `margin-bottom` сбивал выравнивание кнопок
   относительно даты. */
.day-detail-nav {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.day-nav-btn {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 8px;
    border: 1px solid var(--border-soft, rgba(148, 163, 184, 0.3));
    background: transparent;
    color: var(--text-primary);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s;
}

.day-nav-btn svg {
    width: 16px;
    height: 16px;
    display: block;
}

.day-nav-btn:hover {
    background: rgba(148, 163, 184, 0.18);
    border-color: rgba(148, 163, 184, 0.5);
}

/* Крестик закрытия — тот же контрол, только без рамки, чтобы не спорил с
   навигацией по дням */
.day-close-btn {
    border-color: transparent;
    color: var(--text-muted);
    margin-left: 4px;
}

.day-nav-btn:active {
    background: rgba(148, 163, 184, 0.3);
}

/* Своя подсказка вместо системного title */
.app-tooltip {
    position: fixed;
    z-index: 400;
    transform: translate(-50%, -100%) translateY(-8px);
    max-width: 260px;
    padding: 5px 9px;
    border-radius: 8px;
    background: rgba(37, 39, 45, 0.95);
    color: #F9FAFB;
    font-size: 0.72rem;
    line-height: 1.3;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
    pointer-events: none;
    /* Длинные подсказки (про опоздание и переработку) переносим по словам —
       в одну строку они не помещаются и обрезались. */
    white-space: normal;
    text-align: center;
}

[data-theme="dark"] .app-tooltip {
    background: rgba(230, 232, 238, 0.96);
    color: #1F2937;
}

.timeline-hour {
    position: absolute;
    bottom: 0;
    /* По высоте подложки под часами — цифры стоят ровно в её середине */
    line-height: 18px;
    transform: translateX(-50%);
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
    /* Подписи не должны перехватывать клик по блоку под ними */
    pointer-events: none;
}

/* Крайние подписи прижимаем внутрь: иначе половина «00:00» уезжает на колонку
   имён, а «24:00» — за правый край и создаёт лишнюю прокрутку. Плюс небольшой
   отступ от краёв, чтобы цифры не липли к рамке таблицы. */
.timeline-hour--first { transform: none; margin-left: 5px; }
.timeline-hour--last  { transform: translateX(-100%); margin-left: -5px; }

/* Полосы суток и часовая сетка — общий фон под всеми строками, поэтому живут
   отдельным слоем, сдвинутым на ширину колонки имён. */
.timeline-body {
    position: relative;
    /* Колонка имён должна доходить до низа таблицы, а не обрываться после
       последней строки. Рисуем её фоном самого тела вместе с вертикальной
       границей — так она гарантированно под всем содержимым. */
    background: linear-gradient(
        to right,
        var(--tl-sidebar-bg) 0 calc(var(--tl-label) - 1px),
        var(--border-soft, rgba(148, 163, 184, 0.22)) calc(var(--tl-label) - 1px) var(--tl-label),
        transparent var(--tl-label)
    );
    /* Не меньше двенадцати строк: диалог не должен схлопываться до пары
       полосок, когда в дне мало смен. */
    min-height: 528px;
}

.timeline-overlay {
    position: absolute;
    left: var(--tl-label);
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 0;
    pointer-events: none;
}

.timeline-band {
    position: absolute;
    top: 0;
    bottom: 0;
}

.timeline-gridline {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--border-soft, rgba(148, 163, 184, 0.28));
}

.timeline-now {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: #ef4444;
    z-index: 6;
    pointer-events: none;
    /* Проценты здесь считались бы от всей ширины тела, вместе с колонкой имён,
       и линия уезжала бы вправо тем сильнее, чем позже время. Считаем от самой
       полосы времени: она начинается после колонки. */
    left: calc(var(--tl-label) + (100% - var(--tl-label)) * var(--now-x, 0));
}

.timeline-bar {
    position: absolute;
    top: 5px;
    bottom: 5px;
    z-index: 2;
    border-radius: 6px;
    /* Отступ минимальный: на двухчасовой смене каждый пиксель решает, влезет
       подпись времени или обрежется. */
    padding: 0 4px;
    display: flex;
    align-items: center;
    font-size: 0.8rem;
    overflow: hidden;
    white-space: nowrap;
    cursor: pointer;
    transition: filter 0.12s;
}

.timeline-bar:hover {
    filter: brightness(1.04);
}

.timeline-shift {
    color: var(--shift-text, var(--text-primary));
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.timeline-shift.shift-selected {
    outline: 2px solid var(--tg-theme-link-color, #3b82f6);
    outline-offset: 1px;
}

.timeline-free {
    background: rgba(148, 163, 184, 0.18);
    color: var(--text-muted);
}

.timeline-free:hover {
    background: rgba(148, 163, 184, 0.28);
}

.timeline-hole {
    background: rgba(244, 63, 94, 0.5);
    border: 2px dashed rgba(244, 63, 94, 0.9);
    color: var(--text-primary);
    font-weight: 600;
}

/* ── SOS: непокрытый интервал и панель подтверждения ── */

/* Дыра SOS — не занятое время, а «дырка» в графике: пунктирная рамка отличает
   её от обычной смены, залитой цветом менеджера. */
.shift-block.sos-hole {
    border: 2px dashed rgba(244, 63, 94, 0.9);
    box-shadow: none;
}

.month-shift-pill.sos-pill {
    border-left-style: dashed;
    font-style: italic;
}

.sos-section {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(244, 63, 94, 0.08);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

[data-theme="dark"] .sos-section {
    background: rgba(244, 63, 94, 0.16);
}

.sos-note {
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--text-muted);
}

/* ── Toast-уведомление ──────────────────────────── */

.toast-popup {
    position: fixed;
    bottom: 72px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(55,65,81,0.9);
    color: #f9fafb;
    padding: 8px 18px;
    border-radius: 20px;
    font-size: 0.82rem;
    /* Без nowrap и с ограничением по ширине: длинная фраза раньше уезжала за
       края экрана, и на телефоне её было не прочитать. */
    max-width: min(320px, calc(100vw - 32px));
    text-align: center;
    line-height: 1.35;
    z-index: 200;
    pointer-events: none;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}

[data-theme="dark"] .toast-popup {
    background: rgba(75,85,99,0.92);
}

/* ── Модалка подтверждения блокировки ───────────── */

.lock-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 120;
    background: rgba(0,0,0,0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.lock-confirm-box {
    background: var(--tg-theme-bg-color, #fff);
    border-radius: 14px;
    padding: 20px;
    max-width: 340px;
    width: 100%;
    box-shadow: 0 8px 32px rgba(0,0,0,0.25);
}

[data-theme="dark"] .lock-confirm-box {
    background: #2C2C2E;
}

.lock-confirm-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 12px;
}

.lock-confirm-body {
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--text-primary);
    white-space: pre-line;
    max-height: 180px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: rgba(0,0,0,0.04);
    border-radius: 8px;
    padding: 8px 10px;
    margin-bottom: 12px;
}

[data-theme="dark"] .lock-confirm-body {
    background: rgba(255,255,255,0.06);
}

.lock-confirm-footer {
    font-size: 0.84rem;
    line-height: 1.45;
    color: var(--text-primary);
    opacity: 0.65;
    margin-bottom: 16px;
}

.lock-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ── Кнопка «Сегодня» ────────────────────────────── */

.today-btn {
    position: fixed;
    bottom: 24px;
    right: 16px;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--tg-theme-link-color, #3b82f6);
    color: #fff;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(0,0,0,0.22);
    /* Ниже шита отпусков (120) и модалок: плавающая кнопка не должна висеть
       поверх открытого окна. */
    z-index: 100;
    transition: transform 0.15s, opacity 0.15s;
}

.today-btn:hover {
    transform: scale(1.08);
}

.today-btn:active {
    transform: scale(0.92);
    opacity: 0.85;
}

/* ── Десктоп ─────────────────────────────────────── */

@media (min-width: 600px) {
    .day-name           { font-size: 0.9rem; }
    .day-date           { font-size: 0.78rem; }
    .shift-name         { font-size: 1.2rem; }
    .seg-time,
    .shift-time         { font-size: 1.0rem; }
    .week-label         { font-size: 1rem; }
    .month-label        { font-size: 1.05rem; }
    .month-weekday-header { font-size: 0.76rem; }
    .month-day-num      { font-size: 0.9rem; width: 28px; height: 28px; }
    .month-week-row     { height: 140px; }
    .month-shift-pill   { font-size: 0.65rem; }
    .month-free-pill    { font-size: 0.65rem; }
    .month-shift-emoji  { display: inline; }

    /* На десктопе: однострочные пиллы, вернуть нижний padding */
    .month-shift-pill   { padding: 2px 3px; min-height: 16px; }
    /* Группа на десктопе может быть в две строки (двое) — даём им место */
    .month-group-pill   { min-height: 30px; }
    .month-free-pill    { padding: 2px 3px; min-height: 16px; }
    /* Десктоп: вернуть стандартные отступы ячейки */
    .month-cell         { padding: 4px 2px 3px; gap: 2px; }

    /* В месяце на десктопе плашка однострочная — это касается и группы */
    .month-group-compact {
        flex-direction: row;
        align-items: center;
        gap: 4px;
    }
    .month-group-compact .month-shift-time {
        margin-left: auto;
        flex-shrink: 0;
    }

    /* В месяце на десктопе: имя и время в одну строку */
    .month-shift-info {
        flex-direction: row;
        align-items: center;
        gap: 4px;
    }
    .month-shift-name {
        flex: 1;
    }
    .month-shift-time {
        margin-left: auto;
        flex-shrink: 0;
        font-size: 0.88em;
        opacity: 0.7;
        white-space: nowrap;
    }
}

/* ── Мобильная тёмная тема: карточки не чёрные ───── */

@media (max-width: 599px) {
    [data-theme="dark"] .month-view-container,
    [data-theme="dark"] .day-column {
        background: #1C1C1E;
    }

    .month-shift-pill { border-left: none; }
    .month-free-pill  { border-left: none; }

    .month-week-row { height: 150px; }

    .seg-time,
    .shift-time {
        font-size: 1rem;
        margin-top: 8px;
    }

    /* В детальном виде дня на мобильном — компактнее */
    .day-detail--mobile .segment-card {
        padding: 2px 4px;
        gap: 0;
    }
    /* Шкала часов на телефоне уже, а освободившееся отдаём кнопке «+»:
       суммарная левая граница смен от этого не меняется. */
    .day-detail--mobile .day-body--detail {
        --hour-gutter-width: 34px;
        --slot-rail-width: 30px;
    }

    .day-detail--mobile .hour-row-label {
        left: 2px;
        width: calc(var(--hour-gutter-width) - 4px);
    }

    /* Перекрытие дорожек на мобильном больше, чем на десктопе: экран узкий,
       и лишние пиксели ширины важнее строгой раздельности плиток. Значение —
       прибавка к ширине; видимое перекрытие соседей выходит примерно в
       полтора раза больше при трёх дорожках. */
    .day-detail--mobile .shift-lane {
        --lane-overlap: 10px;
    }
    .day-detail--mobile .seg-time {
        font-size: 0.7rem;
        margin-top: 0;
        line-height: 1;
    }

    /* Текст внутри блоков смен на мобильном — крупнее и просторнее */
    .day-detail--mobile .shift-block {
        gap: 3px;
    }
    .day-detail--mobile .shift-name {
        font-size: 0.92rem;
        line-height: 1.35;
    }
    .day-detail--mobile .shift-time {
        font-size: 0.82rem;
        margin-top: 0;
        line-height: 1.3;
    }
}

/* Десктопные переопределения идут ПОСЛЕ мобильных: при равной
   специфичности выигрывает то правило, что ниже в файле. */
@media (min-width: 600px) {
    /* На широком экране шит становится окном в две колонки: слева заявки,
       справа общий список. Высота фиксирована, прокрутка — внутри колонок,
       поэтому шапка с кнопками всегда на месте. */
    .absence-sheet {
        max-width: 980px;
        height: 82vh;
        border-radius: 18px;
        padding: 14px 18px 18px;
    }

    .absence-cols {
        display: grid;
        grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
        gap: 18px;
        min-height: 0;
    }

    .absence-cols.is-single {
        grid-template-columns: minmax(0, 1fr);
    }

    .absence-col {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    .absence-col + .absence-col {
        border-left: 1px solid rgba(148,163,184,0.18);
        padding-left: 18px;
    }

    .absence-col-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        padding-right: 4px;
    }

    /* Общий список — в две подколонки: карточки низкие, и одна колонка на
       широком окне тратила бы половину ширины впустую. */
    .absence-col--list .absence-grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
        align-items: start;
    }

    /* Внутри месяца — настоящий грид, а не inline-block: только так соседние
       карточки выравниваются по верхней границе при разной высоте. */
    .absence-col--list .absence-card + .absence-card {
        margin-top: 0;
    }

    .absence-new-inline {
        display: flex;
    }

    .absence-sheet-new {
        display: none;
    }
}


/* ── Шапка месяца на ПК ─────────────────────────── */

/* «🏖 Отпуск» и «🔓 Открыт» на широком экране крупнее: рядом с ними в шите
   стоит «＋ Новый отпуск» высотой 34 px, и кнопки шапки на его фоне выглядели
   мелкими. На телефоне размер прежний — там шапка и так тесная. */
@media (min-width: 600px) {
    .month-absence-btn,
    .month-lock-btn {
        min-height: 34px;
        padding: 0 12px;
        gap: 6px;
        font-size: 0.95rem;
    }

    .month-absence-btn-label,
    .month-lock-label {
        font-size: 0.78rem;
    }
}


