/* ===== STYLE.CSS — Life Pay HR Portal — Readme Light =====
   Структурные стили: layout, grid, flex, позиции, размеры, адаптив.
   Оформление (цвета, шрифты, тени, градиенты) — в theme.css
   ========================================================== */
/* ===== RESET ===== */
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
  font-family: 'Golos Text', 'Inter', -apple-system, sans-serif;
  background: #F0F4F8;
  color: #0F172A;
}

/* ПОЛЯ И КНОПКИ НАСЛЕДУЮТ ШРИФТ ПОРТАЛА.
   Браузер их шрифту страницы НЕ учит: он выдаёт им свой системный — на маке
   это Arial 13.33px. В портале с этим боролись поштучно: `font-family:inherit`
   выписан руками в 26 местах, и там, где о нём забыли, кнопка оказывалась
   ПРОСТО ДРУГИМ ШРИФТОМ. Замер 27.08.2026 по 38 окнам: Arial нашёлся в окнах
   «Кто в отпуске» (.dept-mo-x) и «Приказы 1С» (.reg-gcv, .gb) — и это
   единственные два окна, где размер выпадал из шкалы.
   Одно правило вместо двадцати шести и вместо будущих таких же.
   line-height НАРОЧНО не наследуем: у полей от него зависит высота. */
button, input, select, textarea, optgroup {
  font-family: inherit;
  font-size: inherit;
}

/* ===== APP LAYOUT (sidebar + main) ===== */
.app-layout {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* ── SIDEBAR ── */
.sidebar {
  width: 220px;
  min-width: 220px;
  height: 100vh;
  background: #0F172A;
  display: flex;
  flex-direction: column;
  /* Прокрутки у самой колонки БОЛЬШЕ НЕТ (25.08.2026). Она уносила за нижний
     край не только лишние пункты, но и метку сборки, а логотип с юрлицами
     уезжал вверх. Прокручивается теперь только список разделов — .nav-scroll. */
  overflow: hidden;
  flex-shrink: 0;
  /* Без анимации ширины: при плавном изменении ширины вся рабочая область (и особенно
     диаграмма отпусков на flex/процентах) переразмерялась каждый кадр и визуально
     «ехала». Мгновенное переключение — чисто и без переезда оформления с месяцем. */
}

/* ── Свёрнутая боковая панель (кнопка ☰ в топбаре) ──
   Узкая полоса только с иконками — расширяет рабочее пространство .app-main.
   Состояние запоминается в localStorage (см. app-ui.js). */
.sidebar-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; margin-right: 4px;
  border-radius: 8px; border: 1px solid #E2E8F0;
  background: #fff; color: #475569; font-size: 15px;
  cursor: pointer; font-family: inherit; flex-shrink: 0;
  transition: all .15s;
}
.sidebar-toggle:hover { border-color: var(--act); color: var(--act); background: var(--act-bg); }

.app-layout.sb-collapsed .sidebar { width: 68px; min-width: 68px; }
.app-layout.sb-collapsed .lp-name,
.app-layout.sb-collapsed .lp-sub,
.app-layout.sb-collapsed .nav-group-label,
.app-layout.sb-collapsed .company-switcher { display: none; }
.app-layout.sb-collapsed .sidebar-logo { justify-content: center; padding: 24px 0 16px; }
/* Подпись пункта меню — это текстовый узел (не span), поэтому прячем её через
   font-size:0 на самом пункте, а иконке (.ni-icon) размер возвращаем. */
.app-layout.sb-collapsed .nav-item { justify-content: center; gap: 0; padding: 12px 0; font-size: 0; }
.app-layout.sb-collapsed .nav-item .ni-icon { font-size: 15px; width: auto; }
.sidebar-logo {
  padding: 24px 24px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid rgba(255,255,255,.07);
}
/* ЗНАЧОК ПОРТАЛА (ТЗ владельца 28.08.2026, макет _maket-logo.html, вариант 10).
   Плашки с градиентом больше нет — только буквы цветом: меню стало легче, а знак
   перестал спорить с цветными иконками разделов. Габарит 32×32 сохранён, чтобы
   шапка меню и шапка входа не переехали.

   ЦВЕТ ЗАВИСИТ ОТ ФОНА, НО ТОН ОДИН (ТЗ владельца 04.09.2026). Раньше знак был
   разного ТОНА: в меню голубой #38BDF8, на входе индиго #4F46E5 — владелец
   заметила расхождение сама («логотип на портале ещё синий»). Голубой там стоял
   не по замыслу, а из-за контраста: сам #4F46E5 на фоне меню #0F172A даёт 2.84
   при норме 4.5 — его там попросту не прочитать.

   Решение то же, что у активного пункта меню строкой ниже: тон остаётся индиго,
   меняется СТУПЕНЬ. На тёмном фоне берём осветлённую #A5B4FC (меню — 8.96,
   карточка входа в тёмной теме — 8.43), на светлой карточке входа — сам #4F46E5
   (6.29). Знак и активный пункт меню теперь одного цвета, а голубой из знака
   ушёл: он не означал ничего и был третьим цветом на экране.
   Числа замерены на стенде 04.09.2026. */
.lp-badge {
  width: 32px; height: 32px; border-radius: 8px;
  background: transparent;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; font-weight: 700; letter-spacing: -.5px; color: #A5B4FC;
}
/* На входе подпись «Life Pay» набрана 20 px, и знак 17 px рядом с ней читался
   мельче положенного — без плашки ему нечем держать вес. Уравниваем по размеру
   имени; габарит 32×32 остаётся, чтобы шапка не переехала. */
.lpl-head .lp-badge { color: #4F46E5; font-size: 20px; }
[data-theme="dark"] .lpl-head .lp-badge { color: #A5B4FC; }
.lp-name { font-size: 13px; font-weight: 600; color: #F1F5F9; }
.lp-sub  { font-size: 11px; color: #94A3B8; }

.company-switcher {
  margin: 12px 12px 4px;
  background: rgba(255,255,255,.05);
  border-radius: 12px;
  padding: 12px 12px;
}

/* ── СПИСОК РАЗДЕЛОВ ──
   flex:1 + min-height:0 — высота от контейнера, а не «100vh минус подобранное
   число» (свод, п. 11). min-height:0 обязателен: без него flex-элемент не даёт
   себя сжать ниже содержимого, и прокрутка не появляется вовсе.
   Полоса прокрутки нарочно ВИДНАЯ: если часть разделов за краем, человек должен
   это понимать — невидимая полоса ровно тем и плоха, что список выглядит
   законченным. Активный пункт портал сам подводит в видимую часть
   (_applyPageChrome в app-core.js). */
/* Обёртка нужна ради нижнего края: растворение должно стоять НЕПОДВИЖНО у
   границы области, а псевдоэлемент самой прокручиваемой коробки уехал бы
   вместе с содержимым. Растворение включено всегда и не требует ни JS, ни
   состояния: оно идёт в цвет колонки, поэтому когда под ним ничего нет — его
   попросту не видно, а когда список уходит вниз — последний пункт мягко
   гаснет, и человек понимает, что там есть продолжение. */
.nav-wrap { position: relative; flex: 1; min-height: 0; display: flex; }
.nav-wrap::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 22px;
  background: linear-gradient(rgba(15,23,42,0), #0F172A);
  pointer-events: none;
}
.nav-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* Место под растворение: докрутив список до конца, человек должен видеть
     последний пункт целиком, а не приглушённым. */
  padding-bottom: 24px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.18) transparent;
}
/* Своих ::-webkit-scrollbar здесь больше нет (разбор 10.09.2026): их
   перекрывает scrollbar-width из theme.css, и «8 px» не рисовались нигде.
   Вид полосы в тёмном меню задаёт scrollbar-color двумя строками выше — оно
   стандартное и работает. */

/* Отступ между группами был 16 px. При шестнадцати разделах это 48 px чистого
   воздуха в колонке, где не хватает места; 10 px группы по-прежнему разделяют,
   но список помещается на ноутбуке почти целиком. */
.nav-group { margin: 10px 0 4px; }
/* Подписи групп меню. Было 10/600, uppercase + letter-spacing:1.5px, цвет
   #334155 — контраст 1.72 при норме 4.5, то есть подписи не читались вовсе.
   Заглавные с трекингом свод запрещает отдельно (п. 8): Windows хинтует буквы
   по пиксельной сетке, и заглавные там слипаются. 11/500 и #7C8AA0 — 5.10
   на фоне меню (замер 27.08.2026). */
.nav-group-label {
  padding: 0 20px 6px; font-size: 11px; font-weight: 500;
  color: #7C8AA0;
}
.nav-item {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 24px; font-size: 13px; font-weight: 500;
  /* #64748B давал 3.75 — сами названия разделов не проходили норму 4.5.
     #94A3B8 — 6.96 на фоне меню (замер 27.08.2026). */
  color: #94A3B8; cursor: pointer; position: relative;
  transition: all .15s;
}
.nav-item:hover { color: #CBD5E1; background: rgba(255,255,255,.04); }
/* Активный пункт — акцентом портала. Меню тёмное всегда, поэтому здесь
   светлая ступень индиго (#A5B4FC), а не сам #4F46E5: замер на фоне меню
   даёт 9.1 против 2.3 у тёмного тона (03.09.2026). */
.nav-item.on { color: #A5B4FC; background: rgba(129,140,248,.14); }
.nav-item.on::before {
  content: ''; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%); width: 3px; height: 20px;
  background: #A5B4FC; border-radius: 0 3px 3px 0;
}
.ni-icon { font-size: 15px; width: 20px; text-align: center; display: inline-flex; align-items: center; justify-content: center; }
.ni-icon svg { width: 18px; height: 18px; opacity: .85; }
.nav-item.on .ni-icon svg { opacity: 1; }

/* ПРОФИЛЬ ИДЁТ СРАЗУ ЗА ПУНКТАМИ (решение владельца 15.08.2026).
   Здесь стоял `margin-top:auto`, а в разметке — распорка <div style="flex:1">:
   вдвоём они прижимали блок с именем к самому низу колонки. На рабочем экране
   между «Настройками» и именем оставалась дыра 115 px — 15% высоты окна;
   владелец: «под низом пустое пространство без текста, меню должно быть
   заполнено без просветов». Теперь профиль стоит вплотную к меню, а тёмный фон
   ниже читается как «меню закончилось», а не как пропуск.
   Откат — вернуть margin-top:auto (распорка в index.html убрана). */
/* Подвала с именем здесь больше нет (25.08.2026): он вёл в то же меню, что и
   аватар в правом верхнем углу, и показывал того же человека. Стили ушли
   вместе с разметкой — мёртвые правила потом читаются как действующие. */
/* Метка сборки: приглушённая строчка под подвалом меню. Смотрят её редко — но
   когда смотрят, она отвечает на вопрос «доехала ли копия» за секунду.
   Дата в одну строку и без переносов: меню узкое, и «07.08.2026 21:56» рвалось
   на три строки с обрезкой года — то есть ровно на том, ради чего метка и есть. */
.sf-build { padding: 0 16px 12px; font-size: 11px; color: #7C8AA0; line-height: 1.35; }
.sf-build:empty { display: none; }
/* Было #3A4657 — контраст 1.86: слово «сборка» на экране просто отсутствовало. */
.sf-build .b-l { display: block; }
.sf-build .b-v { display: block; white-space: nowrap; }
/* Узкое меню — прячем: места нет даже под дату, а обрезанная дата хуже, чем
   никакой. Два случая: меню свёрнуто кнопкой и меню сужено узким экраном. */
.sb-collapsed .sf-build { display: none; }
@media (max-width: 768px) { .sf-build { display: none; } }

/* ── MAIN ── */
.app-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}
.app-topbar {
  background: #fff;
  border-bottom: 1px solid #E2E8F0;
  padding: 0 24px;
  height: 58px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}
/* 600, а не 700: шкала насыщенностей свода — 400/500/600 (п. 1). */
.app-topbar-title { font-size: 15px; font-weight: 600; }

/* АВАТАР В ШАПКЕ — вход в меню пользователя. Заливка и начертание те же, что у
   аватара в карточке «Структуры» (.orgv4-emp-ava): один и тот же человек не
   должен выглядеть по-разному на соседних экранах (свод, п. 7). */
.app-tb-ava {
  width: 32px; height: 32px; border-radius: var(--r3);
  border: 1px solid var(--border); background: var(--slate-bg); color: var(--slate);
  font-size: 12px; font-weight: 500; letter-spacing: .3px; font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; overflow: hidden; padding: 0; flex-shrink: 0;
  transition: border-color .15s, box-shadow .15s;
}
.app-tb-ava:hover { border-color: var(--text3); box-shadow: var(--shadow); }
.app-tb-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.app-topbar-spacer { flex: 1; }
.app-tb-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 8px; border: 1px solid #E2E8F0;
  background: #fff; font-size: 12px; font-weight: 600;
  cursor: pointer; font-family: inherit; color: #475569;
  /* ПЕРЕХОД ТОЛЬКО ПО ЦВЕТУ, А НЕ `all` (жалоба владельца 27.08.2026:
     «кнопка уведомлений стала тяжело ходить»). При `all` анимировалась и
     ШИРИНА: счётчик встал рядом со значком (26.08.2026), и каждое появление,
     исчезновение или смена цифры плавно раздвигали кнопку за 0,15 с. На
     мониторе 23 Гц это три-четыре кадра — глаз читает их как рывки, а вместе
     с ними дёргается вся правая часть шапки. Двигаться в шапке нечему:
     красится — плавно, размеры меняются сразу. */
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
  white-space: nowrap;
}
/* Колокольчику нечего сказать: гасим ЗНАЧОК, а не всю кнопку. Прозрачность .5
   на всей кнопке гасила и рамку — кнопка выглядела отключённой, хотя список
   она открывает всегда (та же жалоба 27.08.2026). */
.app-tb-btn.tb-quiet { color: var(--text3); }
.app-tb-btn:hover { border-color: var(--act); color: #0F172A; background: #F0F9FF; }

/* СЧЁТЧИК НА КОЛОКОЛЬЧИКЕ (26.08.2026, по замечанию владельца «пятно с
   количеством выглядит чужеродно»). Разбор показал, что дело не во вкусе:
   значок был набран 9,5 px и насыщенностью 800 — ни того, ни другого нет в
   своде (размеры 11/12/13/15/20, насыщенности 400/500/600), поэтому цифра
   и читалась как из другого интерфейса. Плюс цифры были пропорциональными:
   «11» и «14» имели разную ширину и кружок дышал.

   ВЫБОР ВЛАДЕЛЬЦА 26.08.2026 (из трёх вариантов на макете): число стоит
   РЯДОМ со значком, а не поверх него. Сам колокольчик остаётся чистым —
   раньше цифра сидела прямо на дужке и мазалась по линиям.

   Цвет — по самой срочной строке списка: красный означает отклонение
   (свод, п. 4), а «пять дел на следующий месяц» отклонением не является.
   Заливка бледная, слово — затемнённой (в тёмной теме осветлённой) ступенью
   того же тона: полный цвет на своей заливке норму 4.5 не проходит
   (свод, п. 12). Замеры на стенде: 5.91/5.16 красный, 4.84/5.85 жёлтый,
   4.75/7.39 синий — светлая/тёмная. */
.tb-badge {
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 99px;
  font-size: 11px; font-weight: 600; line-height: 1;
  font-variant-numeric: tabular-nums;
  display: none; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.tb-badge-late  { background: var(--red-bg);    color: #B91C1C; }
.tb-badge-today { background: var(--orange-bg); color: #B45309; }
.tb-badge-soon  { background: var(--blue-bg);   color: var(--blue2); }
[data-theme="dark"] .tb-badge-late  { background: rgba(239,68,68,.16);  color: #F87171; }
[data-theme="dark"] .tb-badge-today { background: rgba(245,158,11,.16); color: var(--orange); }
[data-theme="dark"] .tb-badge-soon  { background: rgba(59,130,246,.16); color: #93C5FD; }

.app-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px 24px 28px;
}

/* ── ШАПКА СТРАНИЦЫ — одна на все вкладки ──────────────────────────────
   Заведено 27.08.2026 по разбору оформления. До этого каждая вкладка рисовала
   заголовок сама: замеры на стенде дали заголовок на высоте 62, 78, 86, 91,
   93, 94, 100, 115, 166 и 167 px, левый край на 86, 92, 108, 109 и 113 px,
   размер 16, 19, 20 и 22 px, насыщенность 600, 700 и 800. Ничего не было
   сломано — но при переключении вкладок заголовок прыгал, и глаз каждый раз
   заново искал, где он находится.

   Теперь метрика одна и живёт здесь:
     заголовок  20/600  var(--text)      — шкала свода, п. 1 и 2;
     подпись    13/400  var(--text2)     — это содержание, ему не --text3 (п. 6);
     действия   справа, прижаты к верху заголовка.
   Отступ сверху не задаётся: его даёт padding:24px у .app-body, поэтому
   высота считается от контейнера, а не подбирается числом (п. 11).

   .page-head-tight — для вкладок, где сразу под шапкой идёт своя панель
   с отступом (таблица учёта, сверки): нижний отступ там лишний. */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0 0 16px;
}
.page-head-tight { margin-bottom: 10px; }
/* Подпись РЯДОМ с заголовком, а не под ним — «Сверки»: ТЗ владельца 30.07.2026,
   при открытом разборе высокая шапка оставляла пустоту в треть экрана.
   Решение владельца сохранено, общей осталась метрика. */
.page-head-inline .page-head-l { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.page-head-inline .page-sub { margin-top: 0; }
.page-head-l { min-width: 0; }
/* ЗАГОЛОВОК СТРАНИЦЫ — 26, А НЕ 20 (разбор уровня 30.08.2026, шаг 2).
   Замер на шести экранах: из 6187 надписей 4255 набраны одним размером 13 px —
   69 %. Самым крупным в портале был этот заголовок, 20 px, и между 15 и 20 не
   стояло ничего. Иерархию держали цвет и положение, а размер почти не работал:
   экран говорил всё одной громкостью и читался как таблица, а не как раздел.
   26 — верхняя ступень шкалы, шкала остаётся целочисленной и короткой
   (свод, п. 2: размеров мало, а не мелких). Заголовок один на экран, поэтому
   шестая ступень не размывает шкалу — она её достраивает вверх.
   letter-spacing слегка усилен: на крупном кегле прежние -.2 читались рыхло. */
.page-h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.22;
  color: var(--text);
  letter-spacing: -.4px;
}
/* <b> и <strong> берут у браузера 700, а шкала свода — 400/500/600 (п. 1).
   Тег в портале означает «выделено словом», а не «жирнее всех»: на Windows,
   где нет сглаживания как на маке, 700 выходит заметно плотнее. */
b, strong { font-weight: 600; }


.page-sub b { color: var(--text); font-weight: 500; }
.page-sub {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--text2);
}
.page-act {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  /* Действия равняются по строке заголовка, а не по середине блока: подпись
     под заголовком не должна сдвигать кнопки вниз. */
  min-height: 25px;
}

/* ── ГЛОБАЛЬНЫЙ ПОИСК ──────────────────────────────────────────────
   ОДНО определение на портал (24.08.2026). До этого поле описывалось ПЯТЬ раз:
   здесь, ещё раз ниже в этом же файле, и трижды в theme.css — включая заплатку
   с #id и !important. Побеждало нижнее, написанное для ЦВЕТНОЙ шапки, которой
   в портале давно нет: белый текст на полупрозрачном белом, скругление 20 при
   высоте 30. Отсюда и «таблетка», в которой курсор жмётся к скруглённому краю.
   Лишние слои удалены, остался этот — на токенах, поэтому обе темы работают
   сами, без отдельных правил.
   Скругление 8 — как у всех полей портала (.fi), высота тоже их (свод, п. 3).
   Ширина ПОСТОЯННАЯ: поле, растущее при щелчке с 200 до 260, дёргает соседние
   кнопки шапки. */
.global-search-wrap { position: relative; margin-right: 8px; }
.global-search-input {
  width: 260px; padding: 8px 12px;
  border-radius: var(--r3); border: 1px solid var(--border);
  background: var(--card2); color: var(--text); font-size: 13px;
  font-family: inherit;
  outline: none; transition: border-color .15s, box-shadow .15s, background .15s;
}
.global-search-input::placeholder { color: var(--text2); }
.global-search-input:focus {
  background: var(--card);
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(59,130,246,.10);
}
/* Подсказка горячей клавиши внутри поля. Текст ставит app-core.js: на маке ⌘K,
   на Windows Ctrl K — раньше в плейсхолдере жёстко стояло «(⌘K)», хотя
   большинство коллег сидит на Windows (замечание владельца 24.08.2026). */
.gs-kbd {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-family: inherit; font-size: 11px; color: var(--text2);
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r3); padding: 2px 8px; pointer-events: none;
  white-space: nowrap;
}
.gs-kbd:empty { display: none; }
.global-search-drop {
  display: none; position: absolute;
  top: calc(100% + 6px); right: 0; width: 340px;
  background: #fff; border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.15);
  z-index: 999; overflow: hidden; max-height: 400px; overflow-y: auto;
}

/* Адаптив */
@media (max-width: 768px) {
  .sidebar { width: 64px; min-width: 64px; }
  /* ПРЯЧЕМ ПОДПИСЬ, А НЕ ИКОНКУ (жалоба владельца 15.08.2026: «меню занимает
     очень большое пространство, снизу пустота»).
     Здесь стояло `.nav-item span:last-child` — но подпись пункта это ТЕКСТОВЫЙ
     УЗЕЛ, а единственный span внутри пункта это как раз .ni-icon. То есть
     правило прятало ИКОНКУ и оставляло текст: в колонке 64 px оставались
     подписи 13 px, «График отпусков» и «Движение кадров» ломались на две
     строки и упирались в края, а значков не было вовсе.
     Приём тот же, что у свёрнутого меню (.sb-collapsed выше): font-size:0 на
     самом пункте гасит текстовый узел, а иконке размер возвращаем. Двух разных
     способов для одного и того же держать нельзя — они расходятся. */
  .lp-name, .lp-sub,
  .nav-group-label, .company-switcher { display: none; }
  .nav-item { justify-content: center; gap: 0; padding: 12px 0; font-size: 0; }
  .nav-item .ni-icon { font-size: 15px; }
  .global-search-input { width: 140px; }
  .global-search-input:focus { width: 180px; }
}
/* ===== RESET ===== */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { min-height: 100vh; background: var(--bg); }

.nav {
  display: flex;
  gap: 2px;
  flex: 1;
}
.nav-item {
  padding: 8px 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}


/* ===== MAIN CONTAINER ===== */
.main { padding: 0 24px 24px; }



/* ===== SECTION CARD ===== */
.scard { padding: 24px; margin-bottom: 16px; }
.scard h2 {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.scard h3 { margin-bottom: 10px; }

/* ===== GRID LAYOUTS ===== */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* ===== ALERTS ===== */
.alert {
  padding: 12px 16px;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}


.dept-card { overflow: hidden; cursor: pointer; }
.dept-head {
  padding: 16px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.dept-head .name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dept-head .badge {
  padding: 3px 12px;
  flex-shrink: 0;
}

/* ===== CONTEXT MENU ===== */
.ctx-menu {
  position: fixed;
  /* Выше модалки (.mo=1000): меню статуса в карточке сотрудника открывается
     поверх модалки, а не под ней — иначе его не видно и не кликнуть. */
  z-index: 100002;
  display: none;
  min-width: 232px;
  padding: 8px;
}
.ctx-menu.show { display: block; }
.ctx-item {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: 8px;   /* подсветка при наведении — «таблеткой», не во всю ширину */
}
/* Иконки пунктов — контурные SVG (stroke:currentColor), поэтому цвет берут от
   пункта: у .danger становятся красными, у остальных — цвета текста. */
.ctx-item svg { opacity: .75; }
.ctx-item:hover svg { opacity: 1; }
.ctx-sep { height: 1px; margin: 6px 8px; }
/* Заголовок группы пунктов меню — тихая подпись, не кликается. */
.ctx-head { font-size: 11px; font-weight: 600; padding: 8px 12px 3px; user-select: none; }
.ctx-head:first-child { padding-top: 4px; }

/* Стилевое подтверждение (замена confirm() браузера) — поверх всего. */
#uiConfirm { display: none; }
.uic-back { position: fixed; inset: 0; z-index: 100010; display: flex; align-items: center; justify-content: center; padding: 24px; }
.uic-card { width: 100%; max-width: 400px; border-radius: 12px; padding: 24px; }
.uic-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.uic-ico { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.uic-title { font-size: 15px; font-weight: 600; line-height: 1.3; }
.uic-msg { font-size: 12px; line-height: 1.6; margin-bottom: 18px; }
.uic-act { display: flex; gap: 8px; justify-content: flex-end; }
/* СОБСТВЕННОЙ ОКРАСКИ ГЛАВНОЙ КНОПКИ ЗДЕСЬ БОЛЬШЕ НЕТ (16.08.2026).
   Правило красило фон в насыщенный --act, но НЕ трогало цвет слова. Пока .btn-p
   был тёмным с белым текстом, это работало; после перевода кнопок портала на
   светло-синее (.btn-p = --blue-bg + --blue2) слово осталось тёмно-синим на
   насыщенно-синем — контраст 1.3, кнопка выглядела пустой синей плашкой.
   Поймано владельцем на окне «Статус „Декрет“ поставлен».
   Замысел правила 04.08.2026 — «главное действие спокойным синим» — теперь
   выполняет сам .btn-p, поэтому исключение не нужно: одна кнопка на портал. */

/* СПИСОК ВНУТРИ ОКНА (владелец 04.08.2026). Раньше перечень строк приходил в
   окно обычным текстом через переносы: тринадцать ФИО с датами и номерами
   сливались в простыню, ширины 400 px не хватало, и окно выглядело недоделанным.
   Теперь список — это список: ровные колонки, прокрутка внутри, ФИО не
   расползается. Заполняется через uiConfirm(msg, { rows: [...] }). */
.uic-card.wide { max-width: 520px; }
.uic-sub { font-size: 12px; color: var(--text2); margin: -6px 0 12px 45px; }
.uic-list {
  border: 1px solid var(--border); border-radius: 8px;
  max-height: 210px; overflow: auto; margin-bottom: 12px;
}
.uic-lr {
  display: grid; grid-template-columns: minmax(0, 1fr) 120px 108px; gap: 12px;
  padding: 8px 12px; font-size: 12px; align-items: baseline;
  border-bottom: 1px solid var(--border2, #EEF1F5);
}
.uic-lr:last-child { border-bottom: 0; }
.uic-lr .n { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uic-lr .p { color: var(--text2); font-variant-numeric: tabular-nums; }
.uic-lr .o { color: var(--text2); font-variant-numeric: tabular-nums; text-align: right;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uic-more { padding: 8px 12px; font-size: 11px; color: var(--text2); }

/* ПОЛЕ ВВОДА В ОКНЕ (uiPrompt, 30.08.2026) — им заменён браузерный prompt().
   Само поле — общее поле портала (.fi), здесь только ширина и отступ до кнопок:
   своих форм и рамок окно не заводит (свод, п. 3). */
.uic-in { width: 100%; box-sizing: border-box; margin-bottom: 16px; }
textarea.uic-in { min-height: 84px; resize: vertical; }
.uic-hint { font-size: 11px; color: var(--text2); margin: -10px 0 14px; }



/* ===== VACATION TYPE BADGES ===== */
.vt { padding: 2px 8px; display: inline-block; }


/* ===== DECRET TABLE ===== */
.dec-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 4px;
}
.dec-table th { text-align: left; padding: 8px 12px; }
.dec-table td { padding: 12px 12px; }
.dec-table tr td:first-child { border-radius: var(--r3) 0 0 var(--r3); }
.dec-table tr td:last-child { border-radius: 0 var(--r3) var(--r3) 0; }

/* ===== BUTTONS ===== */
.btn {
  padding: 8px 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* Отклик на нажатие (22.08.2026): цвет менялся скачком, и кнопка не давала
     понять, что нажатие принято. transform держим отдельной строкой — он
     единственный, что двигается, остальное только красится. */
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .09s ease;
}
.btn:active { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:active { transform: none; }
}
/* Отступы 5, а не 6 (03.09.2026): при 6 содержимое давало 29 px, и заявленный
   в theme.css min-height:28 не помогал — min-height поднимает, но не сжимает.
   Мелкая кнопка стояла на пиксель ниже соседних в том же ряду, хотя ровно от
   этого её и правили 27.08.2026. Замер после правки: 28 ровно. */
.btn-s { padding: 5px 10px; line-height: 1.35; }

/* ═══ ПЕРЕКЛЮЧАТЕЛИ: СЕГМЕНТ И ВКЛАДКИ (ТЗ владельца 16.08.2026) ═══════════════
   Разметку даёт sgmHtml/tbsHtml в app-core.js — там же записано, какая форма
   когда: сегмент меняет режим показа, вкладка уводит в другой раздел. Здесь
   только вид и движение.
   Пункты внутри группы равной ширины (flex:1) — иначе бегунку некуда ехать
   ровно; для 2–4 пунктов это ещё и аккуратнее. */
.sgm{
  position:relative; display:inline-flex; align-items:stretch;
  background:var(--card2); border:1px solid var(--border);
  border-radius:12px; padding:3px;
}
.sgm-i{
  position:relative; z-index:1; flex:1; display:inline-flex; align-items:center;
  justify-content:center; gap:8px; white-space:nowrap;
  font:inherit; font-size:13px; font-weight:500; color:var(--text2);
  background:none; border:none; padding:8px 12px; border-radius:8px;
  cursor:pointer; transition:color .15s;
}
.sgm-i:hover{ color:var(--text); }
.sgm-i.on{ color:var(--text); }
/* Счётчик в пункте («Учёт отпусков 1439»): тот же вид, что был у .thd-seg .n. */
.sgm-i .n, .tbs-i .n{
  font-size:11px; font-weight:500; padding:1px 8px; border-radius:99px;
  background:var(--border); color:var(--text2); font-variant-numeric:tabular-nums;
}
.sgm-i.on .n, .tbs-i.on .n{ background:var(--act-bg); color:var(--act); }
[data-theme="dark"] .sgm-i.on .n, [data-theme="dark"] .tbs-i.on .n{ color:var(--act-hover); }
/* Ширину и сдвиг задаёт sgmSync (app-core.js) — он МЕРЯЕТ выбранный пункт.
   Значения по умолчанию оставлены прежней формулой: если замер почему-то не
   отработал, бегунок хотя бы не исчезнет. Формула верна ровно тогда, когда все
   пункты одной ширины, а длинная подпись этого не позволяет: у flex-элемента
   min-width равен ширине содержимого. */
.sgm-th{
  position:absolute; left:3px; top:3px; bottom:3px;
  width:var(--w, calc((100% - 6px) / var(--n, 1))); border-radius:8px;
  background:var(--card); box-shadow:0 1px 3px rgba(20,40,70,.10);
  transform:translateX(var(--x, calc(var(--to, 0) * 100%)));
}
/* Класс -move ставится, только когда положение ИЗМЕНИЛОСЬ: на первой отрисовке
   страницы ничего не едет. */
.sgm-move .sgm-th{ animation:sgmSlide .2s cubic-bezier(.2,.7,.3,1); }
@keyframes sgmSlide{ from{ transform:translateX(var(--x0, calc(var(--from, 0) * 100%))); } }

.tbs{
  position:relative; display:inline-flex; align-items:stretch;
  border-bottom:1px solid var(--border);
}
.tbs-i{
  position:relative; z-index:1; flex:1; display:inline-flex; align-items:center;
  justify-content:center; gap:8px; white-space:nowrap;
  font:inherit; font-size:13px; font-weight:500; color:var(--text2);
  background:none; border:none; padding:8px 16px; cursor:pointer;
  transition:color .15s;
}
.tbs-i:hover{ color:var(--text); }
.tbs-i.on{ color:var(--text); }
.tbs-th{
  position:absolute; left:0; bottom:-1px; height:2px; border-radius:2px;
  width:var(--w, calc(100% / var(--n, 1))); background:var(--blue2);
  transform:translateX(var(--x, calc(var(--to, 0) * 100%)));
}
[data-theme="dark"] .tbs-th{ background:var(--act-hover); }
.tbs-move .tbs-th{ animation:sgmSlide .2s cubic-bezier(.2,.7,.3,1); }
/* Человек попросил в системе меньше движения — не двигаем ничего. */
@media (prefers-reduced-motion: reduce){
  .sgm-move .sgm-th, .tbs-move .tbs-th{ animation:none; }
  .sgm-i, .tbs-i{ transition:none; }
}

/* ===== FORMS ===== */
.fg { margin-bottom: 10px; }
.fg label { display: block; margin-bottom: 3px; }
.fi, .fs {
  width: 100%;
  padding: 8px 12px;
  outline: none;
}
/* СПИСОК — РОВНО ТА ЖЕ ВЫСОТА, ЧТО У ПОЛЯ (03.09.2026). При одинаковых отступах
   <select> всё равно выходил 36 против 34 у <input>: у него своя внутренняя
   метрика строки. В форме «Новый сотрудник» подпись и список стояли на два
   пикселя выше соседнего поля — ровно то, что свод запрещает в п. 13. */
.fs {
  box-sizing: border-box;
  min-height: 34px;
  padding-top: 8px;
  padding-bottom: 8px;
}

.file-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  margin: 6px 0;
}


/* ===== MODAL ===== */
.mo {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.mo.show { display: flex; }
/* ═══ ПОЯВЛЕНИЕ ОКНА (22.08.2026, переделано 23.08.2026) ═══════════════════
   Было до 22.08.2026: display:none → display:flex, окно возникало рывком.
   Стало 22.08.2026: фон проявлялся, карточка поднималась на 8 px за 160 мс.
   ПЕРЕДЕЛАНО 23.08.2026 по замеру владельца на её рабочем мониторе 23 Гц.

   Почему движение убрано совсем. На 23 Гц новый кадр приходит раз в 43 мс,
   значит 160 мс — это 3–4 кадра. Подъём карточки за три кадра глаз читает
   как три отдельных положения: ступеньки, а не скольжение. Плавным такое
   движение стало бы только при 350–430 мс, но тягучее окно надоедает при
   десятках открытий за день. Поэтому анимируется ОДНА прозрачность: даже на
   трёх кадрах она читается как мягкое включение — дёргаться нечему.

   Обе части идут одинаковые 120 мс: разные длительности (было 140 и 160)
   дробят появление на два события там, где кадров и так мало. */
@keyframes moBackIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes moCardIn { from { opacity: 0; } to { opacity: 1; } }
.mo.show { animation: moBackIn .12s ease-out both; }
/* will-change просит браузер вынести карточку на отдельный слой заранее —
   иначе первый кадр уходит на подготовку, и на медленной машине именно он
   «проглатывается» (замер 22.08.2026). Движения больше нет, поэтому только
   opacity: обещать браузеру transform, которого не будет, незачем. */
.mo.show > .mc { animation: moCardIn .12s ease-out both; will-change: opacity; }
/* Пока окно открыто, его содержимое не должно заставлять страницу под ним
   пересчитывать раскладку: окно и так перекрывает всё. */
.mo.show > .mc { contain: layout paint; }
@media (prefers-reduced-motion: reduce) {
  .mo.show, .mo.show > .mc { animation: none; }
}
/* УБРАНА ветка @media (update: slow) — она не срабатывала никогда. Замер
   23.08.2026 на мониторе 23 Гц: браузер отвечает update:fast, признак
   update:slow зарезервирован за особыми экранами вроде электронных чернил.
   Правило выглядело как защита медленных экранов, но было мёртвым; вместо
   него появление сделано дешёвым сразу для всех. */
.mc {
  max-width: 520px;
  width: 92%;
  max-height: 85vh;
  overflow-y: auto;
  padding: 24px;
  /* Для крестика в углу. Абсолютным потомкам внутри окон это ничего не
     меняет: .mo.show > .mc и так содержащий блок (contain:layout paint) —
     проверено на «Оформлении календаря», где их восемнадцать. */
  position: relative;
}

/* ── КРЕСТИК В УГЛУ — ОДИН НА ВСЕ ОКНА (27.08.2026) ────────────────────────
   Замер по 38 окнам, которые открываются автоматически: свой крестик был
   у 16, у 19 угол свободен, у трёх занят. Рисуется он в showMo, а не в
   разметке каждого окна: окон 129 в 56 файлах, поштучно такое не выдерживается
   — часть новых окон снова оказалась бы без него. Если окно уже рисует свой ✕,
   второго не появится.
   Закрывает через moTryClose — то есть ведёт себя как Esc и как клик по фону,
   включая черновик несохранённой правки. */
.mc-x {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 28px; height: 28px; padding: 0;
  border: none; border-radius: 8px; background: none;
  color: var(--text2); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, color .12s ease;
}
.mc-x:hover { background: var(--card2); color: var(--text); }
/* Заголовок не должен заезжать под крестик. */
.mc-has-x > h3, .mc-has-x > h2 { padding-right: 34px; }

.mc h3 { margin-bottom: 14px; }
/* ── ПОДВАЛ ОКНА — ОДНА МЕТРИКА (27.08.2026) ───────────────────────────────
   Замер по 38 окнам: подвалов оказалось ТРИНАДЦАТЬ разных на 24 окна с
   кнопкой закрытия, с зазорами 6, 8, 9 и 10 px. Причина не в фантазии авторов,
   а в дрейфе: у .mc-a класс уже задаёт раскладку, но рядом стоял инлайн,
   повторяющий её другими числами (25 таких повторов снято).
   Зазор 8 — тот же, что у действий в шапке страницы (.page-act): один шаг
   между кнопками на весь портал.

   Подвалов на деле ДВА вида, и это разные вещи, а не разнобой:
     .mc-a          — строка кнопок под содержимым обычного окна;
     подвал с полосой — прижат к низу широкого окна, отделён линией.
   Здесь сведены их общие числа; линия и прижатие остаются каждому свои. */
.mc-a {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}
/* Подвалы с полосой (.vf, .ab-foot, .bt-foot, .sc-foot, .och-foot, .sum-foot,
   .pci-acts) держат тот же зазор 8, но правится он В ИХ СОБСТВЕННЫХ файлах:
   стили модулей вставляются в документ ПОСЛЕ style.css и общее правило отсюда
   просто не работало бы (поймано на стенде 27.08.2026). */

/* ===== TOAST ===== */
/* Уведомления (макет sverka-mockup-3.html, перенесено 30.07.2026).
   Снизу ПО ЦЕНТРУ, а не в углу: там их видно, не отводя взгляд от таблицы.
   Новое уведомление встаёт СНИЗУ стопки, у самого края: оно ближе к глазу и,
   когда верхнее (старое) догорает, нижнее не прыгает — оно прижато к краю.
   Контейнер не ловит курсор, ловят только сами пилюли: иначе невидимая полоса
   накрывала бы низ страницы и мешала нажимать кнопки под ней. */
.tw {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.ts {
  pointer-events: auto;
  display: flex; align-items: center; gap: 12px;
  max-width: min(92vw, 620px);
  padding: 12px 16px;
  border-radius: 12px;
  background: #171C26;
  color: #fff;
  font-size: 13px; font-weight: 600; line-height: 1.4;
  box-shadow: 0 12px 32px -8px rgba(16,24,40,.45);
  cursor: pointer;
  opacity: 0; transform: translateY(8px);
  transition: opacity .2s, transform .2s;
}
.ts.on { opacity: 1; transform: translateY(0); }
.ts-ic {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 20px; height: 20px; border-radius: 50%;
  font-size: 12px; font-weight: 600;
  background: rgba(255,255,255,.16); color: #fff;
}
.ts-s .ts-ic { background: #1F9D5B; }
.ts-e .ts-ic { background: #DC3D43; }
.ts-w .ts-ic { background: #B45309; }
.ts-t { min-width: 0; }
/* Действие в уведомлении — «Отменить». Зелёный, чтобы читался на тёмном. */
.ts-act {
  font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap;
  border: 0; background: none; color: #7EE2A8; cursor: pointer; padding: 0 0 0 4px;
}
.ts-act:hover { text-decoration: underline; }

/* ═══ ВСПЛЫВАЮЩИЕ УВЕДОМЛЕНИЯ ЛИЧНОГО КАЛЕНДАРЯ (26.08.2026) ══════════════════
   Разметку строит app-notify.js, здесь только вид. Живут рядом с тостами
   намеренно: это соседние вещи общего слоя, и разъезжаться им нельзя.
   Отличие от тоста: тост говорит о том, ЧТО ТОЛЬКО ЧТО СДЕЛАЛ человек, и
   уходит сам; уведомление приходит само и ЖДЁТ решения — поэтому у него
   кнопки, светлая карточка портала и место в углу, а не по центру внизу.

   Вид «А тихая» (выбор владельца 26.08.2026): без заливки, цвет только у
   значка и слова вида. z-index 900 — НИЖЕ модального окна (1000): открытую
   форму карточка перекрывать не должна.
   Появление и исчезание — 480 мс одной прозрачностью, длительность ставит
   app-notify.js инлайном (NTF_ДЛИТ). */
.ntw {
  position: fixed; top: 70px; right: 24px; z-index: 900;
  display: flex; flex-direction: column; gap: 12px; align-items: flex-end;
  pointer-events: none;
}
.ntf {
  pointer-events: auto; position: relative; box-sizing: border-box; width: 352px;
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 16px 12px 15px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 32px -12px rgba(16,24,40,.28);
  opacity: 0;
}
.ntf.on { opacity: 1; }
[data-theme="dark"] .ntf { box-shadow: 0 12px 32px -12px rgba(0,0,0,.6); }
@media (prefers-reduced-motion: reduce) { .ntf { transition: none !important; } }
@media (max-width: 520px) { .ntw { left: 12px; right: 12px; } .ntf { width: 100%; } }

.ntf-ic { flex-shrink: 0; width: 30px; height: 30px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center; }
.ntf-main { flex: 1; min-width: 0; }
.ntf-head { display: flex; align-items: center; gap: 8px; }
.ntf-kind { font-size: 11px; font-weight: 500; }
.ntf-sep { font-size: 11px; color: var(--text3); }
.ntf-when { font-size: 11px; color: var(--text2); font-variant-numeric: tabular-nums; }
.ntf-title { font-size: 13px; font-weight: 500; color: var(--text); line-height: 1.35;
  margin-top: 3px; word-break: break-word; }
.ntf-one { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ntf-sub { font-size: 11px; color: var(--text2); margin-top: 3px; line-height: 1.4; }
.ntf-acts { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.ntf-sp { flex: 1; }
.ntf-x { position: absolute; top: 8px; right: 8px; width: 22px; height: 22px;
  border: none; background: none; color: var(--text3); border-radius: 8px;
  cursor: pointer; padding: 0; display: inline-flex; align-items: center;
  justify-content: center; transition: color .15s, background .15s; }
.ntf-x:hover { color: var(--text); background: var(--card2); }

/* Тон по виду записи: значок и слово. Слово — ступень своего тона, полный
   цвет на заливке норму 4.5 не проходит (свод, п. 12). Замеры на стенде
   26.08.2026: 5.17/9.32 синий, 6.92/8.88 серый, 6.48/7.24 фиолетовый. */
.ntf-meeting .ntf-ic   { background: var(--blue-bg);   color: var(--blue2); }
.ntf-meeting .ntf-kind { color: var(--blue2); }
[data-theme="dark"] .ntf-meeting .ntf-ic   { background: rgba(59,130,246,.16); color: #93C5FD; }
[data-theme="dark"] .ntf-meeting .ntf-kind { color: #93C5FD; }
.ntf-task .ntf-ic      { background: var(--slate-bg);  color: #475569; }
.ntf-task .ntf-kind    { color: #475569; }
[data-theme="dark"] .ntf-task .ntf-ic      { background: rgba(100,116,139,.2); color: #CBD5E1; }
[data-theme="dark"] .ntf-task .ntf-kind    { color: #CBD5E1; }
.ntf-remind .ntf-ic    { background: var(--purple-bg); color: #6D28D9; }
.ntf-remind .ntf-kind  { color: #6D28D9; }
[data-theme="dark"] .ntf-remind .ntf-ic    { background: rgba(139,92,246,.18); color: #C4B5FD; }
[data-theme="dark"] .ntf-remind .ntf-kind  { color: #C4B5FD; }

/* Панель «Отложить» раскрывается ВНУТРИ карточки: отдельное окно ради двух
   кнопок — лишний слой, а карточка при этом не прыгает по экрану. */
.ntf-sn { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--border); }
.ntf-lbl { font-size: 11px; font-weight: 500; color: var(--text2); margin-bottom: 6px; }
.ntf-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ntf-chip { font-family: inherit; font-size: 11px; font-weight: 500; color: var(--text2);
  background: var(--card2); border: 1px solid var(--border); border-radius: 99px;
  padding: 4px 12px; cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, transform .09s ease; }
.ntf-chip:hover { background: var(--act-bg); border-color: var(--act); color: var(--act); }
.ntf-chip:active { transform: scale(.97); }
.ntf-chip.on { background: var(--act-bg); border-color: var(--act); color: var(--act); }
.ntf-exact { display: grid; grid-template-columns: 1fr 64px 64px; gap: 8px; margin-top: 8px;
  align-items: center; }
/* Поле со списком внутри карточки: высота как у соседнего <select> в этой же
   строке — иначе три поля в ряд стоят разной высоты (свод, п. 13). */
.ntf-exact .np-in { height: 30px; padding: 5px 24px 5px 8px; }
.ntf-fi { width: 100%; box-sizing: border-box; height: 30px; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 8px; font-size: 12px;
  font-family: inherit; color: var(--text); background: var(--card); }
.ntf-fi-s { width: 64px; }
.ntf-note { font-size: 11px; color: var(--text2); margin-top: 9px;
  font-variant-numeric: tabular-nums; }
.ntf-foot { display: flex; align-items: center; gap: 8px; margin-top: 7px; }

/* Ответ на нажатие: карточка не пропадает молча, а говорит, что сделала. */
.ntf-ok { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.ntf-ok-ic { width: 26px; height: 26px; border-radius: 99px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--green-bg); color: #15803D; }
[data-theme="dark"] .ntf-ok-ic { background: rgba(34,197,94,.16); color: #4ADE80; }
.ntf-ok-t { font-size: 12px; font-weight: 500; color: var(--text); }
.ntf-ok-s { font-size: 11px; color: var(--text2); margin-top: 2px;
  font-variant-numeric: tabular-nums; }

/* ===== DATA TABLE (app-table) ===== */
.tbl-main { width: 100%; border-collapse: collapse; }
.tbl-main th {
  padding: 12px 8px;
  text-align: left;
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 10;
  cursor: pointer;
  user-select: none;
}
.ci {
  width: 100%;
  padding: 8px;
  border: none;
  background: transparent;
  outline: none;
}
/* Подсказка в пустой ячейке (например «НФЗП-000587...» в колонке «Приказ») не
   должна выглядеть как заполненное значение: цвет поля голубой и жирный, и
   пустая ячейка читалась как «приказ уже есть». Найдено 01.08.2026 при проверке
   таблицы учёта — на скриншоте это вводит в заблуждение даже вблизи. */
.ci::placeholder {
  color: var(--text3, #94A3B8);
  font-weight: 400;
  opacity: 1;
}
.ci-sel { cursor: pointer; }
.del-btn {
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ===== KANBAN BOARD ===== */
.main.main-home-bg {
  min-height: calc(100vh - 56px);
  border-radius: 0;
  margin: 0 -24px;
  padding: 0 24px 24px;
}

/* ===== EMPLOYEE CALENDAR MODAL ===== */
/* УЗКОЕ ОКНО НА ОДНО ДЕЙСТВИЕ (22.08.2026). Для окон вроде «Отложить задачу»:
   заголовок, пара строк объяснения, одно поле и кнопка. В общем .mc такое
   содержимое тонуло — 24 px внешнего padding складывались с 22 px у блоков
   внутри, и вокруг узкой формы оставалось 46 px полей с каждой стороны.
   Здесь внешнего padding нет: отступы задают сами блоки, как в .mc-card. */
.mc.mc-narrow {
  max-width: 420px;
  width: 92%;
  padding: 0;
  overflow: hidden;
}
.mc.mc-narrow .dp-field { width: 100%; }

.mc.mc-wide {
  max-width: 960px;
  width: 94%;
  max-height: 92vh;
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* ШИРОКОЕ ОКНО, КОТОРОЕ ПРОКРУЧИВАЕТСЯ ЦЕЛИКОМ.
   .mc-wide сделан для календаря сотрудника: у него внутри своё тело со
   скроллом, поэтому у самого окна overflow:hidden. Окнам без такого тела
   (история отпуска) это запрещало прокрутку: пока история короткая — всё видно,
   а стоит раскрыть её полностью, низ просто обрезается и окно «замирает»
   (боевой случай владельца 03.08.2026). Этот модификатор возвращает окну
   собственную прокрутку, ширину оставляет широкой. */
.mc.mc-wide.mc-flow {
  display: block;
  overflow-y: auto;
}
.emp-cal-header {
  padding: 24px 28px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-shrink: 0;
  position: relative;
}
.emp-cal-header-right {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-shrink: 0;
}
.emp-cal-stat { text-align: center; padding: 8px 16px; }
.emp-cal-close {
  position: absolute;
  right: 16px;
  top: 16px;
  width: 32px;
  height: 32px;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.emp-cal-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px 28px 24px;
}
.emp-cal-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 20px;
}
.emp-cal-month { padding: 12px; }
.emp-cal-month-title {
  text-align: center;
  margin-bottom: 6px;
  padding-bottom: 4px;
}
.emp-cal-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  text-align: center;
  margin-bottom: 2px;
}
.emp-cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.emp-cal-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
  position: relative;
}
/* Подсказка теперь своя карточка (calDayTip), а не системный title — курсор
   ставим по data-d, которым помечены дни с подсказкой. */
.emp-cal-day[data-d] { cursor: help; }
.emp-vac-section-title {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.emp-vac-card {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin-bottom: 8px;
  overflow: hidden;
}
.emp-vac-card-stripe {
  width: 5px;
  flex-shrink: 0;
}
.emp-vac-card-body {
  flex: 1;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.emp-vac-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  white-space: nowrap;
  flex-shrink: 0;
}
.emp-vac-type-badge {
  padding: 2px 8px;
  flex-shrink: 0;
}
.emp-vac-card-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 10px;
  flex-shrink: 0;
}


/* ===== SICK / SEDO ===== */
.sick-chk { width: 16px; height: 16px; cursor: pointer; }
.sick-chk:disabled { cursor: default; }

@media (max-width: 768px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .nav { display: none; }
  .main.main-home-bg { margin: 0 -16px; padding: 0 16px 16px; }
  .mc.mc-wide { max-width: 100%; width: 100%; max-height: 100vh; border-radius: 0; }
  .emp-cal-grid { grid-template-columns: repeat(2, 1fr); }
  .emp-cal-header { flex-direction: column; }
  .emp-cal-header-right { flex-wrap: wrap; }
  .emp-vac-card-body { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 480px) {
  .emp-cal-grid { grid-template-columns: repeat(1, 1fr); }
}
/* ===== FIX: zoom компенсация ===== */
body {
  min-width: 100vw;
  overflow-x: hidden;
}
/* ===== ЖУРНАЛ — ховер строки ===== */
.log-entry {
  transition: background .1s;
}
.log-entry:hover {
  background: var(--card2);
}

/* Поле поиска описано выше, одним блоком. Второе определение (белый текст
   для цветной шапки) удалено 24.08.2026 — шапка светлая с редизайна. */
.global-search-drop {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 340px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.15);
  z-index: 999;
  overflow: hidden;
  max-height: 400px;
  overflow-y: auto;
}
.gs-section-title {
  padding: 12px 16px 8px;
  font-size: 11px;
  font-weight: 600;
  color: #9CA3AF;
  
  
}
.gs-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background .1s;
}
.gs-item:hover { background: #F3F4F6; }
.gs-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #EFF6FF;
  color: #2563EB;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 500;
  flex-shrink: 0;
}
.gs-info { flex: 1; min-width: 0; }
.gs-name {
  font-size: 13px;
  font-weight: 600;
  color: #111827;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gs-sub { font-size: 11px; color: #9CA3AF; }
.gs-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 8px;
  white-space: nowrap;
  flex-shrink: 0;
}
.gs-badge-vac { background: #D1FAE5; color: #065F46; }
.gs-badge-soon { background: #FEF3C7; color: #92400E; }
.gs-mark {
  background: #FEF08A;
  color: #111827;
  border-radius: 2px;
  padding: 0 1px;
}
.gs-empty {
  padding: 24px;
  text-align: center;
  color: #9CA3AF;
  font-size: 13px;
}
/* ── ЗАДАЧИ НА ГЛАВНОЙ ─────────────────────────────────────────────────────
   Остаток раздела «ГЛАВНАЯ v6»: сам список задач рисуется инлайновыми стилями
   в app-home.js, а классы ниже — то немногое, что ещё красит разметку.
   Прежняя главная (её разметка, KPI, заметки, редактор виджетов) удалена
   29.07.2026 — если понадобится посмотреть, она в истории git.
   ────────────────────────────────────────────────────────────────────────── */
.hm-task-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 12px; margin-bottom: 2px;
  border-radius: 8px; cursor: pointer;
  transition: background .12s;
}
.hm-task-item:hover { background: #F8FAFC; }
.hm-task-item.hm-task-done { opacity: .6; }
.hm-task-cb {
  width: 20px; height: 20px;
  border: 2px solid #CBD5E1; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  transition: all .2s;
  /* Клик проходит сквозь галочку к самому чекбоксу. Правило переехало сюда из
     удалённого app-home-styles.css (29.07.2026) — там лежала вторая копия этих
     же стилей, и только в ней было pointer-events. */
  pointer-events: none;
}
.hm-chk-path {
  stroke-dasharray: 20; stroke-dashoffset: 20;
  transition: stroke-dashoffset .3s .1s ease-out;
}
/* ===== DRAWER INPUTS — focus styles ===== */
#tblDrawer input:focus,
#tblDrawer select:focus {
  border-color: #38BDF8 !important;
  box-shadow: 0 0 0 3px rgba(56,189,248,.1);
  outline: none;
}

/* ================================================================
   CALENDAR v2.0 — Новый дизайн
   ================================================================ */

/* Высота — от родителя, а не «окно минус подобранное число» (свод
   «Оформление», п. 11). Прежняя calc(100vh - 120px) промахивалась на 2 px
   всегда, а min-height:600px на ноутбучном окне 720 px давал ещё и лишнюю
   прокрутку страницы. .app-body — растянутый flex-элемент, высота у него
   определённая, поэтому процент считается честно; 16 px вычитаем на свой же
   отступ сверху. */
/* Вкладка — колонка на всю высоту области: шапка сверху, карточка календаря
   забирает остаток. Высота считается от контейнера, а не «100% минус
   подобранное число» (свод, п. 11): раньше .cal-v2-wrap стояла первой и
   держала calc(100% - 16px) под свой же margin-top. */
.cal-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}
.cal-v2-wrap {
  display: flex;
  flex-direction: column;
  gap: 0;
  flex: 1;
  min-height: 0;
}

/* ── ТОПБАР ── */
.cal-v2-topbar {
  background: var(--card);
  border-radius: 12px 12px 0 0;
  border: 1px solid var(--border);
  border-bottom: none;
  padding: 16px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  /* ПЕРЕНОС ВМЕСТО ОБРЕЗАНИЯ (03.09.2026). На окне 900 px в топбаре не хватало
     11 px, и портал добирал их, сжимая заголовок: «Сентябрь 2026» показывался
     как «Сентябр» шириной 62 px вместо 135, а кнопка «Сегодня» вставала на
     остаток слова. Резать название месяца нельзя — это главное слово экрана.
     С переносом правая группа кнопок уезжает на вторую строку целиком; на
     рабочих 1280 и 1440 всё по-прежнему в одну строку (замер ниже). */
  flex-wrap: wrap;
  row-gap: 12px;
}
/* min-width:0 — иначе шапка вылезает за правый край карточки (замер
   25.08.2026, окно 1280: топбар кончается на 1256, сегмент видов тянется до
   1263, кнопка «⋯» стоит на 1275–1309, то есть снаружи). У флекс-элемента
   min-width по умолчанию auto, и блок с заголовком не ужимался ниже своей
   ширины по содержимому — 497 px, из которых почти половина уходила строке
   «Ближайшее — …». Уступать место должна она: у неё для этого уже есть
   многоточие (.cal-v2-head-sub), а заголовок и кнопки не режутся. */
.cal-v2-nav { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Цвет стрелок был НЕ ЗАДАН вовсе — <button> брал чёрный по умолчанию от
   браузера. На светлой теме это незаметно, на тёмной — чёрное на #1A1D27,
   контраст 1.25: стрелки листания месяца пропадали (дозор по кнопкам 16.08.2026). */
.cal-v2-nav-btn {
  width: 34px; height: 34px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card); color: var(--text2);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; font-size: 15px; transition: border-color .15s, background .15s;
}
.cal-v2-nav-btn:hover { border-color: var(--text3); background: var(--card2); }
.cal-v2-month-title {
  font-size: 20px; font-weight: 600; margin: 0 4px;
}
.cal-v2-today-btn {
  padding: 7px 14px; min-height: 34px; box-sizing: border-box;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--card); font-size: 12px; font-weight: 500; cursor: pointer;
  font-family: inherit; color:var(--text2); transition: all .15s;
  /* Кнопка в одну строку: на окне 1100 px «+ Новая задача» разваливалась на
     три строки и делала шапку двухэтажной (замер 21.08.2026). */
  white-space: nowrap;
}
.cal-v2-today-btn:hover { border-color: var(--act); color: var(--act); background: var(--act-bg); }
/* Акцентная кнопка «Новая задача» и включённая «Правка календаря». Слово на
   цветной заливке берёт затемнённую ступень своего тона на светлой теме и
   осветлённую на тёмной: --blue на --blue-bg даёт 3.38, --orange на
   --orange-bg — 2.07 (свод «Оформление», п. 12). */
.cal-v2-today-btn.cal-v2-btn-accent {
  border-color: var(--act-line); background: var(--act-bg); color: var(--act);
}
[data-theme="dark"] .cal-v2-today-btn.cal-v2-btn-accent { color: var(--act-hover); }
.cal-v2-today-btn.cal-v2-btn-editing {
  border-color: var(--orange); background: var(--orange-bg); color: #B45309;
}
[data-theme="dark"] .cal-v2-today-btn.cal-v2-btn-editing { color: var(--orange); }
.cal-v2-spacer { flex: 1; }
.cal-v2-view-tabs {
  display: flex; background: var(--border); border-radius: 8px; padding: 3px; gap: 2px;
}
.cal-v2-vt {
  padding: 4px 16px; border-radius: 8px; border: none; background: none;
  font-size: 12px; font-weight: 500; color:var(--text2); cursor: pointer;
  font-family: inherit; transition: all .15s;
}
.cal-v2-vt.active {
  background: var(--card); color:var(--text);
  box-shadow: 0 1px 4px rgba(0,0,0,.08);
}

/* ── LAYOUT ── */
/* Одна колонка: левая панель убрана, её 260 px достались сетке
   (ТЗ владельца 06.08.2026). */
.cal-v2-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  flex: 1;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 0 0 12px 12px;
  background: var(--card);
}

/* Полоса фильтров под шапкой: тип, статус, «Без даты», обозначения.
   Чипы .cal-v2-filter-chip переиспользуются как есть — в колонке их подпись
   растягивалась (flex:1), в строке она должна быть по содержимому. */
/* ПОЛОСЫ НАСТРОЕК ПОДЖАТЫ (ТЗ владельца 07.09.2026). Над сеткой недели стояло
   шесть полос общей высотой 339 px при 900 px экрана — рабочей области
   оставалось 47%, а на ноутбуке 1280×720 всего 32% (пять часов из суток).
   Здесь и в .cw-bar срезаны вертикальные отступы: обе полосы про одно и то же —
   что показывать и в каком масштабе, — и держать их в полный рост незачем. */
.cal-v2-fbar {
  background: var(--card); border: 1px solid var(--border); border-bottom: none;
  padding: 4px 24px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  flex-shrink: 0;
}
.cal-v2-fbar .cal-v2-filter-chip { margin-bottom: 0; }
.cal-v2-fbar .cal-v2-fc-label { flex: none; }
.cal-v2-fbar-sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
.cal-v2-fbar-sp { flex: 1; }
/* Обозначения — без рамок: это подпись, а не фильтры. Цвет --text2, а не
   --text3: у --text3 контраст 2.54 на светлой и 2.22 на тёмной — для текста
   не годится (свод «Оформление», п. 6). */
.cal-v2-fbar-legend { display: flex; align-items: center; gap: 16px; }
.cal-v2-fbl { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--text2); }
.cal-v2-fbl-sw { width: 18px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.cal-v2-fbl-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* Левая панель и мини-календарь удалены (ТЗ владельца 06.08.2026): мини-календарь
   дублировал сетку и ни на что не реагировал, остальное переехало в полосу
   фильтров под шапкой. .cal-v2-section-title и .cal-v2-filter-chip остались —
   чипы теперь стоят в строку, вид у них тот же. */

.cal-v2-section-title {
  font-size: 11px; font-weight: 600; color: var(--text3);
  margin-bottom: 10px;
}

/* Фильтры */
.cal-v2-filters {
  padding: 16px 16px;
  border-bottom: 1px solid var(--border);
}
.cal-v2-filter-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 8px; margin-bottom: 3px;
  cursor: pointer; transition: background .12s;
  border: 1px solid transparent;
}
.cal-v2-filter-chip:hover { background: var(--card2); }
.cal-v2-filter-chip.active { background: var(--act-bg); border-color: var(--act); }
.cal-v2-fc-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.cal-v2-fc-label { font-size: 12px; font-weight: 500; color:var(--text2); flex: 1; }
.cal-v2-filter-chip.active .cal-v2-fc-label { color:var(--text); font-weight: 600; }
.cal-v2-fc-count {
  font-size: 11px; font-weight: 500; padding: 1px 8px;
  border-radius: 99px; background: var(--border); color:var(--text2);
}

/* Ближайшие */
.cal-v2-upcoming { padding: 16px 16px; flex: 1; overflow-y: auto; }
.cal-v2-upcoming-empty { font-size: 13px; color: var(--text2); text-align: center; padding: 16px; }
.cal-v2-up-item {
  display: flex; gap: 12px; padding: 8px 8px; border-radius: 8px;
  cursor: pointer; transition: background .12s; margin-bottom: 3px;
}
.cal-v2-up-item:hover { background: var(--card2); }
.cal-v2-up-info { flex: 1; min-width: 0; }
.cal-v2-up-name { font-size: 12px; font-weight: 500; color:var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-v2-up-meta { font-size: 11px; color:var(--text2); margin-top: 1px; }

/* ── ПРАВАЯ ЧАСТЬ ── */
.cal-v2-main {
  display: flex; flex-direction: column; overflow: hidden; padding: 16px;
}

/* DOW заголовок */
.cal-v2-dow-row {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px; margin-bottom: 8px; flex-shrink: 0;
}
/* Обычный регистр без трекинга: «ПОНЕДЕЛЬНИК» с letter-spacing на Windows
   слипается — там нет сглаживания, которое стоит у нас на body, и буквы
   хинтуются по пиксельной сетке (свод «Оформление», п. 8). */
.cal-v2-dow {
  text-align: center; font-size: 12px; font-weight: 500; color:var(--text2);
  padding: 8px 0;
}
/* Красный выходных остаётся — это нерабочий день, а не оформление. Но слово
   берёт затемнённую ступень того же тона: сам --red даёт 3.42 на заливке
   выходного, #B91C1C — 5.88. В тёмной теме ступень светлее (свод, п. 12). */
.cal-v2-dow.wknd { color: #B91C1C; }
[data-theme="dark"] .cal-v2-dow.wknd { color: #F87171; }
/* Полное название дня недели показываем, только когда оно помещается.
   Замерено на портале: при окне 1280 колонка 96 px, а «ПОНЕДЕЛЬНИК» просил 94 —
   слова соприкасались. От 1400 px колонка ≥ 108 px, запас появляется.
   Обычным регистром слово уже, но порог не трогаем: он с запасом.
   По умолчанию — короткое: так шапка не ломается и на узких окнах. */
.cal-dow-full  { display: none; }
.cal-dow-short { display: inline; }
@media (min-width: 1400px) {
  .cal-dow-full  { display: inline; }
  .cal-dow-short { display: none; }
}

/* Сетка месяца */
/* align-content: stretch, а не start. При start строки прижимались кверху, и под
   сеткой оставалась мёртвая полоса — 80 px замерено при окне 1440×900. Убрали
   лишнюю шестую строку — полоса выросла бы до 176 px. Теперь строки разбирают
   высоту между собой: клетки стали выше, и в них помещается третий чип
   (ТЗ владельца 06.08.2026). */
/* Сетка линиями, а не сорока двумя карточками (ТЗ владельца 16.08.2026).
   Рамка и скругление у каждой клетки повторялись 42 раза на экран, и месяц
   читался как россыпь плиток. Теперь панель одна: фон сетки — цвет линии,
   зазор 1 px открывает его между клетками. */
.cal-v2-grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px; flex: 1; overflow-y: auto;
  align-content: stretch;
  /* ВЫСОТА СТРОК — ОТ КОНТЕЙНЕРА (25.08.2026, свод п. 11). Раньше высоту клетки
     задавала лесенка min-height (90 px, на невысоком окне 72), и на ноутбуке
     1280×720 сетке всё равно не хватало 48 px: последняя неделя месяца уходила
     под прокрутку — во вкладке, которая существует ради обзора месяца.
     Теперь строки делят свободную высоту сами (1fr), а 62 px — пол, ниже
     которого клетка не сжимается: в неё помещаются число и одна плашка. */
  grid-auto-rows: minmax(62px, 1fr);
  background: var(--border); border: 1px solid var(--border);
  border-radius: 12px; overflow-x: hidden;
}
.cal-v2-cell {
  /* Пол высоты живёт на СТРОКЕ сетки (grid-auto-rows выше), а не на клетке:
     min-height у клетки не давал строке сжаться и ломал деление свободной
     высоты. */
  min-height: 0; min-width: 0; padding: 8px 6px;
  background: var(--card);
  cursor: pointer; transition: background .12s, box-shadow .12s;
  display: flex; flex-direction: column; gap: 4px;
}
/* НЕВЫСОКОЕ ОКНО. Высоту клеток здесь больше не трогаем — этим занимается
   grid-auto-rows выше. Остаются отступы: на ноутбуке они уступают место сетке.
   Считаем от высоты окна, а не от ширины: не помещается именно по высоте. */
@media (max-height: 900px) {
  .cal-v2-main { padding: 12px 16px; }
  .cal-v2-month-foot { margin-top: 8px; }
}

/* Рамки нет — ховер и «сегодня» рисуются внутренней тенью, иначе клетка
   раздвигала бы соседей. */
.cal-v2-cell:hover { box-shadow: inset 0 0 0 1px var(--act); }
/* «Сегодня» помечено ОДИН раз (21.08.2026): заливкой клетки и кружком на
   числе. Рамка в 2 px поверх этого была третьим сигналом того же самого и
   спорила с ховером, у которого рамка в 1 px. */
.cal-v2-cell.today { background: var(--blue-bg); }
.cal-v2-cell.wknd { background: var(--card2); }
/* Чужой месяц: приглушаем фоном и цветом числа, а не opacity — прозрачность
   гасила и линии сетки под клеткой. */
.cal-v2-cell.other-m { background: var(--bg); cursor: default; }
.cal-v2-cell.other-m:hover { box-shadow: none; }
/* ЧИСЛА ЧУЖИХ МЕСЯЦЕВ — ПРИГЛУШЕНЫ, НО ЧИТАЕМЫ (04.09.2026). Стоял --text3:
   2.41 на фоне календаря в светлой теме и 2.49 в тёмной при норме 4.5 — дата
   переставала быть датой. Ступень выведена из самого --text3 по правилу свода
   (п. 12): тон 215° и насыщенность не трогаем, меняем только светлоту —
   64% → 44% в светлой теме (4.77) и 34% → 55% в тёмной (5.22). Приглушение
   сохраняется: рядом со своим месяцем (--text, 15.9) разница видна сразу. */
.cal-v2-cell.other-m .cal-v2-cell-num { color: #636E7E; }
[data-theme="dark"] .cal-v2-cell.other-m .cal-v2-cell-num { color: #7688A2; }

.cal-v2-cell-num {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; font-size: 13px; font-weight: 500; color:var(--text2); flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.cal-v2-cell.wknd .cal-v2-cell-num { color: #B91C1C; }
[data-theme="dark"] .cal-v2-cell.wknd .cal-v2-cell-num { color: #F87171; }
/* Ниже правила выходного намеренно: суббота и воскресенье бывают «сегодня», и
   до 16.08.2026 цифра в такой день оставалась красной на голубом — контраст
   1.76, замерено на стенде. */
/* Заливка кружка — --blue2, а не голубой #38BDF8: белым по голубому контраст
   2.14, по --blue2 — 6.35. В тёмной теме наоборот: голубая заливка и тёмный
   текст (свод, п. 12). */
.cal-v2-cell.today .cal-v2-cell-num,
.cal-v2-cell.today.wknd .cal-v2-cell-num { background: var(--blue2); color: #fff; font-weight: 600; }
[data-theme="dark"] .cal-v2-cell.today .cal-v2-cell-num,
[data-theme="dark"] .cal-v2-cell.today.wknd .cal-v2-cell-num { background: #38BDF8; color: var(--accent-text); }

.cal-v2-cell-events { display: flex; flex-direction: column; gap: 2px; flex: 1; overflow: hidden; }
/* Чип задачи: тип называет точка, а не заливка (ТЗ владельца 16.08.2026).
   Замер на боевом снимке: из 829 задач 825 — тип «Отпуск», то есть цветной фон
   стоял почти на каждом чипе и показывал норму, а не отличие (свод, п. 4).
   Заливку сохраняет только просроченное — его пропустить нельзя. */
.cal-v2-ev {
  display: flex; align-items: center; gap: 8px;
  border-radius: 8px; padding: 2px 4px; font-size: 11px; color: var(--text);
  white-space: nowrap; overflow: hidden; cursor: pointer;
  transition: background .12s;
}
.cal-v2-ev > i { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.cal-v2-ev > span { overflow: hidden; text-overflow: ellipsis; }
.cal-v2-ev:hover { background: var(--card2); }
/* Выполненное: зачёркнуто и приглушено до --text2. Прозрачности .55 больше нет —
   она роняла контраст ниже 2 (свод, п. 6). */
.cal-v2-ev.ev-done { color: var(--text2); text-decoration: line-through; }
.cal-v2-ev.ev-done > i { opacity: .5; }
/* ПЛАНОВЫЙ СРОК повторяющегося отчёта (21.08.2026). Записи с такой датой в
   данных нет — она посчитана вперёд по периодичности (homeReportPlanned).
   Отсюда и вид: контур вместо заливки. Настоящий срок остаётся плотным, план
   читается как «будет», а не «есть», и их не спутать.
   Прозрачностью не гасим: гашение в календаре уже занято словом «выполнено»
   (.ev-done, .done) — тот же приём во втором значении читался бы как «сдано». */
.cal-v2-ev.ev-plan { background: transparent; border: 1px dashed var(--border-strong, #CBD5E1); color: var(--text2); }
.cal-v2-ev.ev-plan > i { opacity: .55; }
/* Просрочено — единственная заливка в сетке. Слово на ней берёт затемнённую
   ступень того же тона: --red даёт 3.44, #B91C1C — 5.91; в тёмной теме
   ступень светлее (свод, п. 12). */
.cal-v2-ev.ev-late { background: var(--red-bg); color: #B91C1C; font-weight: 500; }
.cal-v2-ev.ev-late:hover { background: var(--red-bg); }
[data-theme="dark"] .cal-v2-ev.ev-late { color: #F87171; }
.cal-v2-ev-more { font-size: 11px; font-weight: 500; color: var(--text2); padding: 1px 4px; }

/* Полоса под сеткой, когда в открытом месяце задач нет: куда идти за ближайшими.
   flex-shrink: 0 — .cal-v2-main с overflow:hidden иначе сожмёт её в ноль, отдав
   всю высоту сетке. Кнопки внутри — существующий .cal-v2-today-btn, отдельного
   вида кнопки не заводим. */
/* ═══ ШАПКА, ПУСТОЙ МЕСЯЦ И ИТОГ (21.08.2026) ═══════════════════════════
   Приём «Структуры»: под названием — строка, отвечающая на вопрос. Одна мысль
   живёт в одном месте: шапка говорит о просроченном и ближайшем, карточка в
   сетке — о пустоте месяца, итог под сеткой — из чего месяц сложился.
   Размеры и насыщенности из свода (11/12/13/15/20, 400/500/600), цвета —
   токены и ступени слова, парами на обе темы (свод, п. 6 и 12). */
/* min-width:min-content, а не 0 (03.09.2026): при нуле блок ужимался до 70 px
   и срезал само название месяца, хотя уступать место должна строка-вывод под
   ним — у неё для этого есть многоточие. min-content здесь равен ширине
   заголовка, потому что он неразрывный (правило ниже). */
.cal-v2-head-t { display: flex; flex-direction: column; gap: 2px; min-width: min-content; }
/* Заголовок не переносим НИКОГДА: на окне 1100 px «17 – 23 августа 2026»
   ломалось на две строки и толкало кнопки вниз (замер 21.08.2026). Место
   уступает строка-вывод — она обрезается многоточием, а не заголовок. */
.cal-v2-month-title { white-space: nowrap; }
.cal-v2-head-sub {
  font-size: 12px; color: var(--text2); line-height: 1.45;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46ch;
}
.cal-v2-head-sub b { font-weight: 500; color: var(--text); }
/* Просроченное — той же ступенью красного, что и метки просрочки в сетке
   (.ev-late): 6.47 на светлой, 6.08 на тёмной. */
.cal-v2-late-w { color: #B91C1C; font-weight: 500; }
[data-theme="dark"] .cal-v2-late-w { color: #F87171; }

/* Сетка и карточка пустоты в одной системе координат: карточка ложится
   поверх сетки, а не под неё. Высота от родителя, без «окно минус число»
   (свод, п. 11). */
/* Колонка, а не ряд: сетка внутри должна занять всю ширину, иначе она
   становится flex-элементом по содержимому и разъезжается с шапкой дней
   недели (проверено на стенде 21.08.2026). */
.cal-v2-month-block { position: relative; flex: 1; display: flex; flex-direction: column; min-height: 0; }
.cal-v2-empty-wrap {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; pointer-events: none; padding: 16px;
}
/* Карточка кликабельна, сетка под ней — тоже (клик по дню заводит задачу),
   поэтому перехватывает события только сама карточка. */
.cal-v2-empty-card {
  pointer-events: auto; text-align: center; max-width: 400px;
  padding: 24px 26px 24px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-lg);
}
.cal-v2-empty-t { font-size: 15px; font-weight: 600; margin-top: 10px; }
.cal-v2-empty-s { font-size: 12px; color: var(--text2); line-height: 1.6; margin-top: 5px; }
.cal-v2-empty-a { margin-top: 16px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.cal-v2-empty-link {
  font: inherit; font-size: 12px; background: none; border: 0; padding: 0;
  cursor: pointer; color: var(--blue2);
}
[data-theme="dark"] .cal-v2-empty-link { color: var(--blue); }
.cal-v2-empty-link:hover { text-decoration: underline; }

.cal-v2-month-foot {
  flex-shrink: 0; margin-top: 10px; display: flex; align-items: baseline;
  gap: 12px; font-size: 12px; color: var(--text2); flex-wrap: wrap;
}
.cal-v2-month-foot b { font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums; }
.cal-v2-foot-sep { color: var(--text3); margin-left: 10px; }

/* Меню «⋯» в шапке календаря (21.08.2026): редкие кнопки на клик дальше,
   но никуда не пропали. */
.cal-v2-more { position: relative; }
/* 7, а не 8: у .cal-v2-today-btn padding 7px и min-height 34 — при 8 кнопка
   «⋯» выходила 35 и стояла на пиксель выше соседей (замер 03.09.2026). */
.cal-v2-more-b { padding: 7px 10px; }
.cal-v2-more-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  min-width: 180px; padding: 4px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-lg);
}
.cal-v2-more-menu.on { display: block; animation: moMenuIn .12s ease-out both; }
/* Меню появляется тем же способом, что и окна (23.08.2026): одна прозрачность,
   без подъёма — на 23 Гц 120 мс это три кадра, и сдвиг на них виден
   ступеньками. Тот же приём у меню строки в «Задачах» (#tbRowMenu). */
@keyframes moMenuIn { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cal-v2-more-menu.on { animation: none; } }
/* Меню строки в «Задачах» (создаётся из app-taskpage.js) — то же появление. */
.tb-row-menu { animation: moMenuIn .12s ease-out both; }
@media (prefers-reduced-motion: reduce) { .tb-row-menu { animation: none; } }
.cal-v2-more-i {
  display: block; width: 100%; text-align: left; font: inherit; font-size: 13px;
  padding: 8px 12px; border: 0; border-radius: 8px; background: none;
  color: var(--text); cursor: pointer;
}
.cal-v2-more-i:hover { background: var(--card2); }

/* Слово «просрочено» в шапке вкладки «Задачи» (22.08.2026) — та же ступень
   красного, что у просрочки в календаре и таблице: 6.47 на светлой, 6.08 на
   тёмной (свод, п. 12). */
.tp-late-w { color: #B91C1C; font-weight: 500; }
[data-theme="dark"] .tp-late-w { color: #F87171; }

/* Строка списка задач и доски: пересчёт запираем внутри строки. Их на экране
   десятки, и без этого изменение одной (наведение, уход, отметка) заставляло
   браузер мерить заново весь список — 8.9 мс на пересчёт при бюджете кадра
   16.7 мс (замер 22.08.2026). */
#tp-rows > div, #tp-rows .tb-vanish > div > div { contain: layout style paint; }

/* Группы ленты «Список» (21.08.2026) — заголовок группы и счёт в ней. */
.cal-v2-list-grp {
  font-size: 11px; font-weight: 500; color: var(--text2);
  padding: 16px 2px 8px; display: flex; align-items: center; gap: 8px;
}
.cal-v2-list-grp:first-child { padding-top: 2px; }
.cal-v2-list-grp.late { color: #B91C1C; }
[data-theme="dark"] .cal-v2-list-grp.late { color: #F87171; }
.cal-v2-list-grp-n { color: var(--text2); font-variant-numeric: tabular-nums; }
.cal-v2-list-when { font-size: 11px; color: var(--text2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.cal-v2-list-when.late { color: #B91C1C; font-weight: 500; }
[data-theme="dark"] .cal-v2-list-when.late { color: #F87171; }
.cal-v2-list-tail { text-align: center; font-size: 11px; color: var(--text2); padding: 16px 0 4px; }

.cal-v2-empty-hint {
  flex-shrink: 0; margin-top: 8px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; border-radius: 12px;
  background: var(--card2); border: 1px solid var(--border);
}
.cal-v2-eh-text { font-size: 13px; color: var(--text2); }
.cal-v2-eh-sp { flex: 1; }



/* ── НЕДЕЛЯ (компактная агенда по дням) ── */
.cal-week-agenda {
  flex: 1; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  width: 100%; max-width: 720px; margin: 0 auto;
}
.cal-week-row {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 16px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); transition: border-color .12s, background .12s;
}
.cal-week-row:hover { border-color: var(--act); }
.cal-week-row.wknd { background: var(--card2); }
.cal-week-row.today { border-color: #38BDF8; box-shadow: 0 0 0 1px #38BDF8 inset; }
.cal-week-daycol {
  flex-shrink: 0; width: 46px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.cal-week-dnum { font-size: 20px; font-weight: 600; color: var(--text); line-height: 1; font-variant-numeric: tabular-nums; }
.cal-week-row.wknd .cal-week-dnum { color: #B91C1C; }
[data-theme="dark"] .cal-week-row.wknd .cal-week-dnum { color: #F87171; }
.cal-week-row.today .cal-week-dnum { color: var(--blue2); }
[data-theme="dark"] .cal-week-row.today .cal-week-dnum { color: var(--blue); }
.cal-week-dname {
  font-size: 11px; font-weight: 500; color: var(--text2);
}
.cal-week-tasks {
  flex: 1; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  min-height: 30px;
}
.cal-week-empty { color: var(--text2); font-size: 12px; }
/* Тот же чип, что в месяце: тип — точкой, заливка только у просроченного. */
.cal-week-chip {
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
  padding: 4px 12px; border-radius: 8px;
  font-size: 12px; color: var(--text); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background .12s;
}
.cal-week-chip:hover { background: var(--card2); }
.cal-week-chip.ev-done { color: var(--text2); text-decoration: line-through; }
.cal-week-chip.ev-done .cal-week-chip-dot { opacity: .5; }
.cal-week-chip.ev-late { background: var(--red-bg); color: #B91C1C; font-weight: 500; }
.cal-week-chip.ev-late:hover { background: var(--red-bg); }
[data-theme="dark"] .cal-week-chip.ev-late { color: #F87171; }
.cal-week-chip-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }

/* ── СПИСОК ── */
.cal-v2-list { flex: 1; overflow-y: auto; }
.cal-v2-list-month {
  padding: 12px 16px; font-size: 13px; font-weight: 600; color:var(--text2);
  background: var(--card2); border-bottom: 1px solid var(--border);
  position: sticky; top: 0;
}
.cal-v2-list-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--card2);
  cursor: pointer; transition: background .12s;
}
.cal-v2-list-item:hover { background: var(--card2); }
.cal-v2-list-stripe {
  width: 4px; height: 38px; border-radius: 2px; flex-shrink: 0;
}
.cal-v2-list-date {
  width: 48px; text-align: center; flex-shrink: 0;
}
.cal-v2-list-day { font-size: 20px; font-weight: 600; color:var(--text); line-height: 1; font-variant-numeric: tabular-nums; }
.cal-v2-list-mo { font-size: 11px; font-weight: 500; color: var(--text2); }
.cal-v2-list-info { flex: 1; min-width: 0; }
.cal-v2-list-name { font-size: 13px; font-weight: 500; color:var(--text); }
.cal-v2-list-meta { font-size: 11px; color:var(--text2); margin-top: 2px; }
.cal-v2-list-tag {
  font-size: 11px; font-weight: 500; padding: 3px 12px;
  border-radius: 99px; background: var(--border); color:var(--text2); flex-shrink: 0;
}
/* Плашка «просрочено» — тот же оттенок слова, что у просроченного чипа в сетке. */
.cal-v2-list-tag.ev-late { background: var(--red-bg); color: #B91C1C; }
[data-theme="dark"] .cal-v2-list-tag.ev-late { color: #F87171; }
.cal-v2-list-empty {
  padding: 60px; text-align: center; color: var(--text2); font-size: 13px;
}

/* Адаптив колонок больше не нужен: колонка одна на любой ширине. Полоса
   фильтров над сеткой переносится сама (flex-wrap). */
/* ── Праздники в календаре ── */
.cal-v2-holiday-dot {
  font-size: 11px;
  margin-left: 2px;
  line-height: 1;
}

/* У праздника было три голоса разом: оранжевая заливка клетки, красная цифра и
   красная точка. Заливка убрана (ТЗ владельца 16.08.2026) — праздник и так
   приходит с классом wknd, то есть затенён как выходной, а красное остаётся:
   это нерабочий день, он не входит в отпуск (ст. 120 ТК). */


/* ═══ ПУСТОЕ СОСТОЯНИЕ — ОДИН ВИД НА ПОРТАЛ (разбор уровня 30.08.2026, шаг 4) ═══
   Разметку даёт emptyState() в app-core.js — там же записано, почему пустой
   экран отвечает на три вопроса, а не пишет «Нет данных». Здесь только вид.

   Размеры со шкалы свода (п. 2): заголовок 15, пояснение 13. Насыщенности две
   из трёх: 500 у заголовка, 400 у пояснения — жирного здесь нет.
   Ширина пояснения ограничена по СИМВОЛАМ (42ch), а не пикселями: строка в
   пустом состоянии короткая, и на широком экране она иначе растягивается на всю
   карточку в одну нитку — читать такую строку глазу не за что зацепиться. */
.lp-empty {
  display: flex; flex-direction: column; align-items: center;
  /* Отступы со шкалы 4 px: 40 сверху и снизу, 24 по бокам. Раньше у двадцати
     самодельных «пусто» здесь стояло 46/26, 30/16, 24/12 и так далее. */
  padding: 40px 24px;
  text-align: center;
  gap: 8px;
}
.lp-empty-t { font-size: 15px; font-weight: 500; color: var(--text); line-height: 1.35; }
.lp-empty-x {
  font-size: 13px; font-weight: 400; color: var(--text2);
  line-height: 1.55; max-width: 42ch;
}
.lp-empty-x b { font-weight: 500; color: var(--text); }
/* Кнопка отбивается сильнее текста: она не часть объяснения, а следующий шаг. */
.lp-empty-a { margin-top: 8px; }

/* ===== A1: видимый фокус для клавиатурной навигации ===== */
/* ПОЛЯ ВВОДА СЮДА БОЛЬШЕ НЕ ВХОДЯТ (25.08.2026) — см. следующий блок.
   Кольцо остаётся кнопкам, ссылкам и пунктам меню: у них своего признака
   фокуса нет. */
[data-kbd]:focus-visible,
.nav-item:focus-visible,
.theme-seg-btn:focus-visible,
.app-tb-btn:focus-visible,
button:focus-visible,
a:focus-visible {
  /* Цвет — токен портала, а не #38BDF8 числом: тот бирюзовый нигде больше не
     живёт, и кольцо им выглядело чужим (жалоба владельца 24.08.2026 —
     «строки обходятся бирюзовым толстым слоем»). */
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}
/* border-radius здесь БОЛЬШЕ НЕ ЗАДАЁМ. Он менял форму самого элемента в момент
   фокуса: поле поиска со скруглением 20 при щелчке скачком становилось 8 — это
   и читалось как «строка округляется, когда ставишь курсор». Обводка обязана
   повторять форму элемента, а не назначать её. */

/* ═══ ОДНО КОЛЬЦО НА ПОЛЕ, И ЭТО ЕГО СОБСТВЕННАЯ РАМКА ═══
 *
 * 24.08.2026 второе кольцо сняли перечислением: .fi, .fs, .global-search-input,
 * .dp-field. Список не мог быть полным по своей природе — поля есть и в
 * модулях, которые заводят свои классы (.ep-input в выборе сотрудника, поля
 * поиска в задачах и инструкциях), и каждое новое поле возвращало двойную
 * обводку. Владелец нашла её снова 25.08.2026 сразу в шести местах.
 *
 * Теперь правило общее и не требует сопровождения: у поля ввода фокус
 * показывает СВОЯ рамка (плюс мягкий ореол, если модуль его задал), а общая
 * обводка со сдвигом полю не достаётся вовсе. Кнопкам и ссылкам она остаётся —
 * там своего признака нет.
 *
 * border-color задаём и здесь: если у поля своего правила фокуса нет, оно всё
 * равно должно отзываться на курсор. Поля со своим правилом перебьют эту
 * строку своей специфичностью — как и было. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--blue);
}

/* ===== ГЛАВНАЯ ТАБЛИЦА УЧЁТА: фикс-раскладка + адаптив (Задача 4) =====
   table-layout:fixed + процентные ширины столбцов (заданы в app-table.js):
   таблица всегда занимает 100% контейнера и НЕ уходит в горизонтальную
   прокрутку, а скрытие столбцов отдаёт освободившееся место оставшимся.
   Ячейки стилизованы инлайн, поэтому часть правил с !important. Скоуп
   #tblScroll — только главная таблица (вкладку «График 1С» не трогаем). */
#tblScroll table{ table-layout:fixed; width:100%; }
/* Плавность прокрутки виртуализированной таблицы (много строк):
   • overflow-anchor:none — при подмене окна строк (tbody.innerHTML) браузер не
     пытается «якорить» видимый элемент и не дёргает позицию скролла;
   • overscroll-behavior:contain — прокрутка не «протекает» на страницу у краёв;
   • -webkit-overflow-scrolling:touch — инерционная прокрутка на трекпаде/тач.
   Изолируем содержимое, чтобы reflow при перерисовке окна не задевал остальную
   страницу (contain на самом контейнере безопасен для table-layout:fixed). */
#tblScroll{
  overflow-anchor:none;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  contain:layout paint;
  /* ПОЛОСЫ ПРОКРУТКИ ВИДНЫ ВСЕГДА (25.08.2026). При большом числе строк таблица
     получает min-width:1180 и уезжает вправо (app-table.js: так задумано —
     колонки не сжимаются, как в Google-таблицах). Но в macOS полоса прокрутки
     по умолчанию всплывающая: она невидима, пока не крутишь, и на окне 1280
     последняя колонка выглядела не «прокручиваемой», а обрезанной — замер:
     таблица 1180 при области 1010, то есть 170 px спрятано без единого намёка.
     Явная полоса стоит 8 px и превращает «обрезано» в «здесь ещё есть». */
  scrollbar-width:thin;
  scrollbar-color:var(--border) transparent;
}
/* Обёртка держит тень правого края НЕПОДВИЖНО: псевдоэлемент самой
   прокручиваемой коробки уехал бы вместе со строками. Обёртка — flex-элемент
   карточки вместо прежнего #tblScroll, поэтому забирает его flex:1 и min-height,
   иначе область строк перестала бы тянуться на всю высоту.
   Тень видна всегда, а не по состоянию: держать состояние ради 8 px градиента —
   лишний механизм, а на краю таблицы тень читается как край панели и не мешает,
   даже когда прокрутка докручена до конца. */
.tbl-sc-wrap{ position:relative; flex:1; min-height:0; display:flex; }
.tbl-sc-wrap::after{
  content:''; position:absolute; top:0; bottom:0; right:0; width:18px;
  background:linear-gradient(to right, rgba(15,23,42,0), rgba(15,23,42,.11));
  pointer-events:none; border-radius:0 12px 12px 0;
}
[data-theme="dark"] .tbl-sc-wrap::after{
  background:linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,.28));
}
/* Инпуты/селекты прокручиваются внутри своей ячейки, а не тянут колонку вширь. */
#tblScroll input, #tblScroll select{ min-width:0; max-width:100%; }
/* Текстовая ячейка «Вид» переносится по словам вместо обрезки в строку.
   Заголовки НЕ переносим: текст+стрелка живут в inline-flex (см. _renderTHead),
   длинный заголовок обрезается троеточием — так шапка ровная и не «скачет». */
#tblScroll td[data-col="vacType"]{ white-space:normal !important; }

/* Приоритет читаемости по ТЗ: Сотрудник, Начало, Окончание, Дней, Вид —
   остаются; менее важные столбцы скрываются по мере сужения экрана, чтобы
   ключевые данные читались без горизонтальной прокрутки. */

/* Узкий десктоп / планшет-ландшафт: прячем самые «дешёвые» по смыслу столбцы. */
@media (max-width: 1150px){
  #tblScroll [data-col="num"],
  #tblScroll [data-col="source"],
  #tblScroll [data-col="comment"]{ display:none !important; }
}
/* Небольшой ноутбук: дополнительно прячем Приказ (1С) и Перенос, а боковые
   паддинги ячеек ужимаем — иначе в узких колонках дата (ДД.ММ.ГГГГ + иконка
   календаря) не помещается и год обрезается. */
@media (max-width: 950px){
  #tblScroll [data-col="orderNum"],
  #tblScroll [data-col="transfer"]{ display:none !important; }
  #tblScroll th, #tblScroll td{ padding-left:12px !important; padding-right:12px !important; }
  #tblScroll td input, #tblScroll td select{ padding-left:10px !important; padding-right:4px !important; }
}
/* Узкий экран / планшет-портрет: остаются ключевые столбцы (Сотрудник,
   Начало, Окончание, Дней, Вид). Примечание/Статус сворачиваем, шрифт мельче. */
@media (max-width: 820px){
  #tblScroll [data-col="note"]{ display:none !important; }
  #tblScroll th, #tblScroll td{ font-size:12px !important; }
}

/* ================================================================
   РЕДИЗАЙН МОДАЛКИ КАЛЕНДАРЯ СОТРУДНИКА (2026-07) — ТОЛЬКО ВИЗУАЛ.
   Идёт в паре с правками showEmpCal() в app-calendar.js. Логика
   статусов/дат/переносов не менялась. Откат: удалить этот блок +
   вернуть соответствующие куски в app-calendar.js.
   ================================================================ */
:root{ --holiday-bg:#FEE2E2; }

/* Спокойная светлая шапка вместо яркого синего градиента (ФИО не кричит) */
.emp-cal-header{ background:var(--card); color:var(--text); border-bottom:1px solid var(--border); }
.emp-cal-header-left h3{ color:var(--text); font-size:15px; font-weight:600; letter-spacing:-.1px; }
.emp-cal-header-left .emp-cal-subtitle{ color:var(--text3); opacity:1; }
.emp-cal-stat{ background:var(--card2); border:1px solid var(--border); }
.emp-cal-stat .val{ color:var(--text); }
.emp-cal-stat .lbl{ color:var(--text2); opacity:1; }
.emp-cal-close{ background:var(--card); color:var(--text3); border:1px solid var(--border); }
.emp-cal-close:hover{ background:var(--card2); color:var(--text2); }

/* Праздник во время отпуска — маленькая красная точка-пометка */
.emp-cal-hol-dot{ position:absolute; top:1px; right:2px; width:4px; height:4px; border-radius:50%; background:var(--red); }

/* Компактная подпись про праздники и штриховку (вместо полной легенды) */
.emp-cal-grid-hint{ display:flex; align-items:center; gap:8px; justify-content:flex-end; font-size:11px; color:var(--text3); margin:-8px 0 16px; flex-wrap:wrap; }
.emp-cal-grid-hint .sw{ width:12px; height:12px; border-radius:3px; background:var(--holiday-bg); border:1px solid #FCA5A5; }
.emp-cal-grid-hint .sw-hatch{ background-color:#FCFCFD; border:1px solid rgba(100,116,139,.28);
  background-image:repeating-linear-gradient(45deg, rgba(100,116,139,.34) 0 2px, transparent 2px 5px); }
[data-theme="dark"] .emp-cal-grid-hint .sw-hatch{ background-color:var(--card2); border-color:rgba(203,213,225,.22);
  background-image:repeating-linear-gradient(45deg, rgba(203,213,225,.28) 0 2px, transparent 2px 5px); }

/* ОТКУДА ОТПУСК ПЕРЕНЕСЁН (макет согласован владельцем 06.08.2026).
   Пунктирная оранжевая рамка и точка внизу: «отпуск отсюда уехал». Заливки нет
   намеренно — залитый день снова читался бы как отпуск, которого не было
   (от этого ушли 21.07.2026, когда перестали проецировать исходные даты). */
.emp-cal-day.ecd-moved{
  border:1px dashed var(--orange);
  border-radius:4px;
}
.emp-cal-day.ecd-moved::after{
  content:''; position:absolute; left:50%; bottom:1px; transform:translateX(-50%);
  width:3px; height:3px; border-radius:50%; background:var(--orange);
}
/* Метки легенды: перенесённый отпуск и день, откуда он перенесён. */
.emp-cal-grid-hint .sw-tr{ background:var(--orange-bg); border:1px solid var(--orange); }
.emp-cal-grid-hint .sw-moved{ background:transparent; border:1px dashed var(--orange); }
/* «Отпуск не состоялся» — красный ПУНКТИР, как у перенесённого дня, только цвет
   другой (владелец 08.08.2026: сплошная линия слишком ярко). Пунктир здесь общий
   язык «отпуска на этих датах не было», а цвет отвечает на «почему»: оранжевый —
   уехал на другие даты, красный — решения нет. */
.emp-cal-grid-hint .sw-notdone{ background:transparent; border:1px dashed var(--red); }

/* Строка «Перенесён с / на» в карточке-подсказке дня. */
.cal-day-tip .cdt-moved{
  margin-top:8px; font-size:12px; line-height:1.45; color:#78350F;
  background:var(--orange-bg); border:1px solid var(--orange); border-radius:8px; padding:8px 8px;
}
.cal-day-tip .cdt-moved b{ font-weight:600; }
.cal-day-tip .cdt-type.cdt-moved-type{ background:var(--orange-bg); color:#78350F; }
[data-theme="dark"] .cal-day-tip .cdt-moved{
  background:rgba(245,158,11,.14); border-color:rgba(245,158,11,.45); color:#FCD34D;
}
[data-theme="dark"] .cal-day-tip .cdt-type.cdt-moved-type{
  background:rgba(245,158,11,.14); color:#FCD34D;
}

/* ОТПУСК НЕ СОСТОЯЛСЯ (ТЗ владельца 08.08.2026) — тот же приём, что у переноса,
   только красный: дата наступила, а решения нет. У переноса и отмены вопрос уже
   закрыт, поэтому они спокойные; красный здесь один и зовёт. */
.cal-day-tip .cdt-fail{
  margin-top:8px; font-size:12px; line-height:1.45; color:#7F1D1D; font-weight:600;
  background:var(--red-bg); border:1px solid var(--red); border-radius:8px; padding:8px 8px;
}
.cal-day-tip .cdt-type.cdt-fail-type{ background:var(--red-bg); color:#7F1D1D; }
/* Строка «что делать»: подсказка, а не кнопка — карточка остаётся некликабельной. */
.cal-day-tip .cdt-todo{ margin-top:8px; font-size:11px; line-height:1.45; color:var(--text3); }
[data-theme="dark"] .cal-day-tip .cdt-fail{
  background:rgba(239,68,68,.14); border-color:rgba(239,68,68,.45); color:#FCA5A5;
}
[data-theme="dark"] .cal-day-tip .cdt-type.cdt-fail-type{
  background:rgba(239,68,68,.14); color:#FCA5A5;
}

/* ОТПУСК НЕ СОСТОЯЛСЯ В СЕТКЕ ГОДА («вариант А», решение владельца 08.08.2026).
   Пустая клетка с пунктирным контуром: заливка на всём портале значит «дни
   потрачены», а здесь они не потрачены — человек в отпуск не уходил. Поэтому
   именно контур, а не ещё один цвет. Заливку app-calendar.js для этого статуса
   не выводит (calBg:transparent), иначе inline-стиль перекрыл бы фон отсюда.

   Линия — ПУНКТИР, как у дня, откуда отпуск перенесён (владелец 08.08.2026:
   сплошная рамка получилась слишком яркой). Пунктир на этой сетке уже значит
   «отпуска на этих датах не было» — и здесь ровно тот же смысл; отличается
   только цвет: оранжевый — уехал на другие даты, красный — решения нет. */
.emp-cal-day.ecd-notdone{
  background-color:transparent;
  border:1px dashed var(--red);
  border-radius:4px;
  color:var(--red);
}
[data-theme="dark"] .emp-cal-day.ecd-notdone{
  background-color:transparent;
  border-color:rgba(239,68,68,.7);
  color:#FCA5A5;
}

/* ОТСУТСТВИЕ ВНЕ НОРМЫ 28 ДНЕЙ (ТЗ владельца 30.07.2026) — без сохранения,
   учебный, донорский. Цвет остаётся осью «статус», штриховка — второй осью
   «расходует норму или нет». Заливку клетки в этом случае app-calendar.js не
   выводит, иначе inline-стиль перекрыл бы фон отсюда. */
.emp-cal-day.ecd-offnorm{
  background-color:#FCFCFD;
  background-image:repeating-linear-gradient(45deg, rgba(100,116,139,.30) 0 2px, transparent 2px 6px);
  box-shadow:inset 0 0 0 1px rgba(100,116,139,.18);
}
/* В тёмной теме белая клетка была бы дырой: подложка — карточная, полосы светлее фона. */
[data-theme="dark"] .emp-cal-day.ecd-offnorm{
  background-color:var(--card2);
  background-image:repeating-linear-gradient(45deg, rgba(203,213,225,.24) 0 2px, transparent 2px 6px);
  box-shadow:inset 0 0 0 1px rgba(203,213,225,.16);
}

/* Карточка-подсказка при наведении на день (вместо системного title) */
.cal-day-tip{
  position:fixed; z-index:4000; width:252px; background:var(--card);
  border:1px solid var(--border); border-radius:12px;
  box-shadow:0 10px 15px -3px rgba(0,0,0,.08), 0 4px 6px -4px rgba(0,0,0,.06);
  padding:12px 16px; pointer-events:none; opacity:0; transform:translateY(4px);
  transition:opacity .12s ease, transform .12s ease;
}
.cal-day-tip.show{ opacity:1; transform:none; }
.cal-day-tip .cdt-v + .cdt-v{ margin-top:11px; padding-top:12px; border-top:1px solid var(--border); }
/* Имя сотрудника — только в подсказке диаграммы «Отпуска»: там людей много.
   В календаре открыт один человек, и повторять его имя незачем (08.08.2026). */
.cal-day-tip .cdt-emp{ font-size:13px; font-weight:600; color:var(--text); margin-bottom:10px;
  padding-bottom:9px; border-bottom:1px solid var(--border); line-height:1.3; }
.cal-day-tip .cdt-type{ display:inline-block; padding:3px 8px; border-radius:99px; font-size:11px; font-weight:600; }
.cal-day-tip .cdt-dates{ font-size:13px; font-weight:600; color:var(--text); margin:9px 0 1px; letter-spacing:-.1px; }
.cal-day-tip .cdt-sub{ font-size:12px; color:var(--text3); }
.cal-day-tip .cdt-st{ display:flex; align-items:center; gap:8px; margin-top:10px; padding-top:8px;
  border-top:1px solid var(--border); font-size:12px; color:var(--text2); }
.cal-day-tip .cdt-st .dot{ width:7px; height:7px; border-radius:50%; flex-shrink:0; }
.cal-day-tip .cdt-norm{ margin-top:9px; font-size:12px; line-height:1.45; color:var(--text2);
  background:var(--card2); border-radius:8px; padding:8px 8px; }
.cal-day-tip .cdt-norm b{ color:var(--text); font-weight:600; }
.cal-day-tip .cdt-ord{ margin-top:8px; font-size:12px; color:var(--text3); display:flex; align-items:center; gap:8px; }
.cal-day-tip .cdt-ord svg{ flex-shrink:0; }
.cal-day-tip .cdt-hol{ margin-top:8px; font-size:12px; color:var(--red); display:flex; align-items:center; gap:8px; }
.cal-day-tip .cdt-hol .sq{ width:9px; height:9px; border-radius:2px; background:var(--holiday-bg);
  border:1px solid #FCA5A5; flex-shrink:0; }

/* Группы списка отпусков — сворачиваемые плашки без стикеров */
.evc-group{ margin-bottom:10px; }
.evc-group-head{ display:flex; align-items:center; gap:12px; cursor:pointer; user-select:none; background:var(--card); border:1px solid var(--border); border-radius:var(--r3); padding:12px 16px; transition:border-color .15s; }
.evc-group-head:hover{ border-color:var(--text3); }
.evc-group-head .chev{ font-size:11px; color:var(--text2); transition:transform .2s; flex-shrink:0; }
.evc-group.open > .evc-group-head .chev{ transform:rotate(90deg); }
.evc-group-head .gt{ font-size:13px; font-weight:500; color:var(--text); }
.evc-group-head .gc{ font-size:11px; font-weight:500; color:var(--text2); background:var(--card2); border-radius:99px; padding:1px 8px; font-variant-numeric:tabular-nums; }
.evc-group-head.actual{ border-color:#BFDBFE; background:var(--blue-bg); }
.evc-group-head.actual .gt{ color:var(--blue2); }
.evc-group-head.actual .gc{ background:rgba(37,99,235,.12); color:var(--blue2); }
.evc-group-note{ margin-left:auto; font-size:11px; color:var(--text2); }
.evc-group-body{ max-height:0; overflow:hidden; transition:max-height .3s ease; }
.evc-group.open > .evc-group-body{ max-height:8000px; }
.evc-group-inner{ padding-top:8px; }

/* ===== ОКНО СВЕРКИ С ГРАФИКОМ 1С (ТЗ 21.07.2026) =====
   Рабочий экран, а не диалог: широкая модалка с закреплёнными шапкой и подвалом,
   прокручивается только список. Визуальный язык общий с остальным порталом —
   KPI-карточка с цветной полоской, статус-точки, тёмная главная кнопка. */
/* Подпись рядом с переключателем юрлица. Живёт здесь, а не в стилях страницы
   сверок: «Обзор» открывается ещё и модалкой из других мест, и там стили
   страницы не подключены (урок производственного календаря 16.08.2026 —
   правило для элемента, видимого вне окна, не должно жить в стилях окна). */
.sv-orglbl { font-size:12px; color: var(--text2); }

.sc-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.sc-head { padding: 24px 26px 0; flex-shrink: 0; }
.sc-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.sc-title { margin: 0; font-size:15px; font-weight: 600; }
.sc-sub { font-size:12px; color: var(--text2); margin-top: 4px; line-height: 1.5; }
.sc-sub b { font-weight: 500; color: var(--text); }
.sc-note {
  margin: 14px 0 0; padding: 12px 16px; border-radius: 12px;
  background: var(--card2); border: 1px solid var(--border);
  font-size:12px; color: var(--text2); line-height: 1.6;
}
/* Вкладки-KPI: цифра крупная, подпись мелкая, слева полоска категории. */
.sc-tabs { display: flex; gap: 12px; margin: 16px 0 14px; flex-wrap: wrap; }
.sc-tab {
  flex: 1; min-width: 140px; text-align: left; cursor: pointer;
  padding: 12px 16px 12px 16px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--border);
  border-left: 3px solid var(--tab-color, var(--border2, #DCE3EC));
  font-family: inherit; transition: all .16s; position: relative;
}
.sc-tab:hover { background: var(--card2); }
/* Выбранная вкладка-KPI была ТЁМНОЙ ЗАЛИВКОЙ — в портале такого не осталось
   нигде, кроме поверхностей и формы входа (решение 16.08.2026). */
.sc-tab.on { background: var(--act-bg); border-color: var(--act); }
.sc-tab.on .sc-tab-val, .sc-tab.on .sc-tab-lbl { color: var(--act); }
[data-theme="dark"] .sc-tab.on .sc-tab-val, [data-theme="dark"] .sc-tab.on .sc-tab-lbl { color: var(--act-hover); }
.sc-tab-val { font-size:20px; font-weight: 600; line-height: 1; color: var(--text); }
.sc-tab-val.zero { color: var(--text2); }
.sc-tab-lbl { font-size:12px; font-weight: 500; color: var(--text2); margin-top: 5px; }
/* Тело: единственная прокручиваемая часть окна. */
.sc-body { flex: 1; min-height: 0; overflow-y: auto; border-top: 1px solid var(--border); }
.sc-hint { padding: 11px 26px; background: var(--card2); font-size:12px; color: var(--text2); line-height: 1.6; }
.sc-row {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 26px; border-bottom: 1px solid var(--border); transition: background .12s;
}
.sc-row:hover { background: var(--card2); }
.sc-row-main { flex: 1; min-width: 0; }
.sc-emp { font-size:13px; font-weight: 500; color: var(--text); }
.sc-meta { font-size:12px; color: var(--text2); margin-top: 3px; line-height: 1.5; }
.sc-acts { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }
/* Статус-точка вместо цветного бейджа — как в остальных вкладках портала. */
.sc-dot { display: inline-flex; align-items: center; gap: 8px; font-size:12px; font-weight: 500; color: var(--text2); white-space: nowrap; }
.sc-dot::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--dot, var(--text3)); flex-shrink: 0; }
.sc-empty { padding: 46px 26px; text-align: center; color: var(--text2); font-size:13px; line-height: 1.7; }
.sc-empty-icon { font-size:20px; margin-bottom: 10px; opacity: .5; }
.sc-foot {
  flex-shrink: 0; padding: 12px 26px; border-top: 1px solid var(--border);
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap; background: var(--card2);
}

/* ПОЛЯ ТЕЛА В «ПРИЁМКЕ ГРАФИКА НА ГОД» (30.08.2026).
   У .sc-body полей нет намеренно: в сверках его наполняют .sc-row, и отступ
   26px задаёт каждая строка сама — тогда полоса подсветки строки при наведении
   доходит до края окна. Приёмка строк не рисует, у неё карточки дел, и без
   собственных полей они упирались в самый край: шапка отступала на 26px,
   карточки — на 0 (замер на стенде: окно 240…1200, карточка 240…1200).
   Поэтому поля свои, у обёртки, а общий .sc-body не трогаем — на нём живут
   ещё четыре окна сверок. */
.py-body { padding: 16px 26px 24px; }
@media (max-width: 720px){
  .sc-head, .sc-row, .sc-foot, .sc-hint { padding-left: 16px; padding-right: 16px; }
  .py-body { padding-left: 16px; padding-right: 16px; }
  .sc-tab { min-width: 116px; }
  .sc-row { align-items: flex-start; flex-wrap: wrap; }
}

/* ═══ РЕЕСТР СВЕРКИ (ТЗ 26.07.2026) ══════════════════════════════════════════
   Шапка компактная: в ней только то, чем управляют. Всё объясняющее — в
   «Сводке» и «⋯». Тело — таблица, где три источника видны одновременно. */
.reg-wrap{ position:relative; }
.reg-head{ flex-shrink:0; padding:16px 24px 0; }
.reg-row1{ display:flex; align-items:center; gap:12px; margin-bottom:10px; flex-wrap:wrap; }
.reg-title{ font-size:15px; font-weight:600; white-space:nowrap; }
.reg-search{
  font:inherit; font-size:12px; padding:8px 12px; border-radius:8px; width:210px;
  border:1px solid var(--border); background:var(--card2); color:var(--text);
}
.reg-sum{
  margin-bottom:10px; padding:12px 16px; border-radius:12px;
  background:var(--card2); border:1px solid var(--border);
  font-size:12px; color:var(--text2); line-height:1.6;
}
.reg-reasons{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px; }

/* таблица реестра */
/* Плотная строка (26.07.2026): подписи источников — только в шапке, даты
   короткие, действие одной кнопкой. Так таблица влезает в окно без прокрутки. */
/* ═══ КАРКАС РЕЕСТРА: МЕНЮ СЛЕВА, СПИСОК СПРАВА ═══════════════════════════════
   ТЗ владельца 29.07.2026, вариант макета «тихая таблица». Раньше над таблицей
   стояли три яруса подряд — состояния, чипы причин, панель фильтров, — и до
   первой строки взгляд проходил половину экрана. Теперь состояния и причины в
   узком меню слева, а над списком остаются только поиск и фильтры. */
.reg-body{ display:flex; flex:1; min-height:0; }
.reg-main{ flex:1; min-width:0; display:flex; flex-direction:column; }
.reg-nav{
  width:236px; flex-shrink:0; border-right:1px solid var(--border);
  padding:12px 12px 14px 16px; overflow-y:auto;
  display:flex; flex-direction:column; gap:2px;
}
/* «Что сейчас происходит»: на каких выгрузках построена сверка. Переехало из
   контекстной строки над таблицей — там оно читалось как сноска. */
.reg-now{
  border:1px solid var(--border); border-radius:12px; background:var(--card2);
  padding:8px 12px; margin-bottom:6px;
}
.reg-now .t{ font-size:11px; font-weight:600; color:var(--text2); }
.reg-now .s{ display:flex; justify-content:space-between; gap:8px; font-size:11px; color:var(--text2); margin-top:5px; }
.reg-now .s b{ color:var(--text2); font-weight:500; font-variant-numeric:tabular-nums; }
.reg-now .s .warn{ color:var(--amber, #E8A317); font-weight:500; }
.reg-now .reg-upd{ width:100%; margin-top:8px; justify-content:center; font-size:12px; }
.reg-nsec{
  font-size:11px; font-weight:600;
  color:var(--text2); margin:14px 4px 5px;
}
.reg-nsec:first-of-type{ margin-top:4px; }
.reg-ni{
  display:flex; align-items:center; gap:8px; width:100%; text-align:left;
  border:0; background:none; border-radius:8px; padding:8px 8px; cursor:pointer;
  font:inherit; font-size:13px; font-weight:600; color:var(--text2);
}
.reg-ni:hover{ background:var(--card2); }
.reg-ni.on{ background:var(--accent, #0F172A); color:var(--accent-text, #fff); }
.reg-ni .n{ margin-left:auto; font-size:11px; font-weight:600; color:var(--text2); }
.reg-ni.on .n{ color:rgba(255,255,255,.72); }
/* Причины — вложенным списком внутри выбранного состояния, а не отдельным ярусом. */
.reg-ni.sub{ font-size:12px; font-weight:500; padding:5px 8px 4px 24px; }
.reg-ni.sub.on{ background:var(--card2); color:var(--text); font-weight:500; }
.reg-ni.sub.on .n{ color:var(--text2); }
.reg-nd{ width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.reg-nd.err{ background:var(--red, #DC3D43); }
.reg-nd.warn{ background:var(--amber, #E8A317); }
.reg-nd.ok{ background:var(--green, #1F9D5B); }

/* Разделители списка: следуют за сортировкой — месяц или буква алфавита. */
.reg-div{
  display:flex; align-items:center; gap:12px; padding:12px 24px 4px;
  font-size:11px; font-weight:600; color:var(--text2);
}
.reg-div .ln{ flex:1; height:1px; background:var(--border); }
.reg-div .c{ font-weight:500; }

/* Кнопка РЕШЕНИЯ в реестре была синей заливкой отдельным правилом (ТЗ владельца
   29.07.2026: «где принимается решение — не чёрное»). Требование выполнено самой
   ролью: с 16.08.2026 действие во всём портале светло-синее, и отдельное правило
   стало лишним — оно только рассинхронизировало реестр с остальными сверками.
   Оставлена одна строка: в реестре решение чуть заметнее рамкой. */
.reg-body .ec-btn.p{ border-color:var(--act); }

/* Чип «Только новые»: срез поверх любого списка. */
.reg-newchip{ display:inline-flex; align-items:center; gap:8px; }
.reg-newchip .rd{ width:7px; height:7px; border-radius:50%; background:var(--blue, #3B82F6); }
.reg-newchip .n{ font-weight:600; opacity:.7; }
.reg-newchip.on{
  background:var(--blue-bg, #EFF6FF); border-color:#BFDBFE; color:var(--blue2, #2563EB);
}
.reg-newchip.on .n{ opacity:1; }
/* Точки «новое с импорта» напротив фамилии БОЛЬШЕ НЕТ (ТЗ владельца 29.07.2026).
   На боевых данных новым оказывается почти всё — 471 строка из 481, — и точки
   стояли у каждой строки подряд: сигналом это быть перестало, а рябь осталась.
   Что нового, показывает чип «Только новые»: он и считает, и отбирает. */

/* ═══ ПАНЕЛЬ РАЗБОРА ОТПУСКА (app-reg-panel.js) ══════════════════════════════
   ТЗ владельца 29.07.2026: разбор одного отпуска — справа, а не раскрытием
   строки. Список слева остаётся на месте и не прыгает. */
.reg-panel{
  width:402px; flex-shrink:0; border-left:1px solid var(--border);
  background:var(--card2); display:flex; flex-direction:column; min-height:0;
}
.rp-head{ padding:12px 16px 12px; border-bottom:1px solid var(--border); background:var(--card); }
.rp-top{ display:flex; align-items:flex-start; gap:8px; }
/* Шкалы панели приведены к своду 17.08.2026. До этого здесь жили вес 800,
   заглавные с трекингом у подписей блоков и --text3 под текстом: подпись
   «ЧТО ГДЕ СТОИТ» давала 2.31, отдел под фамилией — 2.00. */
.rp-nm{ flex:1; min-width:0; font-size:15px; font-weight:600; line-height:1.25; }
.rp-nm .p1{ color:var(--text); } .rp-nm .p2{ color:var(--text2); font-weight:400; }
.rp-nm .ln{ font-weight:500; }
.rp-sub{ font-size:12px; color:var(--text2); margin-top:3px; }
.rp-nb{
  width:24px; height:24px; flex-shrink:0; border-radius:8px; cursor:pointer;
  border:1px solid var(--border); background:var(--card); color:var(--text2);
  font:inherit; font-size:12px; line-height:1;
}
.rp-nb:hover{ color:var(--text); border-color:var(--border2, #D6DDE6); }
.rp-body{ flex:1; overflow-y:auto; padding:0 16px 16px; min-height:0; }
/* Отступы блоков ужаты 17.08.2026: на шести блоках панели они съедали 168 px из
   948 — почти пятую часть высоты, и «Что сделать» уходило под сгиб. Содержание
   не тронуто, ужат только воздух между блоками. */
.rp-blk{ padding:12px 0; border-bottom:1px solid var(--border); }
.rp-blk:last-child{ border-bottom:0; }
.rp-bt{
  font-size:12px; font-weight:500; color:var(--text2); margin-bottom:6px;
}
.rp-hint{ font-size:12px; color:var(--text2); line-height:1.5; }
.rp-per{ font-size:15px; font-weight:600; margin-top:6px; font-variant-numeric:tabular-nums; }
.rp-per .d{ display:block; font-size:12px; font-weight:400; color:var(--text2); margin-top:2px; }
.rp-rsn{ display:inline-flex; align-items:center; font-size:13px; font-weight:500; border-radius:8px; padding:4px 12px; margin-bottom:7px; }
/* Слово на цветной заливке берёт ступень тона (свод, п. 12): сами --red и
   --green на своих подложках дают 3.4 и 2.9. */
.rp-rsn.err{ background:var(--red-bg, #FEF2F2); color:#B91C1C; }
.rp-rsn.warn{ background:var(--amber-bg, #FEF9C3); color:#B45309; }
.rp-rsn.idea{ background:var(--blue-bg, #EFF6FF); color:var(--blue2, #2563EB); }
.rp-rsn.ok{ background:var(--green-bg, #F0FDF4); color:#15803D; }
[data-theme="dark"] .rp-rsn.err{ color:#F87171; }
[data-theme="dark"] .rp-rsn.warn{ color:var(--orange); }
[data-theme="dark"] .rp-rsn.idea{ color:var(--act-hover); }
[data-theme="dark"] .rp-rsn.ok{ color:#4ADE80; }
.rp-acts{ display:flex; flex-wrap:wrap; gap:8px; }
.rp-acts.col{ flex-direction:column; align-items:stretch; }
.rp-lnk{
  display:block; width:100%; text-align:left; border:0; background:none; cursor:pointer;
  padding:4px 0; font:inherit; font-size:12px; color:var(--text2);
  border-bottom:1px dashed transparent;
}
.rp-lnk:hover{ color:var(--text); border-bottom-color:var(--border2, #D6DDE6); }
.rp-lnk span{ color:var(--text2); font-size:12px; margin-left:6px; }
/* Лента этапов: как отпуск дошёл до нынешнего состояния. */
.rp-tl{ position:relative; padding-left:16px; }
.rp-tl:before{ content:''; position:absolute; left:4px; top:5px; bottom:5px; width:1px; background:var(--border2, #D6DDE6); }
.rp-st{ position:relative; padding:3px 0; font-size:12px; color:var(--text2); }
.rp-st:before{
  content:''; position:absolute; left:-15px; top:9px; width:7px; height:7px; border-radius:50%;
  background:var(--border2, #D6DDE6); border:2px solid var(--card2);
}
.rp-st.now:before{ background:var(--text); }
.rp-st.tr:before{ background:#B45309; }
.rp-st.tr{ color:#B45309; font-weight:500; }
[data-theme="dark"] .rp-st.tr{ color:var(--orange); }
.rp-st.off{ color:var(--text2); text-decoration:line-through; }
.rp-st .w{ color:var(--text2); font-size:12px; margin-left:6px; }
/* Выбор «чьи даты верные» — решение в один клик, а не в два. */
.rp-opts{ display:flex; gap:8px; flex-wrap:wrap; }
.rp-opt{
  flex:1; min-width:150px; text-align:left; cursor:pointer; font:inherit;
  border:1px solid var(--border2, #D6DDE6); border-radius:8px; background:var(--card); padding:8px 12px;
}
.rp-opt:hover{ border-color:var(--blue2, var(--act)); background:var(--blue-bg, #EFF6FF); }
.rp-opt .src{ font-size:12px; font-weight:500; color:var(--text2); }
.rp-opt:hover .src{ color:var(--blue2, var(--act)); }
.rp-opt .dt{ font-size:13px; font-weight:500; font-variant-numeric:tabular-nums; margin-top:3px; line-height:1.35; }
.rp-opt .ex{ font-size:12px; color:var(--text2); margin-top:3px; }
/* Форма заведения: поле подписано слева, чтобы читалось как анкета. */
.rp-fr{ display:flex; align-items:center; gap:8px; margin-top:8px; }
.rp-fr .fl{ width:76px; flex-shrink:0; font-size:12px; font-weight:500; color:var(--text2); }
.rp-fr .reg-sel{
  flex:1; min-width:0; font:inherit; font-size:13px; padding:4px 8px; border-radius:8px;
  border:1px solid var(--border); background:var(--card); color:var(--text);
}
.rp-note{
  margin-top:10px; padding:8px 12px; border-radius:8px; background:var(--card);
  border:1px solid var(--border); font-size:12px; color:var(--text2); line-height:1.5;
}
.rp-note b{ color:var(--text); font-weight:500; }

/* Экран подтверждения: что именно произошло. */
.rp-done{ text-align:center; padding:24px 4px 16px; }
.rp-done .ic{
  width:46px; height:46px; margin:0 auto 10px; border-radius:50%;
  background:var(--green-bg, #F0FDF4); color:#15803D;
  display:flex; align-items:center; justify-content:center; font-size:20px; font-weight:500;
}
[data-theme="dark"] .rp-done .ic{ color:#4ADE80; }
.rp-done .t1{ font-size:15px; font-weight:600; }
.rp-done .t2{ font-size:12px; color:var(--text2); margin-top:4px; }
.rp-wn{ display:flex; align-items:center; justify-content:center; gap:12px; margin-top:12px; font-variant-numeric:tabular-nums; }
.rp-wn .was{ font-size:12px; color:var(--text2); text-decoration:line-through; }
.rp-wn .arr{ color:#15803D; font-weight:500; }
[data-theme="dark"] .rp-wn .arr{ color:#4ADE80; }
.rp-wn .now{ font-size:13px; font-weight:500; }
/* Формы правки, переехавшие в панель, не должны выглядеть врезкой в список. */
.reg-panel .reg-editbox, .reg-panel .reg-ordbox{ margin:9px 0 0; }
/* Выбранная строка подсвечена — видно, что разбирается в панели. */
.reg-r.reg-cur{ background:var(--blue-bg, #EFF6FF); }
/* Пока панель ДЕЛИТ ширину со списком, месту цена выше: номер приказа уходит —
   он всё равно виден в панели. Ниже 1240px панель становится накладкой, список
   снова полной ширины, и прятать колонку незачем.
   Класс ставит разметка, а не :has() — портал открывают и в старых браузерах. */
@media (min-width:1241px){
  .reg-body.rp-on .reg-ordc{ display:none; }
  .reg-body.rp-on .reg-cols, .reg-body.rp-on .reg-r{
    grid-template-columns:22px minmax(150px,1.3fr) minmax(104px,168px) 54px minmax(130px,1fr);
  }
}
@media (max-width:1240px){
  .reg-panel{
    position:fixed; right:0; top:0; bottom:0; width:min(94vw,402px); z-index:70;
    box-shadow:0 10px 34px rgba(16,21,28,.22);
  }
}

/* Меню и запасная полоса состояний — взаимозаменяемы, и видна всегда ровно одна.
   Селектор привязан к .reg-body: этот каркас есть ТОЛЬКО у реестра, поэтому
   сверки графика и приказов, живущие в тех же классах .reg-*, не задеты. */
@media (min-width:981px){
  .reg-body .reg-states, .reg-body .reg-reasons{ display:none; }
}
@media (max-width:980px){ .reg-nav{ display:none; } }

/* Жёсткого минимума у таблицы БОЛЬШЕ НЕТ. Раньше стояло min-width:940px — это
   честная ширина старой раскладки на восемь колонок. После переработки сетке
   нужно около 690px, и старый минимум сам выталкивал строку за край окна:
   таблица становилась шире своей рамки прокрутки, а всплывающие действия
   уезжали за границу (замер 29.07.2026, ширина окна 840px).
   Ограничитель не нужен вовсе: минимальные ширины дорожек в grid и есть тот
   предел, ниже которого таблица не сжимается. */
.reg-tbl{ min-width:0; }
.reg-cols, .reg-r{
  display:grid; gap:12px; align-items:center;
  grid-template-columns:24px 1.7fr 106px 118px 106px 66px 1.5fr 108px;
}
.reg-cols{
  padding:8px 24px; font-size:11px; font-weight:600;
  color:var(--text2); background:var(--card2); border-bottom:1px solid var(--border);
  position:sticky; top:0; z-index:2;
}
.reg-r{ padding:8px 24px; border-bottom:1px solid var(--border); }
.reg-r:hover{ background:var(--card2); }
.reg-r.on{ background:rgba(45,127,249,.07); }
.reg-emp{ font-size:13px; font-weight:500; min-width:0; }
.reg-emp small{ display:block; font-size:11px; font-weight:600; color:var(--text2); margin-top:1px; }
/* Ячейка-источник: содержимое НЕ должно вылезать за колонку. min-width:0 нужен
   гриду (иначе длинный текст растягивает колонку и налезает на соседнюю),
   overflow+ellipsis обрезают то, что всё же длиннее. Полные даты — в подсказке. */
.reg-cell{
  font-size:12px; color:var(--text2); line-height:1.35;
  min-width:0; overflow:hidden;
}
.reg-cell > small{
  display:block; font-size:11px; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
.reg-cell{ white-space:nowrap; text-overflow:ellipsis; }
.reg-cell.reg-edit{ cursor:pointer; border-radius:8px; padding:3px 8px; margin:-3px -7px; border:1px dashed transparent; }
.reg-cell.reg-edit:hover{ border-color:var(--border2, #D6DDE6); background:var(--card); }
.reg-miss{ color:var(--text2); }
.reg-arrow{ color:var(--purple); font-weight:600; }
.reg-days{ font-size:12px; font-weight:500; color:var(--text2); text-align:center; }
.reg-days.bad{ color:var(--red); }
.reg-why{ font-size:12px; line-height:1.4; min-width:0; overflow:hidden; }
.reg-emp, .reg-days{ min-width:0; overflow:hidden; }
.reg-why small{ display:block; color:var(--text2); font-size:11px; margin-top:1px; }
.reg-tag{ font-weight:500; }
.reg-tag.err{ color:var(--red); }
.reg-tag.warn{ color:var(--amber, #E8A317); }
.reg-tag.ok{ color:var(--green); }
.reg-tag.idea{ color:var(--blue, #2D7FF9); }   /* предложение портала, а не ошибка */
.reg-acts{ display:flex; gap:8px; justify-content:flex-end; }

/* панель массовых действий */
.reg-bulk{
  flex-shrink:0; display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:12px 24px; border-top:1px solid var(--border); background:var(--card2);
}
/* меню «⋯» */
.reg-menu{
  position:absolute; right:22px; top:52px; z-index:9; width:262px; padding:8px;
  background:var(--card); border:1px solid var(--border); border-radius:12px;
  box-shadow:0 14px 38px rgba(16,21,28,.2);
}
.reg-menu button{
  display:block; width:100%; text-align:left; font:inherit; font-size:13px; font-weight:600;
  padding:8px 12px; border-radius:8px; border:0; background:transparent; color:var(--text2); cursor:pointer;
}
.reg-menu button:hover{ background:var(--card2); }
.reg-sep{ height:1px; background:var(--border); margin:5px 8px; }

.reg-srow{ display:flex; align-items:center; gap:12px; padding:8px 0; font-size:12px; color:var(--text2); }
.reg-srow + .reg-srow{ border-top:1px dashed var(--border); }
.reg-srow .nm{ width:88px; flex-shrink:0; font-size:11px; font-weight:600; color:var(--text2); }
.reg-srow .val{ flex:1; font-weight:600; }
.reg-checks{ border:1px solid var(--border); border-radius:12px; padding:8px 12px; background:var(--card2); }
.reg-chk{ display:flex; gap:8px; font-size:12px; line-height:1.5; color:var(--text2); padding:3px 0; }
.reg-chk .ic{ width:13px; flex-shrink:0; font-weight:600; text-align:center; }
.reg-chk.ok .ic{ color:var(--green); }
.reg-chk.warn .ic{ color:var(--amber, #E8A317); }
.reg-chk.err .ic{ color:var(--red); }
@media (max-width:720px){
  .reg-head{ padding-left:16px; padding-right:16px; }
  .reg-cols, .reg-r{ padding-left:16px; padding-right:16px; }
}
.reg-wrap .ec-btn[disabled], .mc .ec-btn[disabled]{ opacity:.45; cursor:not-allowed; }

/* ═══ СПОКОЙНАЯ СВЕРКА (ТЗ владельца 27.07.2026) ═════════════════════════════
   «Сверка перегружена, я теряюсь, что как и где». Экран не потерял функций — он
   замолкает, пока ему нечего сказать: три состояния вместо девяти причин, даты
   один раз вместо трёх, действия и подробности по наведению.
   Windows: никаких emoji-глифов (рисуются шрифтом ОС: свой размер, своя базовая
   линия, цветные — строка «прыгает»), только inline SVG; жирность 700, а не 800
   (у Segoe UI нет 800, винда подделывает её растягиванием). */

/* три состояния работы */
.reg-states{ display:flex; gap:8px; align-items:center; margin-bottom:9px; flex-wrap:wrap; }
.reg-state{
  font:inherit; cursor:pointer; text-align:left; padding:8px 15px; border-radius:12px;
  border:1px solid var(--border); background:var(--card); min-width:142px;
}
.reg-state:hover{ background:var(--card2); }
.reg-state .n{ display:block; font-size:20px; font-weight:500; line-height:1.15; }
.reg-state .l{ display:block; font-size:12px; font-weight:500; color:var(--text2); margin-top:1px; }
.reg-state.do .n{ color:var(--red); }
.reg-state.check .n{ color:var(--amber, #E8A317); }
.reg-state.ok .n{ color:var(--green); }
.reg-state.on{ border-color:var(--text); box-shadow:inset 0 0 0 1px var(--text); }
.reg-state.on .l{ color:var(--text2); }
.reg-shint{ font-size:12px; color:var(--text2); margin:-2px 0 10px; }

/* причины: только ненулевые, 4 + «ещё N» */
.reg-rbtn{
  font:inherit; font-size:12px; font-weight:500; cursor:pointer; padding:4px 12px;
  border-radius:99px; border:1px solid var(--border); background:var(--card); color:var(--text2);
}
.reg-rbtn:hover{ background:var(--card2); }
.reg-rbtn.on{ background:var(--text); border-color:var(--text); color:var(--card); }
.reg-rbtn .n{ opacity:.55; margin-left:5px; }


/* КОЛОНКИ: сотрудник · период · дни · № приказа · что не так.
   Действий в сетке НЕТ — см. .reg-acts ниже. Актуальная сетка задана одна, в
   конце файла; здесь её дублировать нельзя, иначе два правила расходятся. */
.reg-r{ position:relative; }
/* Период — всегда с годом и АДАПТИВНЫЙ (ТЗ владельца 29.07.2026): на мониторе
   идёт одной строкой, на узком экране складывается в две. Раньше он был жёстко
   двухстрочным — на широком экране это была пустая трата места.
   Как это работает: колонка выше просит ширину «в одну строку» (max-content) и
   получает её, пока таблице хватает места. Каждая дата неразрывна, поэтому
   единственная точка переноса — пробел между ними: тире остаётся в конце первой
   строки, вторая дата встаёт ровно под первой, столбик не разъезжается. */
.reg-per{ font-size:13px; font-weight:500; min-width:0; line-height:1.35; }
.reg-per .d1, .reg-per .d2{ white-space:nowrap; font-variant-numeric:tabular-nums; }
.reg-per .d2{ color:var(--text2); }

.reg-per small{ display:block; font-size:11px; font-weight:600; }
/* Класса .reg-edit у ячейки периода больше нет: правка дат ушла в панель разбора
   (ТЗ владельца 30.07.2026), и подсветка «меня можно нажать» стала врать. */

/* Значок состояния строки: сделано в сессии · разобрано · отложено
   (app-reg-session.js, макет 29.07.2026). Стоит перед ФИО и заменяет собой
   вычитывание примечания. */
.reg-st{
  display:inline-flex; align-items:center; justify-content:center;
  width:15px; height:15px; margin-right:5px; border-radius:50%;
  font-size:11px; font-weight:600; vertical-align:1px;
}
.reg-st.ap{ background:var(--green-bg, #F0FDF4); color:#16A34A; }
.reg-st.ck{ background:var(--card2); color:var(--text2); }
.reg-st.zz{ background:#F0ECFF; color:var(--purple, #8B5CF6); }

/* Лента «Сделано сегодня» — не список отпусков, а список действий. */
.reg-done-list{ padding:4px 0; }
.reg-done-r{
  display:flex; align-items:center; gap:12px; padding:12px 24px;
  border-bottom:1px solid var(--border); font-size:13px;
}
.reg-done-r .tm{
  width:38px; flex-shrink:0; font-size:12px; color:var(--text2);
  font-variant-numeric:tabular-nums;
}
.reg-done-r .who{ width:230px; flex-shrink:0; min-width:0; font-size:13px; }
.reg-done-r .who small{
  display:block; font-size:11px; color:var(--text2); font-variant-numeric:tabular-nums;
}
.reg-done-r .lbl{ flex:1; min-width:0; color:var(--text2); font-weight:600; }
.reg-done-r .mut{ font-size:12px; color:var(--text2); cursor:help; white-space:nowrap; }

/* Легенда «Как читать список» — внутри меню «⋯». */
.reg-legend{ padding:8px 12px 4px; }
.reg-legend .lg-h{
  font-size:11px; font-weight:600;
  color:var(--text2); margin-bottom:7px;
}
.reg-legend .lg-i{
  display:flex; align-items:flex-start; gap:8px; padding:3px 0;
  font-size:12px; line-height:1.45; color:var(--text2);
}
.reg-legend .reg-nd{ margin-top:5px; flex-shrink:0; }
.reg-legend .reg-st{ margin-right:0; flex-shrink:0; }

/* Готовые причины в окне «Отметить разобранным» (макет 29.07.2026). */
.reg-whys{ display:flex; flex-wrap:wrap; gap:8px; margin:7px 0 6px; }
.reg-why{
  font:inherit; font-size:12px; font-weight:600; cursor:pointer; padding:4px 12px;
  border-radius:99px; border:1px dashed var(--border2, #D6DDE6);
  background:transparent; color:var(--text2);
}
.reg-why:hover{
  border-style:solid; border-color:var(--blue); color:var(--blue);
  background:var(--blue-bg, rgba(45,127,249,.07));
}
.reg-src{ display:flex; align-items:center; gap:8px; min-width:0; font-size:12px; color:var(--text2); position:relative; }
.reg-src b{ font-weight:500; color:var(--text); }
.reg-onum{ font-weight:500; color:var(--text); }
.reg-omut{ color:var(--text2); }
.reg-hand{
  display:inline-block; font-size:11px; font-weight:500; padding:1px 8px; border-radius:99px;
  background:rgba(139,92,246,.13); color:var(--purple, #8B5CF6);
}
.reg-addord{
  font:inherit; font-size:12px; font-weight:500; cursor:pointer; color:var(--text2);
  background:transparent; border:1px dashed var(--border2, #D6DDE6); border-radius:8px; padding:3px 8px;
  display:inline-flex; align-items:center; gap:4px;
}
.reg-addord:hover{ color:var(--act); border-color:var(--act); border-style:solid; background:var(--blue-bg, rgba(45,127,249,.07)); }

/* Действия — по наведению: спокойная строка остаётся спокойной.
   Всплывают ПОВЕРХ правого края строки, а не занимают колонку (ТЗ владельца
   29.07.2026): так они не могут распереть таблицу и вылезти за край окна.
   Подложку берут у строки, поэтому текст под ними не просвечивает.
   pointer-events: ловят курсор ТОЛЬКО сами кнопки. Пока «ловушкой» был весь
   блок, он невидимым накрывал половину колонки «Что не так», и карточка по
   наведению либо не показывалась, либо гасла на полпути к ней. */
.reg-acts{
  position:absolute; right:22px; top:50%; transform:translateY(-50%); z-index:6;
  display:flex; align-items:center; gap:8px; background:inherit; padding-left:16px;
  opacity:0; transition:opacity .12s; pointer-events:none;
}
.reg-acts .ec-btn{ pointer-events:auto; }
.reg-r:hover .reg-acts, .reg-r.on .reg-acts, .reg-r.reg-editing .reg-acts{ opacity:1; }
@media (max-width:720px){ .reg-acts{ right:16px; } }

/* Карточка по наведению вместо окна «Открыть». Открывается ТОЛЬКО от колонки
   «Источники» (ТЗ владельца 27.07.2026): на всей строке она вылетала от любого
   движения мыши по списку и закрывала соседние строки.
   Живёт внутри ячейки, поэтому:
   • top:100% — прилипает к нижнему краю ячейки, между ними нет зазора, и курсор
     доезжает до кнопок карточки, не потеряв наведение;
   • .reg-hc:hover держит её открытой, пока мышь внутри. */
.reg-hc{
  /* Карточка шире ячейки и растёт ВЛЕВО (right:0): правым краем она садится на
     правый край строки — ровно туда, откуда идёт курсор. Слева всегда есть ФИО и
     период, места хватает и в узком окне.
     ДО КАРТОЧКИ НУЖНО ДОТЯНУТЬСЯ МЫШЬЮ (ТЗ владельца 29.07.2026: карточка гасла
     на полпути). Две страховки:
       • :before перекрывает 14px над карточкой — наведение не рвётся в зазоре
         между строкой и карточкой;
       • исчезновение отложено на 0,26 с — есть запас времени, даже если рука
         ведёт мышь не по прямой. Появляется карточка по-прежнему сразу. */
  position:absolute; right:0; left:auto; top:calc(100% - 6px); z-index:9;
  width:min(434px, calc(100vw - 40px));
  background:var(--card); border:1px solid var(--border); border-radius:12px;
  box-shadow:0 10px 34px rgba(16,21,28,.16); padding:12px 12px;
  font-size:12px; color:var(--text2); cursor:default; white-space:normal;
  visibility:hidden; opacity:0;
  transition:opacity .12s ease .26s, visibility 0s linear .26s;
}
.reg-hc:before{ content:''; position:absolute; left:0; right:0; top:-14px; height:14px; }
/* У нижних строк места под карточку нет — переворачиваем её наверх (класс ставит JS). */
.reg-hc.up{ top:auto; bottom:calc(100% - 6px); }
.reg-hc.up:before{ top:auto; bottom:-14px; }
.reg-note:hover > .reg-hc, .reg-hc:hover{
  visibility:visible; opacity:1; transition:opacity .12s ease, visibility 0s;
}
.reg-hc-h{ font-size:13px; font-weight:500; margin-bottom:7px; }
.reg-hc-h span{ font-weight:600; color:var(--text2); }
.reg-hc .reg-srow{ display:flex; align-items:center; gap:12px; padding:4px 0; font-size:12px; }
.reg-hc .reg-srow + .reg-srow{ border-top:1px dashed var(--border); }
.reg-hc .nm{ width:74px; flex-shrink:0; font-size:11px; font-weight:500; color:var(--text2); }
.reg-hc .val{ flex:1; font-weight:600; color:var(--text); min-width:0; }
.reg-hc .val.mut{ color:var(--text2); font-weight:600; }
.reg-hc .mark{ font-size:11px; font-weight:500; }
.reg-hc .mark.ok{ color:var(--green); }
.reg-hc .mark.diff{ color:var(--amber, #E8A317); }
.reg-hc .mark.no{ color:var(--text2); }
/* «Чему верить», когда источники разошлись. Отдельной строкой и словами —
   раньше это правило печаталось вместо результата сравнения словом «основа»
   (ТЗ владельца 29.07.2026). */
.reg-mainhint{
  margin-top:7px; padding-top:8px; border-top:1px dashed var(--border);
  font-size:12px; line-height:1.5; color:var(--text2);
}
.reg-hc-f{ display:flex; gap:8px; margin-top:9px; padding-top:8px; border-top:1px solid var(--border); flex-wrap:wrap; }
.reg-hc-mut{ margin-left:auto; }

/* правка дат прямо в строке: период одним полем */
.reg-r.reg-editing{ background:var(--blue-bg, rgba(45,127,249,.07)); }
/* Форма правки дат раскрывается ПОД строкой обычным блоком во всю её ширину.
   Раньше она висела абсолютом (left:190px; width:500px) и в узком окне уезжала
   за край: кнопка «Сохранить» оказывалась за границей окна (жалоба владельца
   28.07.2026). Внутри сетки строки такое невозможно. */
.reg-editbox{
  grid-column:1/-1; position:static; width:auto; margin:8px 0 2px;
  background:var(--card2); border:1px solid var(--border); border-radius:12px;
  padding:12px 12px;
}
.reg-eb-lbl{ font-size:11px; font-weight:500; color:var(--text2); }
.reg-perin{ display:flex; align-items:center; gap:8px; margin-top:6px; }
.reg-perfield{
  font:inherit; font-size:15px; font-weight:500; width:218px; padding:8px 12px;
  border-radius:8px; border:1px solid var(--blue); background:var(--card); color:var(--text);
  outline:none; box-shadow:0 0 0 3px rgba(45,127,249,.15);
}
.reg-step{
  width:26px; height:26px; border-radius:8px; border:1px solid var(--border); background:var(--card);
  color:var(--text2); cursor:pointer; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
}
.reg-step:hover{ background:var(--card2); color:var(--text); }
.reg-cnt{ font-size:12px; font-weight:500; color:var(--text2); white-space:nowrap; }
.reg-cnt b{ font-size:15px; color:var(--text); }
.reg-picks{ display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
.reg-pick{
  font:inherit; font-size:12px; font-weight:600; cursor:pointer; padding:4px 12px;
  border-radius:8px; border:1px dashed var(--border2, #D6DDE6); background:transparent; color:var(--text2);
  display:inline-flex; align-items:center; gap:8px;
}
.reg-pick:hover{ border-style:solid; border-color:var(--act); color:var(--act); background:var(--blue-bg, rgba(45,127,249,.07)); }
.reg-pick.main{ border-style:solid; }
.reg-pick .k{ font-size:11px; font-weight:500; color:var(--text2); }
.reg-pick:hover .k{ color:var(--act); }
.reg-pick.on{
  font-size:12px; color:var(--text2); padding:4px 12px; border-radius:8px;
  border:1px solid var(--border); background:var(--card2);
}
.reg-echecks{ margin-top:10px; }
.reg-keys{ display:flex; gap:8px; align-items:center; margin-top:11px; font-size:11px; color:var(--text2); }
.reg-kbd{
  font:inherit; font-size:11px; font-weight:500; padding:2px 8px; border-radius:8px;
  border:1px solid var(--border2, #D6DDE6); background:var(--card2); color:var(--text2);
}

/* инлайн-ввод приказа в колонке «Источники» */
.reg-ordin{ display:inline-flex; align-items:center; gap:4px; min-width:0; }
.reg-oin{
  font:inherit; font-size:12px; font-weight:500; width:100px; padding:4px 8px; min-width:0;
  border-radius:8px; border:1px solid var(--blue); background:var(--card); color:var(--text);
  outline:none; box-shadow:0 0 0 3px rgba(45,127,249,.15);
}
.reg-oin.date{ width:82px; font-weight:600; border-color:var(--border2, #D6DDE6); box-shadow:none; }

/* список ручных приказов */
.reg-hlist{ border:1px solid var(--border); border-radius:12px; overflow:hidden; }
.reg-hrow{
  display:grid; grid-template-columns:1.4fr 150px 1fr 1fr 90px; gap:12px; align-items:center;
  padding:8px 12px; font-size:12px;
}
.reg-hrow + .reg-hrow{ border-top:1px solid var(--border); }
.reg-hrow.head{
  background:var(--card2); font-size:12px; font-weight:500; color:var(--text2);
}
.reg-hrow .mut{ color:var(--text2); font-size:12px; }
/* <b> в разметке — 700 от браузера; жирнее 600 в портале не бывает (свод, п. 1). */
.reg-hrow b{ font-weight:500; }

/* Windows: тонкие полосы прокрутки вместо широких серых плит */
.reg-wrap *{ scrollbar-width:thin; scrollbar-color:var(--border2, #D6DDE6) transparent; }
/* Вендорные правила убраны 10.09.2026 — их перекрывало scrollbar-width из
   theme.css. Строка выше (scrollbar-width + scrollbar-color) работает. */

/* Последние строки списка: карточка/правка не должны обрезаться нижним краем */
.reg-wrap .sc-body{ padding-bottom:220px; }

/* ═══ ГЛАВНЫЙ ЭКРАН СВЕРОК (ТЗ 26.07.2026) ═══════════════════════════════════
   Компоновка по важности: юрлицо и состояние выгрузок наверху, слева ежедневная
   работа (реестр и источники), справа то, к чему обращаются изредка. Ничего не
   убрано — только переставлено. */
.hub-wrap{ display:flex; flex-direction:column; height:100%; min-height:0; }
.hub-head{ flex-shrink:0; padding:16px 24px 12px; border-bottom:1px solid var(--border); }
/* На странице сверок своя шапка не рисуется — остаётся только полоса источников,
   и верхний отступ ей не нужен: над ней уже стоят подвкладки. */
.hub-head.inpage{ padding:2px 0 12px; }
.hub-head.inpage .hub-src{ margin-top:0; }
.hub-row1{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.hub-title{ font-size:15px; font-weight:600; }
.hub-year{ font-size:12px; font-weight:400; color:var(--text2); }
.hub-orgs{ display:inline-flex; gap:4px; margin-left:4px; }
/* Выбранное юрлицо было ТЁМНОЙ ЗАЛИВКОЙ — последняя в сверках. Тёмное в портале
   осталось только у поверхностей и формы входа (решение 16.08.2026), а «выбрано»
   показывается светло-синим. */
.hub-org{
  font:inherit; font-size:13px; font-weight:500; cursor:pointer; padding:4px 12px;
  border-radius:8px; border:1px solid var(--border); background:var(--card2); color:var(--text2);
}
.hub-org.on{ background:var(--act-bg); border-color:var(--act); color:var(--act); }
[data-theme="dark"] .hub-org.on{ color:var(--act-hover); }
.hub-src{ display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }
.hub-chip{
  display:inline-flex; align-items:center; gap:8px; font-size:12px; font-weight:500;
  padding:4px 12px; border-radius:99px; border:1px solid var(--border);
  background:var(--card2); color:var(--text2); white-space:nowrap;
}
.hub-chip.on, .hub-chip.warn{ color:var(--text2); }
.hub-dot{ width:6px; height:6px; border-radius:50%; background:var(--text3); flex-shrink:0; }
.hub-chip.on .hub-dot{ background:var(--green); }
.hub-chip.warn .hub-dot{ background:var(--amber, #E8A317); }
.hub-when{ color:var(--text2); font-weight:400; }

.hub-body{ flex:1; min-height:0; overflow:auto; padding:16px 22px 22px; }
.hub-cols{ display:grid; grid-template-columns:1fr 300px; gap:16px; align-items:start; }
@media (max-width:980px){ .hub-cols{ grid-template-columns:1fr; } }
.hub-sect{ font-size:12px; font-weight:500; color:var(--text2); margin:0 0 8px; }
.hub-sect.mt{ margin-top:18px; }

/* герой — реестр */
.hub-hero{ border:1px solid var(--border); border-radius:12px; padding:16px 16px; background:var(--card); }
.hub-hero-top{ display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; }
/* Было 38 px весом 900 — самый крупный шрифт портала при своде «20 и не жирнее
   600». Число и так единственное крупное на экране, размер ему не нужен. */
.hub-num{ font-size:20px; font-weight:600; line-height:1.1; }
.hub-lbl{ font-size:13px; color:var(--text2); margin-top:4px; line-height:1.5; max-width:340px; }
/* <b> в тексте — 700 от браузера; в портале жирнее 600 не бывает (свод, п. 1). */
.hub-lbl b, .hub-note b, .hub-tile-sub b{ font-weight:500; color:var(--text); }
.hub-hero-act{ margin-left:auto; display:flex; flex-direction:column; gap:8px; min-width:196px; }
.hub-hero-act .ec-btn{ justify-content:center; }
.hub-reasons{ display:flex; gap:8px; flex-wrap:wrap; margin-top:14px; padding-top:12px; border-top:1px solid var(--border); }
.hub-rchip{
  font:inherit; font-size:12px; font-weight:500; cursor:pointer; padding:4px 8px;
  border-radius:8px; border:1px solid var(--border); background:var(--card2); color:var(--text2);
}
.hub-rchip:hover{ border-color:var(--border2, #D6DDE6); }
.hub-rchip b{ margin-left:5px; color:var(--text); font-weight:500; }
.hub-rdot{ display:inline-block; width:6px; height:6px; border-radius:50%; margin-right:6px; vertical-align:middle; }
.hub-foot{ display:flex; gap:16px; margin-top:10px; font-size:12px; color:var(--text2); flex-wrap:wrap; }
.hub-foot b{ color:var(--text); font-weight:500; }

/* плитки источников */
.hub-tiles{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
@media (max-width:720px){ .hub-tiles{ grid-template-columns:1fr; } }
.hub-tile{ border:1px solid var(--border); border-radius:12px; padding:12px 16px; background:var(--card); }
.hub-tile h4{ margin:0; font-size:13px; font-weight:600; }
.hub-tile-sub{ font-size:12px; color:var(--text2); margin-top:3px; line-height:1.45; min-height:34px; }
/* «выгрузка загружена» стояла зелёной у всех загруженных источников — норма
   цветом (свод, п. 4). Загружено — обычная подпись; цвет остался у того, что
   требует действия: устаревшей выгрузки и незагруженной. */
.hub-st{ font-size:12px; font-weight:500; margin-top:8px; }
.hub-st.ok{ color:var(--text2); }
.hub-st.warn{ color:#B45309; }
[data-theme="dark"] .hub-st.warn{ color:var(--orange); }
.hub-st.off{ color:#B91C1C; }
[data-theme="dark"] .hub-st.off{ color:#F87171; }
.hub-tile-acts{ display:flex; gap:8px; margin-top:9px; }
.hub-badge{
  font-size:11px; font-weight:500; padding:1px 8px; border-radius:99px;
  border:1px solid var(--purple); color:#6D28D9; margin-left:6px; vertical-align:middle;
}
[data-theme="dark"] .hub-badge{ color:#C4B5FD; }

/* сайдбар */
.hub-side{ display:flex; flex-direction:column; gap:12px; }
.hub-panel{ border:1px solid var(--border); border-radius:12px; padding:12px 16px; background:var(--card); }
.hub-panel h4{ margin:0 0 8px; font-size:13px; font-weight:600; }
.hub-note-in{ font-size:12px; color:var(--text2); line-height:1.5; }
.hub-mini{ display:flex; align-items:center; gap:8px; padding:8px 0; font-size:12px; color:var(--text2); }
.hub-mini + .hub-mini{ border-top:1px dashed var(--border); }
.hub-mini .nm{ flex:1; min-width:0; }
.hub-mini .n{ font-size:12px; font-weight:500; color:var(--text2); white-space:nowrap; }
.hub-note{
  border:1px solid var(--border); border-radius:12px; padding:12px 12px; background:var(--card2);
  font-size:12px; color:var(--text2); line-height:1.55;
}
@media (max-width:720px){
  .hub-head{ padding-left:16px; padding-right:16px; }
  .hub-body{ padding-left:16px; padding-right:16px; }
}

/* Экраны сверок шире обычной модалки: в 960px реестр с тремя источниками
   не помещался и колонка действий уезжала за край (26.07.2026). */
.mc.mc-wide.mc-xwide{ max-width:1280px; width:96%; }
@media (max-width:1000px){ .mc.mc-wide.mc-xwide{ width:98%; } }

/* Плашка «↳ перенос» в колонке переноса. Лупа 🔎 из неё убрана 16.08.2026
   по просьбе владельца: эмодзи не вписывается в лаконичный вид, а то, что
   плашка кликабельная, видно по курсору и подсказке. Цвет классом, а не
   инлайном: инлайновый цвет не умеет тёмную тему. */
/* inline-flex и line-height числом: строчная плашка с отступами растягивала
   строку таблицы на пиксель (50 вместо 49). Вид не изменился — изменилось то,
   как считается высота строки (04.09.2026). */
.tbl-trchip{ display:inline-flex; align-items:center; line-height:14px;
             font-size:11px; font-weight:500; color:#B45309; background:var(--orange-bg);
             padding:3px 8px; border-radius:8px; }
[data-theme="dark"] .tbl-trchip{ color:var(--orange); }

/* ═══ ИСТОРИЯ ОТПУСКА И СДВИГИ (ТЗ 26.07.2026) ═══════════════════════════════
   Перенос везде ОРАНЖЕВЫЙ — тот же цвет, что в таблице (просьба владельца). */
/* Ширина 820 — как у карточки отпуска (ТЗ владельца 16.08.2026). Класс свой:
   .mc-wide общий, им пользуются загрузка календаря и годовой календарь
   сотрудника, и сужать его целиком нельзя. Ставится в vhOpenHistory и
   _vhShiftRender рядом с mc-flow. */
.mc.mc-wide.vh-modal{ max-width:820px; }
.vh-wrap{ padding:16px 24px; }
.vh-head{ display:flex; align-items:flex-start; gap:16px; margin-bottom:4px; }
.vh-title{ margin:0 0 3px; font-size:15px; font-weight:600; }
.vh-who{ font-size:12px; color:var(--text2); line-height:1.5; }
.vh-sum{
  display:flex; gap:24px; flex-wrap:wrap; margin:14px 0 4px; padding:12px 16px;
  border:1px solid var(--border); border-radius:12px; background:var(--card2);
}
.vh-sum-i{ font-size:12px; color:var(--text2); }
.vh-sum-i b{ display:block; font-size:15px; color:var(--text); font-weight:600; margin-top:2px;
             font-variant-numeric:tabular-nums; }
.vh-tl{ margin:16px 0 0; position:relative; padding-left:26px; }
.vh-tl:before{ content:''; position:absolute; left:8px; top:6px; bottom:10px; width:2px; background:var(--border); }
.vh-step{ position:relative; padding:0 0 16px; }
.vh-step:before{
  content:''; position:absolute; left:-22px; top:4px; width:10px; height:10px; border-radius:50%;
  background:var(--card); border:2px solid var(--border2, #D6DDE6);
}
.vh-step.base:before{ background:var(--text3); border-color:var(--text3); }
.vh-step.dead:before{ background:var(--card3); border-color:var(--border2, #D6DDE6); }
.vh-step.cur:before{ background:var(--green); border-color:var(--green); }
.vh-step-t{ font-size:13px; font-weight:500; }
.vh-when{ font-weight:400; color:var(--text2); margin-left:6px; font-size:12px; }
.vh-step-d{ font-size:13px; margin-top:2px; font-variant-numeric:tabular-nums; }
.vh-step.dead .vh-step-d{ color:var(--text2); text-decoration:line-through; }
.vh-step-m{ font-size:12px; color:var(--text2); margin-top:3px; line-height:1.55; }
/* Голый <b> в тексте этапа даёт браузерные 700 — четвёртая насыщенность на
   экране. Выделение внутри абзаца делаем 500 и цветом (свод, п. 1). */
.vh-step-m b, .vh-step-d b, .vh-pick-r b{ font-weight:500; color:var(--text); }
/* «ЧТО ПРОИЗОЙДЁТ» — БЕЗ ЗАЛИВКИ (ТЗ владельца 16.08.2026, вариант 1).
   Блок был залит оранжевым во всю ширину окна. Заливка по своду означает
   «прочти немедленно» — тревогу; а здесь спокойное объяснение последствий,
   которое читают перед КАЖДЫМ сдвигом. Осталось то же самое: заголовок,
   тонкая линия сверху и тот же список — ни строки не убрано. */
.vh-warn{
  margin-top:16px; padding:16px 0 0; border-top:1px solid var(--border);
  font-size:12px; line-height:1.7; color:var(--text2);
}
.vh-warn b{ font-weight:500; color:var(--text); }
.vh-warn > b:first-child{ display:block; font-size:13px; font-weight:600; margin-bottom:6px; }
/* .amber остался для мест, где блок ДЕЙСТВИТЕЛЬНО предупреждение. */
.vh-warn.amber{
  padding:12px 16px; border:1px solid var(--amber); border-top:1px solid var(--amber);
  border-radius:12px; background:var(--amber-bg); color:var(--text);
}
.vh-acts{ display:flex; gap:8px; align-items:center; margin-top:16px; flex-wrap:wrap; }
.vh-danger{ color:var(--red); border-color:var(--red); }
.vh-lbl{ font-size:12px; color:var(--text2); margin-top:16px; }
.vh-pick{ border:1px solid var(--border); border-radius:12px; padding:8px 12px; margin-top:6px; }
.vh-pick-r{ display:flex; align-items:center; gap:12px; padding:8px 0; font-size:13px; cursor:pointer; }
.vh-pick-r + .vh-pick-r{ border-top:1px dashed var(--border); }
.vh-pick-r.off{ color:var(--text2); cursor:not-allowed; }
.vh-radio{ width:14px; height:14px; accent-color:#F76B15; font-size:13px; }
.vh-sub{ font-size:12px; color:var(--text2); }
.vh-fld{ display:flex; gap:12px; margin:12px 0; flex-wrap:wrap; }
/* Подписи полей были ЗАГЛАВНЫМИ с трекингом и цветом --text3 (контраст 2.54):
   на Windows такие подписи слипаются (свод, пп. 6 и 8). */
.vh-fld label{ flex:1; min-width:150px; font-size:12px; font-weight:500; color:var(--text2); }
.vh-in, .vh-days, .vh-fld .dp-field{
  display:block; width:100%; margin-top:5px; font:inherit; font-size:13px; font-weight:400;
  padding:8px 12px; border-radius:8px; border:1px solid var(--border2, #D6DDE6);
  background:var(--card2); color:var(--text);
}
.vh-days{ text-align:center; background:var(--card3); }

/* Строка отменённого сдвига в таблице учёта: видна, но приглушена. */
.gtbl-row.vh-cancelled td{ opacity:.62; }
.gtbl-row.vh-cancelled td[data-col="from"], .gtbl-row.vh-cancelled td[data-col="to"]{ text-decoration:line-through; }
.vh-chip-x{
  display:inline-block; margin-left:6px; font-size:11px; font-weight:500; vertical-align:middle;
  padding:1px 8px; border-radius:99px; background:var(--orange); color:#fff;
}
/* Значок истории отпуска — без коробки (16.08.2026), заодно с остальными
   кнопками строки. Рамка была одинакова у всех и ничего не сообщала.
   Площадь попадания 24×24 сохранена — уменьшать её нельзя. */
.vh-hist-btn{
  width:24px; height:24px; border-radius:8px; border:none; background:transparent;
  color:var(--text2); cursor:pointer; font-size:11px; line-height:1;
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  transition:background .15s, color .15s;
}
.vh-hist-btn:hover{ background:var(--card2); color:var(--text); }
/* «История есть» — это ДАННЫЕ, а не украшение, поэтому признак сохранён.
   Раньше оранжевой была ОБВОДКА КОРОБКИ: цвет доставался рамке, а сам значок
   оставался бледным. Теперь цвет на значке — там, куда смотрят.
   Оттенок разный по темам: чистый --orange на белом даёт контраст 2.02, а для
   значка нужно не меньше 3. Приглушённый вариант даёт 5.2 на светлой; на
   тёмной наоборот проходит сам --orange (7.8). То же правило, что у слов
   статусов в таблице учёта, — см. ОФОРМЛЕНИЕ.md. */
.vh-hist-btn.has{ color:#9D6507; opacity:1 !important; }
[data-theme="dark"] .vh-hist-btn.has{ color:var(--orange); }
.vh-cancel-note{ font-size:11px; color:var(--text2); }
/* Дни периода, список периодов и итог при делении (ТЗ владельца 29.07.2026:
   перенос переехал внутрь истории — вместе с днями и документами). */
.vh-days-chip{
  display:inline-block; margin-left:8px; font-size:11px; font-weight:500; color:var(--text2);
  background:var(--card2); border:1px solid var(--border); border-radius:99px; padding:1px 8px;
}
.vh-per{ display:flex; align-items:baseline; gap:2px; }
.vh-per + .vh-per{ margin-top:2px; }
.vh-per-n{ font-size:11px; font-weight:500; color:#B45309; min-width:64px; }
[data-theme="dark"] .vh-per-n{ color:var(--orange); }
.vh-total{ font-size:12px; color:var(--text2); margin-top:4px; }
/* Документы этапа: заявление и приказ ИМЕННО этого сдвига. */
.vh-docs{ display:flex; gap:8px; flex-wrap:wrap; margin-top:7px; }
.vh-doc{ flex:1; min-width:158px; display:flex; align-items:center; gap:8px; border-radius:8px; padding:8px 12px; font-size:12px; }
.vh-doc.has{ background:var(--blue-bg); border:1px solid var(--blue-bg); cursor:pointer; }
.vh-doc.no{ background:var(--card2); border:1px solid var(--border); opacity:.8; }
.vh-doc-k{ font-size:12px; color:var(--text2); font-weight:400; }
.vh-doc-v{ font-size:13px; font-weight:500; }
.vh-doc.has .vh-doc-v{ color:var(--blue2); }
[data-theme="dark"] .vh-doc.has .vh-doc-v{ color:var(--act-hover); }
.vh-doc.no  .vh-doc-v{ color:var(--text2); }
.vh-doc .ic{ display:inline-flex; color:var(--text2); }
.vh-doc.no .ic{ opacity:.6; }
/* Карточка «Чей это сотрудник?» (app-impmatch.js, ТЗ владельца 29.07.2026):
   по каждому юрлицу — найден ли человек в структуре, должность и отдел. */
.emo-list{ display:flex; flex-direction:column; gap:12px; margin-top:14px; }
.emo-org{ border:1px solid var(--border); border-radius:12px; padding:12px 16px; background:var(--card2); }
.emo-org.cur{ border-color:var(--border2, #D6DDE6); }
.emo-org.on{ border-color:var(--green); background:var(--green-bg, rgba(34,197,94,.08)); }
.emo-h{ display:flex; align-items:center; gap:8px; font-size:13px; margin-bottom:5px; flex-wrap:wrap; }
.emo-cur, .emo-ok{ font-size:11px; font-weight:500; padding:1px 8px; border-radius:99px; }
.emo-cur{ background:var(--blue-bg); color:var(--blue); }
.emo-ok{ background:var(--card3); color:var(--text2); }
.emo-pos{ font-size:13px; color:var(--text); }
.emo-pos + .emo-pos{ margin-top:3px; }
.emo-dep{ color:var(--text2); }
.emo-tab{ color:var(--text2); margin-left:8px; font-size:12px; }
.emo-no{ color:var(--text2); }
.emo-act{ margin-top:8px; }
/* Свёрнутые несостоявшиеся сдвиги: одна плашка, раскрывается кликом. */
.vh-fold{ cursor:pointer; }
.vh-fold:hover .vh-step-t{ color:var(--orange); }
.vh-fold-off{
  font-size:12px; color:var(--text2); cursor:pointer; margin:-6px 0 10px; user-select:none;
}
.vh-fold-off:hover{ color:var(--text2); }
.vh-to-cancel{ font-size:11px; font-weight:500; color:#B45309; margin-left:6px; }
[data-theme="dark"] .vh-to-cancel{ color:var(--orange); }
/* Кнопка-галочка «разобрано» в строке реестра: исключение, которое больше
   не должно всплывать после импортов (26.07.2026). */
.reg-chk-btn{ padding:6px 9px !important; font-weight:600; }
.reg-chk-btn:hover{ border-color:var(--green); color:var(--green); }

/* ═══ ЕДИНОЕ ОФОРМЛЕНИЕ СВЕРОК · РЕЕСТР (ТЗ владельца 28.07.2026) ════════════
   Претензия владельца: «всего так много, всё бросается в глаза, нет порядочности».
   Экран не потерял ни одной операции — изменилась только подача:
   • шапка — заголовок и ОДНА контекстная строка вместо пяти полос подряд;
   • причина расхождения написана один раз над группой, а не в каждой строке;
   • источники подписаны полностью («Учёт», «График 1С», «Приказ 1С»);
   • цвет означает ровно одно: зелёный — источник есть, серый — нет,
     ОРАНЖЕВЫЙ — только перенос. Расхождение дат и дней — красным в «Дни». */

/* шапка: заголовок + контекст */
.reg-row1{ align-items:flex-start; gap:8px; margin-bottom:12px; flex-wrap:nowrap; }
.reg-ttl{ min-width:0; }
.reg-title{ font-size:15px; font-weight:600; }
.reg-ctx{ font-size:12px; color:var(--text2); margin-top:3px; line-height:1.5; }
.reg-ctx .dot{ opacity:.5; margin:0 6px; }
.reg-ctx a{ color:var(--text2); text-decoration:none; border-bottom:1px dashed var(--border2, #D6DDE6); }
.reg-ctx a:hover{ color:var(--text); }
.reg-ctx .warn{ color:var(--red); font-weight:600; }
.reg-search{ flex-shrink:0; width:190px; background:var(--card); border-radius:8px; }
.reg-ib{ padding:8px 12px !important; flex-shrink:0; }

/* три состояния — одна полоса, а не три отдельные коробки */
.reg-states{ gap:0; margin-bottom:0; border:1px solid var(--border); border-radius:12px; overflow:hidden; }
.reg-state{
  flex:1; min-width:0; border:0; border-left:1px solid var(--border); border-radius:0;
  padding:12px 16px 12px; position:relative; background:transparent;
}
.reg-state:first-child{ border-left:0; }
.reg-state .n{ font-size:20px; font-weight:600; color:var(--text2); }
.reg-state .l{ font-size:12px; margin-top:2px; }
.reg-state:before{ content:''; position:absolute; left:0; right:0; top:0; height:2px; background:transparent; }
.reg-state.on{ background:var(--card2); box-shadow:none; border-color:var(--border); }
.reg-state.on .l{ color:var(--text2); }
.reg-state.do.on:before{ background:var(--red); }
.reg-state.check.on:before{ background:var(--amber, #E8A317); }
.reg-state.ok.on:before{ background:var(--green); }
.reg-state.do .n, .reg-state.check .n, .reg-state.ok .n{ color:var(--text2); }
.reg-state.do.on .n{ color:var(--red); }
.reg-state.check.on .n{ color:var(--amber, #E8A317); }
.reg-state.ok.on .n{ color:var(--green); }
.reg-shint{ margin:9px 2px 0; line-height:1.5; }
.reg-shint.alt{ color:var(--text2); }
.reg-shint a{ color:var(--blue); }

/* причины — точка цвета уровня + счётчик */
.reg-reasons{ margin:14px 0 0; }
.reg-rbtn{ display:inline-flex; align-items:center; gap:8px; font-weight:600; font-size:12px; padding:5px 11px; }
.reg-rbtn .rd{ width:6px; height:6px; border-radius:50%; background:var(--text3); }
.reg-rbtn.err .rd{ background:var(--red); }
.reg-rbtn.warn .rd{ background:var(--amber, #E8A317); }
.reg-rbtn.idea .rd{ background:var(--blue); }
.reg-rbtn .n{ opacity:1; color:var(--text2); font-size:11px; font-weight:500; }
.reg-rbtn.on .n{ color:var(--card); opacity:.7; }

/* «Как считали» — бывшая сводка и обе полосы-объяснения */
.reg-nt{ margin:12px 0 0; border-top:1px solid var(--border); }
.reg-nts{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  font-size:12px; color:var(--text2); padding:12px 2px 0;
}
.reg-nts:hover{ color:var(--text2); }
.reg-nts svg{ transition:transform .15s; }
.reg-nt.open .reg-nts svg{ transform:rotate(90deg); }
.reg-ntb{ padding:4px 2px 8px; }
.reg-nti{ display:flex; gap:12px; font-size:12px; color:var(--text2); line-height:1.55; padding:7px 0; border-top:1px dashed var(--border); }
.reg-nti:first-child{ border-top:0; }
.reg-nti .k{ flex-shrink:0; width:44px; text-align:right; font-size:13px; font-weight:600; color:var(--text); }
.reg-nti .v b{ color:var(--text); font-weight:500; }
.reg-nti .v b.tr{ color:var(--orange, #F59E0B); }
.reg-nti .v a{ color:var(--blue); }

/* заголовок группы: причина ОДИН раз */
.reg-gh{ display:flex; align-items:center; gap:8px; padding:16px 24px 8px; }
.reg-gh .t{ font-size:11px; font-weight:600; color:var(--text2); white-space:nowrap; }
.reg-gh .t.idea{ color:var(--blue); }
.reg-gh .c{ font-size:11px; font-weight:500; color:var(--text2); }
.reg-gh .hint{ font-size:12px; color:var(--text2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.reg-gh .ln{ flex:1; height:1px; background:var(--border); min-width:12px; }
.reg-gh .ga{ font-size:12px; font-weight:500; color:var(--text2); cursor:pointer; opacity:0; transition:opacity .12s; white-space:nowrap; }
.reg-gh:hover .ga{ opacity:1; }
.reg-gh .ga:hover{ color:var(--text); }
.reg-gcv{
  border:0; background:transparent; color:var(--text2); cursor:pointer; padding:0; flex-shrink:0;
  display:inline-flex; align-items:center; transition:transform .15s;
}
.reg-gh.closed .reg-gcv{ transform:rotate(-90deg); }
.reg-gh input[type=checkbox]{ opacity:0; transition:opacity .12s; }
.reg-gh:hover input[type=checkbox], .reg-gh input[type=checkbox]:checked{ opacity:1; }
.reg-gmore{
  padding:8px 24px 8px 58px; border-bottom:1px solid var(--border);
  font-size:12px; color:var(--text2); cursor:pointer;
}
.reg-gmore:hover{ background:var(--card2); color:var(--text2); }

/* КОЛОНКИ: сотрудник · период · дни · № приказа · что не так.
   Колонки ДЕЙСТВИЙ в сетке нет намеренно (ТЗ владельца 29.07.2026). Пока она была
   фиксированной, сумма минимальных ширин колонок превышала ширину таблицы, а grid
   ниже минимума не сжимается — кнопки вылезали за правый край окна. Теперь
   действия всплывают поверх строки и ширину таблицы не занимают вообще.
   Период: minmax(104px,168px) — ровно на одну строку «08.01.2026 – 13.01.2026»,
   пока таблице хватает места, и ужимается с переносом, когда не хватает.
   ВАЖНО, почему не max-content: шапка и каждая строка — ОТДЕЛЬНЫЕ grid-контейнеры,
   и max-content каждый считает по своему содержимому. В шапке там короткое слово
   «Период», в строках — длинные даты, поэтому колонки разъезжались на 16–20px
   (замер 29.07.2026). Фиксированный верх делает результат одинаковым у обоих. */
.reg-cols, .reg-r{
  grid-template-columns:22px minmax(158px,1.3fr) minmax(104px,168px) 54px 118px minmax(140px,1fr);
}
/* Совсем узко — № приказа уходит: он есть и в «Что не так», и в карточке.
   Колонку убираем ВМЕСТЕ с её дорожкой, иначе остальные ячейки сдвинутся на одну
   влево и «Что не так» окажется в узкой дорожке номера. */
@media (max-width:880px){
  .reg-cols, .reg-r{
    grid-template-columns:22px minmax(140px,1.3fr) minmax(104px,168px) 54px minmax(120px,1fr);
  }
  .reg-ordc{ display:none; }
}
.reg-cols{ background:var(--card); border-bottom:1px solid var(--border); }
/* Фон строки задан явно: от него наследуется подложка всплывающих действий. */
.reg-r{ border-bottom:1px solid var(--border); background:var(--card); }
.reg-r input[type=checkbox]{ opacity:0; transition:opacity .12s; }
.reg-r:hover input[type=checkbox], .reg-r input[type=checkbox]:checked, .reg-r.on input[type=checkbox]{ opacity:1; }
/* ФИО ЦЕЛИКОМ, без отдела и должности (ТЗ владельца 29.07.2026: «пусть
   подгружаются полностью фамилия, имя, отчество»). Два неразрывных куска —
   «Фамилия Имя» и «Отчество» — и пробел между ними: влезает в колонку — идёт
   одной строкой, не влезает — переносится РОВНО отчество, а фамилия с именем
   остаются вместе. Фамилия жирная: столбик читается сверху вниз при сортировке. */
.reg-emp{ font-size:13px; font-weight:500; line-height:1.3; min-width:0; }
.reg-emp .p1, .reg-emp .p2{ white-space:nowrap; }
.reg-emp .p1{ color:var(--text); }
.reg-emp .p2{ color:var(--text2); }
.reg-emp .ln{ font-weight:600; }
.reg-days{ text-align:left; }

/* Колонка «№ приказа»: отдельная, чтобы по номеру можно было сортировать. */
.reg-ordc{
  font-size:12px; font-variant-numeric:tabular-nums; color:var(--text2);
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.reg-ordc .no{ color:var(--text2); }

/* Шапка таблицы: сортировка кликом по колонке (ТЗ владельца 29.07.2026).
   Тихая — серая, без рамок; активная колонка помечена стрелкой. */
.reg-th{
  font:inherit; font-size:11px; font-weight:600;
  color:var(--text2); background:none; border:0; padding:0; text-align:left;
  display:inline-flex; align-items:center; gap:4px; white-space:nowrap; min-width:0;
}
.reg-th.srt{ cursor:pointer; }
.reg-th.srt:hover{ color:var(--text2); }
.reg-th.on{ color:var(--text); }
.reg-th .ar{ font-size:11px; }

/* источники — полные подписи; цвет строго по смыслу */
.reg-src{ gap:4px; flex-wrap:wrap; }
.reg-sc{
  font-size:11px; font-weight:500; border-radius:99px; padding:3px 8px; white-space:nowrap;
  display:inline-flex; align-items:center; gap:4px; cursor:help;
}
.reg-sc:before{ content:''; width:5px; height:5px; border-radius:50%; background:currentColor; opacity:.85; }
.reg-sc.yes{ background:var(--green-bg, #F0FDF4); color:#16A34A; }
.reg-sc.no{ background:var(--card2); color:var(--text2); }
.reg-sc.tr{ background:var(--orange-bg, #FFF7ED); color:#B45309; }

/* «Что не так» — причина и личное отличие строки. Здесь же живёт карточка по
   наведению, поэтому обрезать текст приходится ВНУТРЕННИМ span: overflow:hidden
   на самой ячейке срезал бы всплывающую карточку. */
.reg-note{ font-size:12px; color:var(--text2); line-height:1.4; min-width:0; position:relative; cursor:help; }
.reg-note .reg-note-t{ display:block; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.reg-note .reg-rl{ color:var(--text2); font-weight:500; }
.reg-note b{ color:var(--text2); font-weight:600; }
.reg-note small{ display:block; font-size:11px; margin-top:1px; }
/* «Вы это уже разбирали» — расхождение вернулось из-за изменившихся данных,
   а не потому, что работа пропала (ТЗ владельца 29.07.2026). */
.reg-note small.reg-wasch{ color:var(--amber); }
.reg-tr{ color:#B45309; font-weight:500; }

/* подвал: редкие переключатели */
.reg-foot{
  flex-shrink:0; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:12px 24px; border-top:1px solid var(--border); font-size:12px; color:var(--text2);
}
.reg-foot a{ color:var(--text2); text-decoration:none; border-bottom:1px dashed var(--border2, #D6DDE6); }
.reg-foot a:hover{ color:var(--text); }
.reg-foot .dot{ opacity:.5; }

/* массовые действия — плавающая панель, пока что-то выделено */
.reg-bulk{
  position:sticky; bottom:12px; z-index:12; margin:0 22px; border-radius:12px; border-top:0;
  background:var(--accent, #0F172A); color:var(--accent-text, #fff);
  box-shadow:0 10px 30px -10px rgba(16,24,40,.35); padding:8px 12px;
}
.reg-bulk .ec-btn{
  background:rgba(255,255,255,.1); border-color:rgba(255,255,255,.22); color:var(--accent-text, #fff);
}
.reg-bulk .ec-btn:hover{ background:rgba(255,255,255,.2); }

@media (max-width:720px){
  .reg-gh{ padding-left:16px; padding-right:16px; }
  .reg-foot{ padding-left:16px; padding-right:16px; }
  .reg-bulk{ margin-left:16px; margin-right:16px; }
}

/* Предупреждение о незагруженном источнике — всегда на виду, не в «Как считали»:
   без графика 1С всё перенесённое выглядит как «нет приказа». */
.reg-warn{
  margin:10px 0 0; padding:9px 12px; border-radius:12px; font-size:12px; line-height:1.5;
  background:var(--amber-bg, #FEF9C3); border:1px solid rgba(202,138,4,.3); color:var(--text2);
}
.reg-warn b{ color:var(--text); }
.reg-r.reg-done{ opacity:.55; }
.reg-expl{ grid-column:1/-1; margin:6px 0 2px; }
.reg-ok{ color:var(--green); font-weight:500; }

/* фильтры и порядок строк (ТЗ владельца 28.07.2026) */
.reg-flt{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin:10px 0 0; padding:12px 12px; background:var(--card2); border-radius:12px;
}
.reg-flt label{ font-size:11px; font-weight:500; color:var(--text2); }
.reg-flt select{
  font:inherit; font-size:13px; padding:4px 8px; border-radius:8px;
  border:1px solid var(--border); background:var(--card); color:var(--text);
}
.reg-rst{ font-size:12px; color:var(--text2); cursor:pointer; border-bottom:1px dashed var(--border2, #D6DDE6); }
.reg-rst:hover{ color:var(--text); }
.reg-ib.on{ background:var(--accent, #0F172A); border-color:var(--accent, #0F172A); color:var(--accent-text, #fff); }
.reg-fdot{
  position:absolute; top:3px; right:3px; width:6px; height:6px; border-radius:50%;
  background:var(--blue); box-shadow:0 0 0 2px var(--card);
}
.reg-ib{ position:relative; }
.reg-srt{
  font-size:12px; font-weight:500; color:var(--text2); cursor:pointer; white-space:nowrap;
  text-transform:none;
}
.reg-srt:hover{ color:var(--text2); }
.reg-cols > div:last-child{ text-align:right; }

/* ═══ КОМПАКТНАЯ ШАПКА ВКЛАДКИ (ТЗ владельца 28.07.2026) ════════════════════
   Было шесть ярусов до первой строки таблицы, и полоса состояний растягивалась
   на всю ширину: на мониторе 1920 px два числа тонули в 1800 px пустоты.
   Стало две строки: состояния компактным переключателем + инструменты справа,
   под ними — смысл состояния, объём данных и «Как считали». */
.reg-bar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.reg-tools{ display:flex; align-items:center; gap:8px; margin-left:auto; }
.reg-tools .reg-search{ width:200px; }

/* состояния: ширина по содержимому, число и подпись в одну строку */
.reg-states{ display:inline-flex; gap:2px; padding:3px; background:var(--card2);
             border:0; border-radius:12px; margin:0; overflow:visible; }
.reg-state{
  flex:0 0 auto; min-width:0; border:0; border-radius:8px; padding:8px 12px;
  display:inline-flex; align-items:center; gap:8px; background:transparent;
  color:var(--text2); white-space:nowrap;
}
.reg-state:before{ display:none; }
.reg-state .n{
  display:inline; font-size:15px; font-weight:600;
  font-variant-numeric:tabular-nums; color:var(--text2); margin:0;
}
.reg-state .l{ display:inline; font-size:13px; font-weight:500; color:inherit; margin:0; }
.reg-state:hover{ background:rgba(0,0,0,.04); }
.reg-state.on{ background:var(--card); box-shadow:0 1px 2px rgba(0,0,0,.08); color:var(--text); }
.reg-state.do.on .n{ color:var(--red); }
.reg-state.check.on .n{ color:var(--amber, #E8A317); }
.reg-state.ok.on .n{ color:var(--green); }
@media (prefers-color-scheme: dark){ .reg-state:hover{ background:rgba(255,255,255,.06); } }

/* вторая строка шапки */
.reg-line{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
           font-size:12px; color:var(--text2); margin:9px 2px 0; line-height:1.5; }
.reg-line .say{ color:var(--text2); }
.reg-line .dot{ opacity:.5; }
.reg-line a{ color:var(--text2); text-decoration:none; border-bottom:1px dashed var(--border2, #D6DDE6); }
.reg-line a:hover{ color:var(--text); }
.reg-line .warn{ color:var(--red); font-weight:600; }
.reg-head .reg-ntb{ margin-top:6px; border-top:1px solid var(--line, var(--border)); }

/* Ввод номера приказа вручную — блоком ПОД строкой, а не в колонке «Источники».
   Там ей доставалось 236 px на два поля, и введённый номер не был виден целиком
   (жалоба владельца 28.07.2026). Размер по содержимому: поля видны полностью,
   но окно не разрастается на весь экран. */
.reg-ordbox{
  grid-column:1/-1; margin:8px 0 2px; padding:12px 12px;
  background:var(--card2); border:1px solid var(--border); border-radius:12px;
}
.reg-obx-t{ font-size:11px; font-weight:600;
            color:var(--text2); margin-bottom:9px; }
.reg-obx-t span{ font-weight:600; text-transform:none; }
.reg-obx-r{ display:flex; align-items:flex-end; gap:12px; flex-wrap:wrap; }
.reg-obx-f{ display:flex; flex-direction:column; gap:4px; }
.reg-obx-f > span{ font-size:11px; color:var(--text2); }
.reg-obx-f .reg-oin{ width:240px; }
.reg-obx-f .reg-oin.date{ width:170px; }
.reg-obx-h{ font-size:12px; color:var(--text2); margin-top:9px; line-height:1.5; }
.reg-obx-h b{ color:var(--text2); font-weight:500; font-size:11px;
              border:1px solid var(--border2, #D6DDE6); border-radius:8px; padding:1px 4px; }

/* Полоса действий над всем срезом (шаг 2, ТЗ владельца 30.07.2026). Заменяет
   кнопки в заголовках групп из старого экрана: групп в срезе нет, список плоский.
   Показывается только когда есть что делать пачкой. */
.reg-slice{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:8px 24px; border-bottom:1px solid var(--border);
  background:var(--blue-bg, #EFF6FF); font-size:12px; color:var(--text2);
}
.reg-slice b{ color:var(--text); font-weight:600; }
.reg-slice .sp{ flex:1; }

/* Служебные списки среза (уволенные, чужое юрлицо, нераспознанные ФИО).
   Там в колонке пояснения — не пометка, а сам смысл строки: «помечено вручную»
   против «определено автоматически». Обрезать его многоточием нельзя, поэтому
   здесь текст переносится, а не прячется (ТЗ владельца 30.07.2026). */
.reg-side .reg-note-t{ white-space:normal; overflow:visible; text-overflow:clip; }
.reg-side .reg-note{ cursor:default; }

/* Формы правки ВНУТРИ панели разбора (ТЗ владельца 30.07.2026).
   Панель — 402 px, а формы рисовались по меркам списка во всю ширину: поле
   периода фиксированные 218 px плюс распорка flex:1 выталкивали «Сохранить»
   за край, и кнопки было не достать. Внутри панели поле тянется по месту,
   ряд переносится, распорка не работает — кнопки всегда видны. */
.reg-panel .reg-perin{ flex-wrap:wrap; row-gap:8px; }
.reg-panel .reg-perfield{ width:auto; flex:1 1 150px; min-width:0; }
.reg-panel .reg-perin > span[style*="flex:1"]{ display:none; }
.reg-panel .reg-perin .ec-btn{ flex:0 0 auto; }
.reg-panel .reg-picks{ flex-wrap:wrap; }
/* Тот же расчёт для формы ввода приказа. */
.reg-panel .reg-obx-r{ flex-wrap:wrap; row-gap:8px; }
.reg-panel .reg-obx-f{ flex:1 1 130px; min-width:0; }
.reg-panel .reg-oin{ width:100%; min-width:0; }
.reg-panel .reg-obx-r > span[style*="flex:1"]{ display:none; }
.reg-panel .reg-obx-r .ec-btn{ flex:0 0 auto; }

/* ===== ОКНО «КАКОЙ ОТПУСК СДВИГАЕМ» (ТЗ владельца 04.08.2026) =============
   Приказ 1С о переносе приходит на один период, а у отпуска их бывает
   несколько. Окно спрашивает, какой двигаем и что это — новый сдвиг или
   исправление дат. Оформление то же, что у сверок: спокойные карточки-варианты,
   синяя главная кнопка, оранжевым — только перенос. */
.vhq { padding: 16px 24px 8px; }
.vhq-h { margin-bottom: 12px; }
.vhq-t { font-size:15px; font-weight:600; }
.vhq-s { font-size:12px; color:var(--text2); margin-top: 3px; line-height: 1.5; }
.vhq-src {
  background: var(--orange-bg, #FAF4EA); border: 1px solid rgba(176, 124, 60, .22);
  border-radius: 12px; padding: 11px 13px; font-size:13px; line-height: 1.55; margin-bottom: 14px;
}
.vhq-src .k {
  font-size:11px; font-weight:600;
  color: #B07C3C; margin-bottom: 4px;
}
.vhq-src b { font-variant-numeric: tabular-nums; }
.vhq-bt {
  font-size:11px; font-weight:600;
  color:var(--text2); margin: 0 0 8px;
}
.vhq-opt {
  display: flex; gap: 12px; align-items: flex-start; padding: 12px 12px; border-radius: 8px;
  border: 1px solid var(--border); cursor: pointer; margin-bottom: 7px; background: var(--card);
  transition: border-color .12s, background .12s;
}
.vhq-opt:hover { border-color: var(--border2, #D6DDE6); }
.vhq-opt.on { border-color: var(--act, var(--act)); background: var(--blue-bg, #EFF6FF); }
.vhq-opt .rd {
  width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--border2, #D6DDE6);
  flex: 0 0 auto; margin-top: 2px; position: relative;
}
.vhq-opt.on .rd { border-color: var(--act, var(--act)); }
.vhq-opt.on .rd:after {
  content: ''; position: absolute; inset: 2.5px; border-radius: 50%; background: var(--act, #2563EB);
}
.vhq-opt .tx { min-width: 0; }
.vhq-opt .nm { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.vhq-opt .sub { font-size: 12px; color: var(--text3); margin-top: 2px; line-height: 1.45; }
.vhq-opt .tag {
  margin-left: auto; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 99px;
  background: var(--orange-bg, #FAF4EA); color: #B07C3C; white-space: nowrap;
}
/* Два варианта «что это» — рядом, каждый со своим объяснением. */
.vhq-how { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.vhq-how .vhq-opt { margin: 0; flex-direction: column; gap: 8px; }
.vhq-how .vhq-opt .top { display: flex; gap: 8px; align-items: center; }
.vhq-prev {
  background: var(--card2); border-radius: 12px; padding: 12px 12px;
  font-size: 13px; line-height: 1.6; margin: 12px 0 4px;
}
.vhq-prev .was { color: var(--text3); text-decoration: line-through; font-variant-numeric: tabular-nums; }
.vhq-prev .now { font-weight: 600; font-variant-numeric: tabular-nums; }
.vhq-prev .keep { color: var(--text2); font-size: 12px; margin-top: 6px; }
.vhq-f { display: flex; gap: 8px; justify-content: flex-end; padding: 16px 0 12px; }
@media (max-width: 560px) { .vhq-how { grid-template-columns: 1fr; } }

/* ═══ «ЧЬИ ЭТО СОТРУДНИКИ?» — разбор принадлежности к юрлицу (app-orgclaim.js,
   ТЗ владельца 04.08.2026). Список по ЛЮДЯМ, а не по строкам: у одного человека
   три отпуска — это одно дело, а не три вопроса. ══════════════════════════════ */
.oc-empty{ padding:22px 12px; text-align:center; font-size:13px; color:var(--text2); line-height:1.55; }
.oc-bar{ display:flex; align-items:center; gap:12px; margin:14px 0 8px; flex-wrap:wrap; }
.oc-cnt{ font-size:12px; color:var(--text3); }
.oc-list{ border:1px solid var(--border); border-radius:12px; overflow:hidden; max-height:46vh; overflow-y:auto; }
.oc-row{
  display:flex; align-items:center; gap:12px; padding:12px 12px; cursor:pointer;
  font-size:13px; background:var(--card);
}
.oc-row + .oc-row{ border-top:1px solid var(--border); }
.oc-row:hover{ background:var(--card2); }
.oc-row.on{ background:var(--card2); }
.oc-box{
  width:16px; height:16px; border-radius:4px; flex-shrink:0; text-align:center;
  border:1.5px solid var(--border2, #D6DDE6); background:transparent;
  color:#fff; font-size:11px; line-height:14px;
}
.oc-row.on .oc-box{ background:var(--act, var(--act)); border-color:var(--act, var(--act)); }
.oc-main{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.oc-fio{ font-weight:600; }
.oc-where{ font-size:12px; color:var(--text3); line-height:1.45; }
.oc-n{ font-size:12px; color:var(--text3); white-space:nowrap; }
.oc-more{ flex-shrink:0; }
.oc-acts{ display:flex; gap:8px; flex-wrap:wrap; margin-top:12px; }
.oc-done-h{ margin-top:16px; font-size:13px; font-weight:600; color:var(--text2); cursor:pointer; user-select:none; }
.oc-done-h:hover{ color:var(--text); }
.oc-done-s{ font-weight:500; color:var(--text3); }
.oc-done{ margin-top:8px; }
.oc-done .oc-row{ cursor:default; }
.oc-done .oc-row:hover{ background:var(--card); }
@media (max-width:720px){
  .oc-row{ flex-wrap:wrap; }
  .oc-n{ margin-left:28px; }
}

/* ═══ ОКНО «ЗАВЕСТИ СТРОКУ УЧЁТА» (app-rowcreate.js, ТЗ владельца 04.08.2026) ══
   Перенесено с макета один в один: блок «откуда знаем» с точками-источниками,
   поля с подписями и кнопкой «изменить», плашки-пояснения, подвал с действиями.
   Владелец: «всё, что на макете, должно быть на сайте до мельчайших деталей».

   ПРИВЕДЕНО К СВОДУ 15.09.2026 (окно делалось 04.08 — до свода от 16.08):
   подписи и имя сотрудника были --text3 (контраст 2,6 светлая / 2,2 тёмная —
   «не для текста», п. 6) → --text2; насыщенность 600 стояла у подписей строк,
   значений и полей (20 мест против 4 в карточке отпуска) → 500, 600 только у
   заголовка окна (п. 1); отступы 10/14 → шкала 12/16 (п. 12-бис). */
.rc-h{ display:flex; align-items:flex-start; gap:12px; padding:2px 0 13px; border-bottom:1px solid var(--border); }
.rc-t{ font-size:15px; font-weight:600; letter-spacing:-.2px; }
.rc-w{ font-size:12px; color:var(--text2); margin-top:2px; }
.rc-x{ margin-left:auto; width:28px; height:28px; border-radius:8px; border:1px solid var(--border);
       background:var(--card); color:var(--text2); font-size:13px; line-height:1; cursor:pointer;
       display:flex; align-items:center; justify-content:center; flex:none; font-family:inherit; }
.rc-x:hover{ background:var(--card2); color:var(--text); }
.rc-b{ padding:16px 0 4px; }
/* ШАПКА / ТЕЛО / ПОДВАЛ — тремя частями (свод, п. 13 «Модальные окна»; 15.09.2026).
   Окно жило внутри .mc с общим отступом 24 и прокруткой всего окна: на ноутбуке
   720 оно выходило 741 px, прокручивалось целиком (612/741), и кнопка «Завести
   строку» уезжала за нижний край. Теперь прокручивается только тело, шапка и
   подвал стоят — как у карточки отпуска (.mc-vc). Класс ставит app-rowcreate.js
   после showMo (тот каждый раз начинает с чистой .mc). */
.mc.mc-rc{ padding:0; display:flex; flex-direction:column; overflow:hidden; }
.mc-rc .rc-h{ padding:16px 24px 13px; flex-shrink:0; }
.mc-rc .rc-b{ flex:1; min-height:0; overflow-y:auto; padding:16px 24px 8px; }
.mc-rc .rc-a{ flex-shrink:0; padding:16px 24px; margin:0; }

/* откуда знаем */
.rc-src{ background:var(--card2); border:1px solid var(--border); border-radius:12px; padding:12px 12px; margin-bottom:16px; }
.rc-src-t{ font-size: 11px; font-weight: 500; 
           color:var(--text2); margin-bottom:6px; }
.rc-src-r{ display:flex; align-items:center; gap:8px; font-size: 13px; padding:2px 0; }
.rc-dot{ width:7px; height:7px; border-radius:50%; flex:none; background:var(--green-dark,#16A34A); }
.rc-src-r.off{ color:var(--text2); }
.rc-src-r.off .rc-dot{ background:var(--border2,#D6DDE6); }

/* поля */
.rc-f{ display:grid; grid-template-columns:118px 1fr auto; gap:4px 12px; align-items:center;
       padding:12px 0; border-bottom:1px solid var(--border); }
.rc-f:last-of-type{ border-bottom:0; }
.rc-f.col{ align-items:start; }
.rc-l{ font-size: 11px; font-weight: 500; color:var(--text2); }
.rc-f.col .rc-l{ padding-top:8px; }
.rc-v{ font-size:13px; font-weight: 500; }
.rc-v .dim{ font-weight:400; color:var(--text2); }
.rc-hint{ grid-column:2 / 4; font-size:12px; color:var(--text2); margin-top:-2px; }
/* «изменить» — кнопка, значит мелкая ступень 28 (было 19). */
.rc-edit{ font:inherit; font-size:12px; font-weight:500; color:var(--act,#2563EB); background:none;
          border:0; padding:2px 4px; cursor:pointer; min-height:28px; }
.rc-edit:hover{ text-decoration:underline; }

/* поля ввода и выбор вида */
.rc-in{ font:inherit; font-size:13px; font-weight:500; padding:8px 12px; border:1px solid var(--border2,#D6DDE6);
        border-radius:8px; background:var(--card); color:var(--text); min-width:120px; }
.rc-in:focus{ outline:none; border-color:var(--act,var(--act)); }
.rc-dates{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.rc-dates .sep{ color:var(--text3); }
.rc-sel{ font:inherit; font-size:13px; font-weight:500; padding:7px 30px 8px 12px;
         border:1px solid var(--act,#2563EB); border-radius:8px; background:var(--card); color:var(--text);
         width:100%; -webkit-appearance:none; appearance:none;
         background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='none' stroke='%232563EB' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
         background-repeat:no-repeat; background-position:right 11px center; }
.rc-sel:focus{ outline:none; }
.rc-opts{ border:1px solid var(--act,#2563EB); border-radius:12px; margin-top:6px; overflow:hidden; }
.rc-opt{ padding:8px 12px; font-size:13px; border-bottom:1px solid var(--border); cursor:pointer;
         background:var(--card); }
.rc-opt:last-child{ border-bottom:0; }
.rc-opt:hover{ background:var(--card2); }
.rc-opt.on{ background:var(--act-bg); font-weight:500; }
.rc-opt .h{ font-size:11px; color:var(--text2); font-weight:400; margin-left:6px; }

/* плашки-пояснения */
.rc-note{ display:flex; gap:8px; background:var(--card2); border:1px solid var(--border); border-radius:12px;
          padding:12px; font-size:12px; color:var(--text2); line-height:1.55; margin:16px 0 0; }
.rc-note b{ color:var(--text); font-weight:500; }
/* Значок — линейный SVG (свод, п. 9), а не «ⓘ»/«⚠» из шрифта: на Windows они
   рисовались другой гарнитурой и другого размера. */
.rc-note .ic{ flex:none; color:var(--text2); display:inline-flex; margin-top:1px; }
.rc-note.warn{ background:var(--amber-bg,rgba(217,119,6,.10)); border-color:rgba(217,119,6,.32); }
.rc-note.warn .ic{ color:#D97706; }

/* подвал */
.rc-a{ display:flex; gap:8px; justify-content:flex-end; align-items:center; flex-wrap:wrap;
       padding:16px 0 2px; margin-top:16px; border-top:1px solid var(--border); }
.rc-btn{ font:inherit; font-size:13px; font-weight:500; padding:8px 14px; border-radius:8px;
         border:1px solid var(--border); background:var(--card); color:var(--text); cursor:pointer; }
.rc-btn:hover{ background:var(--card2); }
.rc-btn.p{ background:var(--act-bg); border-color:var(--act-line); color:var(--act); }
.rc-btn.p:hover{ border-color:var(--act); }
[data-theme="dark"] .rc-btn.p{ color:var(--act-hover); }
.rc-btn.ghost{ border-color:transparent; color:var(--text2); }
.rc-btn.ghost:hover{ background:var(--card2); }

/* ═══ ОКНО «ПЕРЕВЕСТИ В ТАБЛИЦУ УЧЁТА» (app-adopt.js) ════════════════════════
   Второй заход, ТЗ владельца 06.08.2026: «стало маленьким, обрезанным и
   неинформативным». Разбор того, что было не так:
     • у .mc-wide padding:0 — заголовок, счётчик и кнопки упирались в самый край
       окна, правый столбец подрезался;
     • подписей у полей не было вовсе: два поля с датами, два выпадающих списка —
       и догадайся, где исходные даты, а где новые;
     • «Приказ» и «Комментарий» занимали у КАЖДОЙ записи отдельную строку, из-за
       чего одна запись весила 195 px и на экран влезало две из одиннадцати;
     • шапка и кнопки уезжали при прокрутке — сколько отмечено и куда нажимать,
       было видно только в начале и в конце списка.
   Стало: окно устроено как сама таблица учёта — закреплённая шапка, строка
   колонок с подписями, прокручиваемый список, закреплённый подвал с кнопками.
   Одна запись — одна строка (~40 px), перенос — подстрокой под ней. */
.ado{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.ado-head{ padding:16px 24px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
.ado-t{ font-size:15px; font-weight:600; letter-spacing:-.3px; }
.ado-sum{ margin-top:4px; font-size:13px; font-weight:600; color:var(--text2); }
.ado-sum b{ color:var(--text); }
.ado-hint{ margin-top:6px; font-size:13px; color:var(--text3); line-height:1.5; }
.ado-tools{ display:flex; align-items:center; gap:8px; margin-top:11px; }
.ado-cnt{ font-size:13px; font-weight:600; color:var(--text2); }
/* Список НИКОГДА не схлопывается в ноль.
   Было (случай владельца 08.08.2026): окно открывается, сверху «1 отпусков
   у 1 сотрудников · отмечено 28 дн.», внизу «Перевести отмеченные · 1», а между
   ними — только фамилия и пустота. Строки при этом честно лежали в разметке:
   замер на стенде показал высоту области списка 8 px при содержимом на 3102 px.
   Причина — flex:1 внутри окна, у которого высота задана только как max-height:
   свободного места нет, и flex-элементу достаётся ноль, а весь список уезжает
   в невидимую прокрутку. Портал предлагал перевести отпуск, которого не
   показывал. min-height ставит этому предел: список всегда занимает хотя бы
   несколько строк, дальше растёт по месту. */
.ado-body{ flex:1 1 auto; min-height:240px; overflow-y:auto; overflow-x:auto; padding:0 24px 8px; }
@media (max-height:700px){ .ado-body{ min-height:150px; } }
.ado-foot{ display:flex; align-items:center; gap:12px; padding:16px 24px;
           border-top:1px solid var(--border); background:var(--card); flex-shrink:0; }
/* Пока есть строки с ошибками, «Перевести» не работает — и должна ВЫГЛЯДЕТЬ
   неработающей. У .btn в проекте своего вида для disabled нет, и кнопка молча
   не отвечала на нажатие. */
.ado-foot .btn[disabled]{ opacity:.45; cursor:not-allowed; }

/* Строка колонок и строка отпуска — одна и та же сетка, поэтому подписи всегда
   стоят ровно над своими полями. */
.ado-cols, .ado-row{
  display:grid;
  grid-template-columns:20px 112px 10px 112px 46px minmax(150px,1.15fr) 132px 118px minmax(140px,1.5fr) 112px 34px;
  gap:4px 8px; align-items:center;
}
.ado-cols{ position:sticky; top:0; z-index:3; padding:8px 12px 8px; margin:0 -10px;
          background:var(--card); border-bottom:1px solid var(--border);
          font-size: 11px; font-weight: 600; 
          color:var(--text3); }
.ado-cols .c{ text-align:center; }

.ado-row{ padding:8px 12px; margin:0 -10px; border-radius:8px; border:1px solid transparent; }
.ado-row + .ado-row{ border-top:1px solid var(--border); border-radius:0; }
.ado-row:hover{ background:var(--card2); }
.ado-row.err{ border-color:var(--red); background:var(--red-bg); border-radius:8px; }
.ado-row.off{ opacity:.45; }
.ado-cb{ width:16px; height:16px; accent-color:#2563EB; cursor:pointer; }
.ado-sep{ color:var(--text3); text-align:center; }
.ado-days{ font-size:12px; font-weight:600; color:var(--text2); text-align:center; white-space:nowrap; }

/* Поля правки. Ширину и отступы задаём сами: у .dp-field (календарь) свои,
   более крупные — в строке таблицы они не помещаются. */
.ado-in, input.ado-in.dp-field{ font:inherit; font-size:13px; font-weight:600; padding:6px 9px;
        width:100%; border:1px solid var(--border2,#D6DDE6); border-radius:8px;
        background:var(--card); color:var(--text); min-width:0; }
.ado-in:focus, input.ado-in.dp-field:focus{ outline:none; border-color:var(--act,var(--act)); }
.ado-in::placeholder{ color:var(--text3); font-weight:400; }
.ado-sel{ font:inherit; font-size:13px; font-weight:600; padding:6px 24px 8px 8px; width:100%;
         border:1px solid var(--border2,#D6DDE6); border-radius:8px; background:var(--card);
         color:var(--text); -webkit-appearance:none; appearance:none; cursor:pointer; min-width:0;
         background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='none' stroke='%2394A3B8' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
         background-repeat:no-repeat; background-position:right 8px center; }
.ado-sel:focus{ outline:none; border-color:var(--act,var(--act)); }

/* Кнопка в колонке «Перенос»: у обычного отпуска — «Перенести», у переноса —
   «＋ период». Кнопка видимая, а не по наведению: спрятанное действие в этом
   окне человек просто не найдёт. */
.ado-mini{ font:inherit; font-size:12px; font-weight:600; padding:4px 8px; width:100%;
          border:1px solid var(--border); border-radius:8px; background:var(--card);
          color:var(--text2); cursor:pointer; white-space:nowrap; }
.ado-mini:hover{ background:var(--card2); color:var(--text); border-color:var(--text3); }
.ado-x{ font:inherit; font-size:13px; line-height:1; padding:4px 6px; border:0; border-radius:8px;
       background:none; color:var(--text3); cursor:pointer; }
.ado-x:hover{ background:var(--card3); color:var(--red); }

/* «Убрать» — удаление записи карточки прямо из окна. Приглушена по умолчанию и
   краснеет по наведению: действие разрушительное, лезть в глаза ему незачем,
   но и прятать его нельзя — ради него окно и открывают, когда отпуска не было. */
.ado-del{ display:inline-flex; align-items:center; justify-content:center; width:100%; padding:4px 0;
         border:1px solid transparent; border-radius:8px; background:none; color:var(--text3);
         cursor:pointer; }
.ado-del:hover{ background:var(--red-bg); border-color:var(--red); color:var(--red); }

/* Откуда взялась запись: год и след появления. Мелкой строкой под своей записью —
   это справка, а не поле для правки. */
.ado-meta{ grid-column:2 / -1; font-size:11px; font-weight:600; color:var(--text3);
          padding-bottom:2px; }
.ado-meta b{ color:var(--orange); font-weight:600; }

/* Перенос — подстрокой под своим отпуском. Слева подпись, чтобы строка читалась
   слева направо: «перенесён на» → даты → сколько дней. */
.ado-tr{ grid-column:2 / -1; margin:1px 0; padding:4px 8px; border-radius:8px;
        background:var(--orange-bg); border:1px solid var(--orange); justify-self:start; }
.ado-tr-row{ display:grid; grid-template-columns:18px 128px 104px 10px 104px 52px 28px;
            gap:8px; align-items:center; }
.ado-tr-row + .ado-tr-row{ margin-top:3px; }
.ado-tr .ado-in, .ado-tr input.ado-in.dp-field{ padding:4px 8px; font-size: 13px; }
.ado-tr-l{ font-size:11px; font-weight: 600; color:var(--orange); 
          white-space:nowrap; }
.ado-err{ grid-column:2 / -1; font-size:12px; font-weight: 600; color:var(--red); padding-bottom:3px; }

/* Заголовок группы: кто это. Одного ФИО мало — нужны отдел, табельный, остаток. */
.ado-emp{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
         margin:14px 0 2px; padding-top:12px; border-top:1px solid var(--border); }
.ado-emp .n{ font-size:13px; font-weight:600; color:var(--text); }
.ado-emp .i{ font-size:12px; font-weight:600; color:var(--text3); }
.ado-emp:first-child{ border-top:0; margin-top:6px; padding-top:0; }

/* Плашка слияния — одной строкой над своими записями. */
.ado-mg{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:6px 0 2px;
        padding:7px 11px; border-radius:8px; font-size:12px; line-height:1.45; }
.ado-mg.ok{ background:var(--green-bg); border:1px solid var(--green); color:var(--text2); }
.ado-mg.no{ background:var(--red-bg); border:1px solid var(--red); color:var(--text); }
.ado-mg .sp{ flex:1; }

@media (max-width:1180px){
  .ado-cols, .ado-row{ grid-template-columns:20px 104px 10px 104px 40px minmax(120px,1fr) 112px 96px minmax(110px,1.2fr) 96px 32px; }
}

/* ═══ ОКНО «ПРОВЕРКА ЦЕЛОСТНОСТИ ОТПУСКОВ» (app-viedit.js) ═══════════════════
   Перенесено из утверждённого макета (scratchpad/makety/vacintegrity.html,
   ТЗ владельца 06.08.2026) — размеры, цвета и отступы взяты дословно.
   Все правила живут внутри .viw: имена из макета (.row, .chip, .in, .sel) в
   портале уже заняты другими блоками, и без обёртки окно ломало бы чужую вёрстку.

   Раскладка: слева список разделов, справа шапка раздела с инструкцией, строки
   -редакторы и подвал с действием пачкой. Раньше это был свёрнутый список
   категорий без единого действия — владелец: «оно ничего не даёт сделать». */
.viw{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }

/* Шапка окна */
.viw .vh{ padding:16px 24px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
.viw .vh-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.viw .vh-t{ display:flex; align-items:center; gap:8px; }
.viw .vh-t .ico{ color:var(--text2); display:flex; }
.viw .vh-t h1{ margin:0; font-size:15px; font-weight:600; letter-spacing:-.3px; }
.viw .vh-t h1 span{ font-size:12px; font-weight:500; color:var(--text3); }
.viw .vh-x{ font:inherit; font-size:13px; border:1px solid var(--border); background:var(--card);
            border-radius:8px; padding:4px 12px; cursor:pointer; color:var(--text2); }
.viw .vh-x:hover{ background:var(--card2); }
.viw .vh-sub{ font-size:12px; color:var(--text3); margin-top:2px; }
.viw .vh-chips{ display:flex; flex-wrap:wrap; gap:8px; margin-top:11px; }
.viw .chip{ font-size:12px; font-weight:600; padding:4px 10px; border-radius:99px;
            border:1px solid var(--border); background:var(--card2); color:var(--text2); }
.viw .chip.danger{ background:var(--red-bg); border-color:var(--red); color:#B91C1C; }
.viw .chip.ok{ background:var(--green-bg); border-color:var(--green); color:#15803D; }

/* Тело: слева разделы, справа редактор */
.viw .vb{ flex:1; min-height:0; display:grid; grid-template-columns:246px minmax(0,1fr); }
.viw .vnav{ border-right:1px solid var(--border); overflow-y:auto; padding:12px 0; background:var(--card); }
.viw .vnav-h{ font-size: 11px; font-weight: 600; 
              color:var(--text3); padding:8px 16px 4px; }
.viw .vni{ display:flex; align-items:center; gap:8px; padding:8px 16px; cursor:pointer; font-size:13px;
           color:var(--text2); border-left:3px solid transparent; }
.viw .vni:hover{ background:var(--card2); }
.viw .vni.on{ background:var(--act-bg); border-left-color:var(--act,var(--act)); color:var(--text); font-weight:600; }
.viw .vni .dot{ width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.viw .vni .nm{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.viw .vni .n{ font-size:12px; font-weight:600; color:var(--text3); }
.viw .vni.on .n{ color:var(--act,var(--act)); }

.viw .vmain{ display:flex; flex-direction:column; min-height:0; }
.viw .vm-head{ padding:16px 24px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
.viw .vm-t{ font-size:15px; font-weight: 600; display:flex; align-items:center; gap:8px; }
.viw .vm-t .bdg{ font-size: 11px; font-weight: 600; 
                 padding:2px 8px; border-radius:99px; }
.viw .bdg.act{ background:var(--red-bg); color:#B91C1C; }
.viw .bdg.info{ background:var(--green-bg); color:#15803D; }
.viw .vm-x{ font-size:13px; color:var(--text2); line-height:1.55; margin-top:5px; max-width:96ch; }
.viw .vm-tools{ display:flex; align-items:center; gap:8px; margin-top:11px; }
.viw .vm-cnt{ font-size:13px; font-weight:600; color:var(--text2); }
.viw .vm-body{ flex:1; min-height:0; overflow-y:auto; padding:0 20px 12px; }

/* Кнопки окна — из макета. Своё имя (.vbtn), чтобы не спорить с .btn портала. */
.viw .vbtn{ font:inherit; font-size:12px; font-weight:500; padding:6px 10px; border-radius:8px;
            border:1px solid var(--border); background:var(--card); color:var(--text); cursor:pointer; }
.viw .vbtn:hover{ background:var(--card2); }
.viw .vbtn.p{ background:var(--blue-bg); border-color:rgba(37,99,235,.22); color:var(--blue2); }
.viw .vbtn.p:hover{ border-color:var(--act); }
[data-theme="dark"] .viw .vbtn.p{ color:var(--act-hover); }
/* .dgr — «опасная» роль: удаление. Красным словом, а не тёмной заливкой. */
.viw .vbtn.dgr{ color:#B91C1C; border-color:#FCA5A5; }
.viw .vbtn.dgr:hover{ background:var(--red-bg); }
[data-theme="dark"] .viw .vbtn.dgr{ color:#F87171; }
.viw .vbtn[disabled]{ opacity:.45; cursor:not-allowed; }

/* Строка-редактор: колонки макета до пикселя */
.viw .gr{ display:grid; gap:4px 7px; align-items:center; }
.viw .cols, .viw .vrow{
  grid-template-columns:18px minmax(128px,1.05fr) 98px 8px 98px 38px minmax(112px,.9fr) 108px 146px 104px;
}
.viw .cols{ position:sticky; top:0; z-index:3; background:var(--card); padding:8px 8px 8px; margin:0 -8px;
            border-bottom:1px solid var(--border); font-size: 11px; font-weight: 600;
            color:var(--text3); }
.viw .cols .c{ text-align:center; }
.viw .vrow{ padding:8px 8px; margin:0 -8px; border-radius:8px; border:1px solid transparent; }
.viw .vrow + .vrow{ border-top:1px solid var(--border); border-radius:0; }
.viw .vrow:hover{ background:var(--card2); }
.viw .vrow.bad{ background:var(--red-bg); border-color:#FCA5A5; border-radius:8px; }
.viw .cb{ width:16px; height:16px; accent-color:#2563EB; cursor:pointer; }
.viw .emp{ font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.viw .emp small{ display:block; font-size:11px; font-weight:500; color:var(--text3); }
.viw .in, .viw input.in.dp-field{ font:inherit; font-size:13px; font-weight:600; padding:6px 9px;
       width:100%; min-width:0; border:1px solid var(--border2,#D6DDE6); border-radius:8px;
       background:var(--card); color:var(--text); }
.viw .in:focus, .viw input.in.dp-field:focus{ outline:none; border-color:var(--act,var(--act)); }
.viw .in[readonly]{ background:var(--card2); color:var(--text2); cursor:default; }
.viw .sel{ font:inherit; font-size:13px; font-weight:600; padding:6px 24px 8px 8px; width:100%; min-width:0;
     border:1px solid var(--border2,#D6DDE6); border-radius:8px; background:var(--card); color:var(--text);
     -webkit-appearance:none; appearance:none; cursor:pointer;
     background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='none' stroke='%2394A3B8' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
     background-repeat:no-repeat; background-position:right 8px center; }
.viw .sel:focus{ outline:none; border-color:var(--act,var(--act)); }
.viw .sep{ color:var(--text3); text-align:center; }
.viw .days{ font-size:12px; font-weight:600; color:var(--text2); text-align:center; }
.viw .src{ font-size:12px; color:var(--text2); line-height:1.35; }
.viw .src b{ font-weight:600; color:var(--text); }
.viw .src i{ font-style:normal; color:var(--text3); }
.viw .src.unknown{ color:var(--text3); }
.viw .acts{ display:flex; gap:4px; justify-content:flex-end; }
.viw .mini{ font:inherit; font-size:12px; font-weight:600; padding:4px 8px; border-radius:8px;
            border:1px solid var(--border); background:var(--card); color:var(--text2); cursor:pointer;
            white-space:nowrap; }
.viw .mini:hover{ background:var(--card2); color:var(--text); border-color:var(--text3); }
.viw .mini.dgr:hover{ background:var(--red-bg); color:#B91C1C; border-color:#FCA5A5; }

/* Подстрока-объяснение под проблемной строкой */
.viw .why{ grid-column:2 / -1; font-size:12px; line-height:1.45; padding:6px 10px; border-radius:8px;
           margin:1px 0 3px; display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.viw .why .txt{ flex:1; min-width:220px; }
.viw .why.red{ background:var(--red-bg); border:1px solid #FCA5A5; color:#7F1D1D; }
.viw .why.orange{ background:var(--orange-bg); border:1px solid var(--orange); color:#78350F; }
.viw .why.grey{ background:var(--card2); border:1px solid var(--border); color:var(--text2); }
.viw .why b{ font-weight: 600; }
.viw .why .tag{ display:inline-block; font-size: 11px; font-weight: 600; 
                padding:1px 8px; border-radius:99px;
                background:rgba(0,0,0,.06); margin-right:7px; }

/* Свёрнутая «норма»: строки, которые портал посмотрел и претензий не имеет.
   Раздел обязан отвечать на вопрос «что чинить», поэтому норма лежит под
   спокойной серой полосой и разворачивается по кнопке (владелец 07.08.2026). */
.viw .vnorm{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
             margin:10px 0 4px; padding:8px 12px; border-radius:8px;
             background:var(--card2); border:1px solid var(--border);
             font-size:12px; line-height:1.45; color:var(--text2); }
.viw .vnorm .txt{ flex:1; min-width:220px; }
.viw .vnorm b{ font-weight:600; color:var(--text); }

/* Подвал раздела */
.viw .vf{ display:flex; align-items:center; gap:8px; padding:12px 24px;
          border-top:1px solid var(--border); flex-shrink:0; background:var(--card); }
.viw .vf .sp{ flex:1; }
.viw .vf-note{ font-size:12px; color:var(--text3); }

/* Разделы только для чтения (совместители, уволенные) */
.viw .ro{ padding:16px 8px; font-size: 13px; color:var(--text2); }
.viw .ro table{ width:100%; border-collapse:collapse; margin-top:10px; }
.viw .ro th{ text-align:left; font-size: 11px; font-weight: 600; 
             color:var(--text3); padding:8px 8px; border-bottom:1px solid var(--border); }
.viw .ro td{ padding:8px 8px; border-bottom:1px solid var(--border); font-size: 13px; }
.viw .note{ margin:12px 0 0; padding:8px 12px; border-radius:8px; background:var(--blue-bg);
            border:1px solid #BFDBFE; font-size:12px; color:#1E3A8A; line-height:1.5; }
.viw .vempty{ padding:34px 12px; text-align:center; color:var(--text2); font-size:13px; }

[data-theme="dark"] .viw .note{ background:rgba(59,130,246,.12); border-color:rgba(59,130,246,.35); color:#BFDBFE; }
[data-theme="dark"] .viw .vbtn.p, [data-theme="dark"] .viw .vbtn.dgr{ background:#E5E7EB; border-color:#E5E7EB; color:#111827; }
[data-theme="dark"] .viw .why.red{ color:#FCA5A5; }
[data-theme="dark"] .viw .why.orange{ color:#FCD34D; }

@media (max-width:1180px){
  .viw .vb{ grid-template-columns:200px minmax(0,1fr); }
  .viw .cols, .viw .vrow{
    grid-template-columns:18px minmax(110px,1fr) 92px 8px 92px 34px minmax(100px,.8fr) 96px 120px 96px;
  }
}

/* Кнопка удаления В СТРОКЕ СПИСКА. Обычная .btn-d красная всегда — это верно
   для одиночной кнопки в окне, но не для списка: в карточке сотрудника таких
   строк десяток, и десять красных рамок подряд — предупреждение, которое
   перестают читать (тот же урок, что в таблице учёта, 16.08.2026).
   Здесь кнопка тихая и краснеет под курсором. */
.btn.btn-dq { color: var(--text2); }
.btn.btn-dq:hover { color: #B91C1C; border-color: #FCA5A5; background: var(--red-bg); }
[data-theme="dark"] .btn.btn-dq:hover { color: #F87171; border-color: #F87171; }

/* ═══ СЛОВО-СТАТУС ОТПУСКА — ОДНО НА ПОРТАЛ ═════════════════════════════════
   Заведено в app-table.js 16.08.2026 (макет «вариант Г»), перенесено сюда
   16.08.2026: теми же классами живут теперь таблица учёта и строка задачи на
   Главной и на странице «Задачи». Общая вещь не должна лежать в модуле одного
   экрана — на этом уже обожглись с кнопкой .ec-btn, которую из app-empcheck.js
   тянули семнадцать файлов.

   Заливки и точки у плашки нет: слово само цветное. Отсюда два набора оттенков.
   Затемнённые проходят на белом (4.55–4.62) и проваливаются на тёмном (3.4);
   исходные цвета на тёмном проходят сами (4.57–7.82). */
.tbl-note-ok   { color:#12823B; }
.tbl-note-move { color:#9D6507; }
.tbl-note-no   { color:#63738A; }
/* «План» — ТОТ ЖЕ ТОН, ЧТО У ТОЧКИ И ПОЛОСЫ (замечание владельца 04.09.2026).
   Здесь стояло #3472D8: слово читалось, но было ДРУГИМ цветом — тон 217° против
   198° у точки статуса и у полосы «Плана» в шапке вкладки, и рядом с индиго-
   ссылками в той же строке разница бросалась в глаза. Проверка остальных слов
   показала, что «План» — выброс: у «Исполнено», «Перенос» и «Не идёт» разбежка
   с точкой 0°, у «В работе» 4°.
   Ступень выведена по правилу свода (п. 12): берём цвет точки #38BDF8, тон и
   насыщенность не трогаем, светлоту опускаем 60% → 32%. Замеры: на белой строке
   5.56, на --card2 4.87, на своей заливке --blue-bg 5.11 — норма 4.5 всюду. */
.tbl-note-plan { color:#066F9E; }
.tbl-note-dec  { color:#7B4FD8; }
.tbl-note-none { color:var(--text2); }
/* «В работе» — пятый статус (ручной, 11.08.2026). Своей ступени у него не было:
   карточка сотрудника красила слово прямо var(--cyan) — 2.9 на своей заливке. */
.tbl-note-work { color:#0E7490; }
/* Отдельной ступени для кнопки-переключателя статуса в карточке сотрудника
   больше не нужно (04.09.2026). Она стоит НА СВОЕЙ ЗАЛИВКЕ, и прежнее слово
   #3472D8 давало там 4.25 — поэтому его подменяли на --blue2. Новая ступень
   проходит и на заливке: 5.11 в светлой теме, 6.77 в тёмной. Заодно ушёл
   var(--act-hover) в тёмной теме — статус был покрашен АКЦЕНТОМ (индиго),
   а это прямой запрет свода: акцент — действие, не состояние. */
[data-theme="dark"] .tbl-note-ok   { color:var(--green); }
[data-theme="dark"] .tbl-note-move { color:var(--orange); }
[data-theme="dark"] .tbl-note-no   { color:var(--slate); }
/* В тёмной теме слово берёт сам цвет точки: 7.85 на карточке, 6.77 на заливке.
   Было var(--blue) #3B82F6 — снова другой тон (217°) и всего 4.57. */
[data-theme="dark"] .tbl-note-plan { color:#38BDF8; }
[data-theme="dark"] .tbl-note-dec  { color:#9063F6; }
[data-theme="dark"] .tbl-note-work { color:var(--cyan); }

/* «Сегодня» в мини-календаре Главной. Было: белым по #38BDF8 — контраст 2.14.
   На светлой теме заливку берём на ступень темнее (--blue2, белым по ней 5.17),
   на тёмной наоборот — светлая заливка и тёмное число (8.33). Тот же счёт, что
   и у кружка «сегодня» во вкладке «Календарь» (ОФОРМЛЕНИЕ.md, п. 12). */
.hcal-today { background:var(--blue2); color:#fff; }
[data-theme="dark"] .hcal-today { background:#38BDF8; color:#0B1220; }

/* Ссылка-действие в шапке виджета («Все задачи →», «+ Добавить»). В разметке
   стоял #38BDF8 числом: 2.14 на белом при норме 4.5, и про тёмную тему
   инлайновый цвет ничего не знает. Ступени — из ОФОРМЛЕНИЕ.md, п. 12. */
/* Число на жёлтой плашке: var(--amber) по --amber-bg — 2.74. Ступень слова
   (свод, п. 12) — #9D6507 на светлой, сам токен на тёмной. */
.hm-amber { color:#9D6507; }
[data-theme="dark"] .hm-amber { color:var(--amber); }
.lnk-act { color:var(--act); }
[data-theme="dark"] .lnk-act { color:var(--act-hover); }

/* Срок задачи. Те же ступени, что и у слова-статуса: на светлой теме оттенок
   темнее токена, на тёмной светлее. До правки стояли var(--red) и var(--orange)
   числом — 3.44 и 2.07 на карточке при норме 4.5, и тёмной темы они не знали. */
.tb-due-late { color:#B91C1C; }
.tb-due-now  { color:#9D6507; }
[data-theme="dark"] .tb-due-late { color:#F87171; }
[data-theme="dark"] .tb-due-now  { color:var(--orange); }

/* ═══ ЧЕКБОКС ЗАДАЧИ (app-taskpage.js) ══════════════════════════════════════
   Один и тот же на доске «Сегодня нужно» и на странице «Задачи». Галочка не
   появляется рывком, а прорисовывается: короткая анимация подтверждает, что
   действие принято (ТЗ владельца 06.08.2026). Всё держится на классе .on —
   вёрстка строки его только проставляет. */
/* Квадратик галочки остаётся 19×19, область нажатия доведена до 24×24
   невидимым слоем (04.09.2026): в списке задач по нему промахивались. */
.tb-cbw{ position:relative; width:19px; height:19px; margin-top:2px; cursor:pointer; display:inline-block; }
.tb-cbw::after{ content:''; position:absolute; left:50%; top:50%; width:24px; height:24px;
  transform:translate(-50%,-50%); }
.tb-cbw input{ position:absolute; opacity:0; width:100%; height:100%; cursor:pointer; z-index:2; margin:0; }
.tb-cb{ width:19px; height:19px; border:2px solid #D1D5DB; border-radius:8px; background:var(--card);
        display:flex; align-items:center; justify-content:center;
        transition:background .18s ease, border-color .18s ease, transform .12s ease; }
.tb-cbw:hover .tb-cb{ border-color:var(--accent); }
/* Запертый квадратик: задача закрыта статусом учёта, снять отметку здесь
   нельзя (22.08.2026). Курсор обычный, наведение ничего не обещает. */
.tb-cbw-lock{ cursor:default; }
.tb-cbw-lock:hover .tb-cb{ border-color:var(--border); }
.tb-cbw-lock .tb-cb{ opacity:.65; }
.tb-cbw:active .tb-cb{ transform:scale(.9); }
/* Отмеченный квадратик — ЗЕЛЁНЫЙ (решение владельца 28.08.2026: «нужно, чтобы
   была зелёная», одинаково у личных и у отпускных задач). Зелёный здесь значит
   «сделано» — ровно та же мысль, что у слова «Исполнено» в таблице учёта.
   Ступень #15803D, а не сам --green (#22C55E): белая галочка на #22C55E даёт
   2.07, а иконке нужно 3. Этот же оттенок уже носят «ок»-плашки портала. */
.tb-cb.on{ background:#15803D; border-color:#15803D; }
/* В тёмной теме глубокий зелёный сливается с фоном — берём ступень светлее,
   галочка на ней остаётся читаемой. */
[data-theme="dark"] .tb-cb.on{ background:#16A34A; border-color:#16A34A; }
/* Сама галочка: линия «рисуется» от начала к концу */
.tb-cb svg{ display:block; }
.tb-cb svg path{ stroke-dasharray:20; stroke-dashoffset:20; transition:stroke-dashoffset .26s ease .04s; }
.tb-cb.on svg path{ stroke-dashoffset:0; }
@media (prefers-reduced-motion: reduce){
  .tb-cb, .tb-cb svg path{ transition:none; }
}

/* ═══ ЗАКРЫТАЯ ЗАДАЧА УХОДИТ ВПРАВО ═══════════════════════════════════════
   Макет makety/segodnya-nuzhno.html, вариант «А · уход вправо» — выбран
   владельцем 15.08.2026.

   Порядок важен и подобран так, чтобы действие читалось как одно движение:
   сначала успевает нарисоваться сама галочка (её линия чертится 260 мс), и
   только потом строка отшатывается влево и уезжает вправо. Следом плавно
   схлопывается её высота — иначе соседние строки прыгнули бы вверх рывком, и
   спокойный уход превратился бы в подёргивание списка.

   Только transform и opacity (правило проекта): они не заставляют браузер
   пересчитывать раскладку и не тормозят на длинном списке. Высоту схлопываем
   через grid-template-rows — это единственный способ анимировать «до нуля»,
   не зная высоты строки заранее. */
/* ЦЕНА КАДРА (22.08.2026). Владелец: «на мониторе 23 кадра в секунду, анимация
   выглядит рваной». Замер на стенде объяснил, почему: схлопывание высоты —
   это анимация РАСКЛАДКИ, и на каждом её кадре браузер пересчитывал поток
   всего списка. Один такой пересчёт стоил 8.9 мс при бюджете кадра 16.7 мс
   (60 Гц) — то есть больше половины кадра уходило на перерасчёт, ещё до
   отрисовки. На медленной машине этого хватает, чтобы кадры начали пропадать.

   contain:layout paint запирает пересчёт внутри строки: то, что происходит с
   её высотой, больше не заставляет мерить заново весь список. */
.tb-vanish{ display:grid; grid-template-rows:1fr; transition:grid-template-rows .26s ease-in;
  contain:layout paint; }
.tb-vanish > div{ overflow:hidden; }
/* Экраны с редким обновлением (30 Гц и ниже, энергосберегающие режимы) —
   медиа-признак update:slow. Там плавного схлопывания не выйдет при любой
   оптимизации: кадров слишком мало, и движение читается как рывки. Оставляем
   один короткий уход вправо, а высоту схлопываем мгновенно. */
@media (update: slow){
  .tb-vanish{ transition:none; }
  .tb-row-go{ animation-duration:.2s; }
}
.tb-vanish.tb-gone{ grid-template-rows:0fr; }
/* СТРОКА ЗАДАЧИ ВМЕСТЕ СО СВОЕЙ ПОДПИСЬЮ — ОДИН БЛОК И ОДНА ЛИНИЯ (06.09.2026).
   Во вкладках «Выполнено» и «Корзина» под строкой идёт подпись («Закрыто
   статусом …», «Скрыто 16.08.2026 · вернётся через 9 дн»). Линию рисовали обе:
   и строка, и подпись — две полоски в 20 px друг от друга, между ними зажатый
   текст. Линию строки гасим, снизу остаётся линия подписи.
   !important здесь обязателен: строка задачи стилизована инлайном (тот же
   случай, что и ячейки таблицы учёта выше), и без него правило не побеждает. */
.tp-unit > .tb-vanish > div > div{ border-bottom:none !important; }
.tb-row-go{ animation:tbGoRight .34s cubic-bezier(.4,0,.6,1) forwards; will-change:transform,opacity; }
@keyframes tbGoRight{
  0%   { opacity:1; transform:translateX(0); }
  25%  { transform:translateX(-4px); }        /* короткий замах — «принято» */
  100% { opacity:0; transform:translateX(46px); }
}
/* Уменьшенное движение: задача просто исчезает, без поездки и схлопывания. */
@media (prefers-reduced-motion: reduce){
  .tb-row-go{ animation:none; opacity:0; }
  .tb-vanish{ transition:none; }
}

/* ═══ ДИАГРАММА «ОТПУСКА»: ПОМЕТКИ НА ПОЛОСЕ ═══════════════════════════════
   ТЗ владельца 08.08.2026, макет scratchpad/makety/vac-plan-marks.html
   (вариант 2 — торец) плюс vac-move-forms.html (перенос незалитый).

   Смысл разделения: ЦВЕТ полосы отвечает на вопрос «что с отпуском» (пять
   состояний), а ПОМЕТКА — на вопрос «что мне сделать». Раньше «пора оформлять»
   перекрашивало плановый отпуск в янтарный, хотя состояние у него не менялось:
   он как был запланирован, так и остался. Янтарный при этом почти сливался с
   оранжевым переносом — из-за этого их и путали.

   Наведение и подсказка не трогаются: меняется только вид полосы. */

/* Торец слева: янтарный — нужен приказ, красный — срочно (меньше недели). */
.vac-bar.has-cap{ padding-left:16px; }
.vac-bar-cap{ position:absolute; left:0; top:0; bottom:0; width:6px; z-index:2; }
.vac-bar-cap.warn{ background:#EAB308; }
.vac-bar-cap.crit{ background:#EF4444; }

/* Светлая часть слева — сколько дней отпуска уже прошло. Полупрозрачный белый,
   а не отдельный цвет: он работает поверх любой заливки и не заводит в палитру
   шестой оттенок. */
.vac-bar-fill{ position:absolute; left:0; top:0; bottom:0; z-index:1;
               background:rgba(255,255,255,.34); border-right:1px solid rgba(255,255,255,.6); }
.vac-bar-txt{ position:relative; z-index:3; overflow:hidden; text-overflow:ellipsis; }

/* Перенос — незалитая полоса: отпуск уехал на другие даты, в эти дни человека
   не будет. Закрашенные дни на диаграмме читаются как «дни потрачены», поэтому
   здесь заливки нет. Цвета берём из темы, иначе в тёмной теме светлая подложка
   выжигает глаза. */
/* Рамка держит полный цвет (она не текст), слово берёт свою ступень: var(--orange)
   словом на --orange-bg давало 2.07 при норме 4.5 (свод, п. 12). */
.vac-bar.vac-bar-move{ background:var(--orange-bg); border:1px solid var(--orange);
                       color:#9D6507; box-shadow:none; }
[data-theme="dark"] .vac-bar.vac-bar-move{ color:var(--orange); }

/* ═══ ШАПКА ВКЛАДКИ «ГРАФИК ОТПУСКОВ» (app-tblhead.js) ══════════════════════
   Утверждённый макет 09.08.2026 (makety/table-header-live.html). Раньше шапка
   была тремя полосами на flex-wrap: при нехватке места они переносились целиком,
   и кнопки «ездили» от ширины экрана и от того, свёрнуто ли боковое меню.
   Теперь одна строка, которая НИЧЕГО не переносит: при нехватке места по шагам
   исчезают подписи, а порядок и правый край кнопок остаются на месте.
   Шаги считаются по ширине САМОЙ шапки (container-type), а не окна — поэтому
   сворачивание меню больше её не перестраивает. */
.thd{ container-type:inline-size; margin-bottom:14px; }
.thd-row{ display:flex; align-items:center; gap:12px; position:relative; }
.thd-ttl{ display:flex; align-items:baseline; gap:8px; white-space:nowrap; }
/* Шапка таблицы учёта компактная — заголовок стоит в одной строке с
   переключателями и кнопками (макет владельца 16.08.2026). Поэтому здесь не
   блок .page-head, а его класс .page-h1 прямо на заголовке: метрика общая
   (20/600), а раскладка своя. Юрлице — 13/--text2: было 12 px цветом --text3,
   контраст 2.39 при норме 4.5, а --text3 для содержания не годится (п. 6). */
.thd-ttl i{ font-style:normal; font-size:13px; font-weight:400; color:var(--text2); }
.thd-sp{ flex:1 1 auto; min-width:6px; }

.thd-seg{ display:inline-flex; align-items:center; gap:4px; background:var(--card2); flex:0 0 auto;
          border:1px solid var(--border); border-radius:12px; padding:3px; white-space:nowrap; }
.thd-seg button{ border:0; background:transparent; color:var(--text2); font:inherit; font-size:13px;
                 font-weight:600; padding:8px 12px; border-radius:8px; cursor:pointer;
                 display:inline-flex; align-items:center; gap:8px; transition:color .15s; }
.thd-seg button.on{ background:var(--card); color:var(--text); font-weight:600;
                    box-shadow:0 1px 3px rgba(20,40,70,.1); }
.thd-seg .n{ font-size:11px; font-weight:600; padding:1px 6px; border-radius:99px;
             background:var(--border); color:var(--text2); }
.thd-seg button.on .n{ background:var(--act-bg); color:var(--blue2,var(--act)); }
.thd-seg .dot{ width:6px; height:6px; border-radius:50%; background:#22C55E; }

/* Пульс года: крупное число и шкала долей статусов вместо пяти плашек. */
.thd-slot{ position:relative; display:flex; align-items:center; flex:1 1 auto; min-width:0;
           justify-content:center; }
/* Сводка года. Переехала в .thd-line2 (макет «вариант 1», 16.08.2026), и вместе
   с переездом снялись два прежних ограничения:

   • max-width:330px — он держал сводку в тесном первом ряду. Во втором ряду с
     ним полоса ужималась до 246 px и пять подписей переносились на три строки:
     панель раздувалась до 147 px вместо 69.
   • width:100% — во втором ряду он занимал всю строку и выталкивал «Показано N»
     на отдельную, добавляя 35 px пустоты.

   ЗАОДНО ЗАКРЫЛСЯ СТАРЫЙ ДЕФЕКТ. На окне уже ~1000 px полоса вылезала из
   схлопнувшейся .thd-pulse и наезжала на «Фильтры» и «Сверки» — при 760 px
   перекрытие было 27 px. Лечить его на месте не выходило (overflow:hidden не
   помогал: .thd-pcol с min-width выходил за нулевую ширину родителя). Переезд
   решил задачу по построению: полосы в первом ряду больше нет, наезжать нечему.
   Проверено замером: 760, 960, 1280, 1400 — перекрытий ноль. */
.thd-pulse{ display:flex; align-items:flex-start; gap:16px; min-width:0; flex:0 1 auto;
            transition:opacity .14s ease-out, transform .14s ease-out; }
.thd-slot.searching .thd-pulse{ opacity:0; transform:translateY(-4px); pointer-events:none; }
.thd-num{ font-size:20px; font-weight:600; letter-spacing:-.02em; line-height:1; flex:0 0 auto;
          font-variant-numeric:tabular-nums; background:none; border:0; padding:4px 8px;
          border-radius:8px; cursor:pointer; color:var(--text); font-family:inherit;
          transition:transform .12s ease-out, background .15s; }
.thd-num:hover{ background:var(--card2); }
.thd-num:active{ transform:scale(.96); }
.thd-num s{ display:block; text-decoration:none; font-size:11px; font-weight:500;
            color:var(--text2); margin-top:3px; }
/* Сводка живёт во втором ряду (макет «вариант 1», 16.08.2026), где места
   много: ограничение в 210 px было нужно, пока она теснилась в первом ряду
   между переключателями и кнопками. */
/* Ширина сводки. Без потолка полоса растягивалась на всю строку (1199 px на
   окне 1400) и становилась главным элементом экрана — а она сводка, а не герой.
   580 px хватает, чтобы пять подписей встали в одну строку (замер: нужно 548), и оставляет второй ряд спокойным. */
.thd-pcol{ flex:0 1 580px; min-width:220px; max-width:580px; }
.thd-bar{ display:flex; height:10px; width:100%; border-radius:99px; overflow:hidden;
          background:var(--card2); box-shadow:inset 0 0 0 1px var(--border); }
.thd-bar i{ display:block; height:100%; cursor:pointer;
            transition:opacity .18s, filter .15s, transform .2s ease-out; }
.thd-bar i:hover{ filter:brightness(1.07); }
.thd-bar.picked i{ opacity:.28; }
.thd-bar.picked i.act{ opacity:1; }
.thd-barl{ display:flex; gap:16px; margin-top:7px; font-size:12px; font-weight:600;
           color:var(--text2); flex-wrap:wrap; }
/* Название доли — тихим весом рядом с числом. Число отвечает «сколько»,
   слово — «чего»; раньше слово жило отдельной легендой в другом месте. */
.thd-barl button s{ text-decoration:none; color:var(--text2); font-weight:400; margin-left:3px; }
.thd-barl button{ display:inline-flex; align-items:center; gap:4px; border:0; background:none;
                  font:inherit; font-size:12px; font-weight:600; color:var(--text2); cursor:pointer;
                  padding:1px 3px; border-radius:8px; white-space:nowrap;
                  transition:opacity .15s, transform .12s ease-out; }
.thd-barl button:hover{ transform:translateY(-1px); }
.thd-barl button i{ width:7px; height:7px; border-radius:50%; }
.thd-barl.picked button{ opacity:.4; }
.thd-barl.picked button.act{ opacity:1; }

/* Кнопки шапки. flex:0 0 auto обязателен: без него флекс сжимал кнопки-иконки
   до 15 px, и «⋯» выглядела приплюснутой (замечание владельца 09.08.2026). */
/* Кнопки шапки — те же роли, что во всём портале (16.08.2026). Скругление 8:
   по своду 8 — мелкое, для кнопок и полей, 12 — крупное, для карточек и панелей.
   В проходе по таблице 15.08.2026 я поставила здесь 12 — это была ошибка против
   собственного свода, поправлено вместе с общими ролями. */
.thd-b{ display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto; gap:8px;
        padding:8px 14px; min-height:34px; box-sizing:border-box;
        border-radius:8px; border:1px solid var(--border2,#DCE3EC);
        background:var(--card); color:var(--text); font:inherit; font-size:13px; font-weight:500;
        cursor:pointer; white-space:nowrap;
        transition:transform .12s ease-out, border-color .15s, color .15s, background .15s; }
.thd-b:hover{ border-color:var(--text3); background:var(--card2); transform:translateY(-1px); }
.thd-b:active{ transform:translateY(0) scale(.985); }
/* «Сверки» были второй тёмной заливкой рядом с главным действием: на экране
   спорили две «главные» кнопки. Тёмное убрано, действие на вкладке одно —
   «Завести отпуск». */
.thd-b.thd-dark{ background:var(--card); border-color:var(--text3); color:var(--text); }
.thd-b.thd-dark:hover{ border-color:var(--text); background:var(--card2); }
.thd-b.thd-blue{ background:var(--act-bg); border-color:var(--act-line);
                 color:var(--act); }
.thd-b.thd-blue:hover{ color:var(--act); border-color:var(--act); }
[data-theme="dark"] .thd-b.thd-blue{ color:var(--act-hover); }
.thd-b.thd-ico{ flex:0 0 34px; width:34px; height:34px; min-height:34px; padding:0; }
.thd-b.thd-ico svg{ display:block; }
.thd-b.on{ border-color:var(--blue2,var(--act)); color:var(--blue2,var(--act)); background:var(--act-bg); }
.thd-cnt{ font-size:11px; font-weight:600; padding:1px 8px; border-radius:99px;
          background:var(--border); color:var(--text2); }
.thd-b.on .thd-cnt{ background:var(--act-bg); color:var(--act); }

/* Поиск раскрывается ПОВЕРХ пульса, по центру строки: шапка не сдвигается.
   Вид — как у поиска в верхней панели портала (.global-search-input): тот же
   радиус, подложка и голубая обводка по фокусу. Ширина фиксированная 300 px —
   на всю шапку поле не растягивается (замечание владельца 09.08.2026). */
.thd-find{ position:absolute; left:50%; top:50%; z-index:15; width:300px; max-width:70%;
           display:flex; align-items:center; gap:8px; padding:8px 12px; border-radius:12px;
           background:var(--card2); border:1px solid var(--border);
           opacity:0; transform:translate(-50%,-50%) scale(.98); pointer-events:none;
           transition:opacity .16s ease-out, transform .16s ease-out,
                      border-color .15s, box-shadow .15s, background .15s; }
.thd-find.on{ opacity:1; transform:translate(-50%,-50%) scale(1); pointer-events:auto; }
.thd-find:focus-within{ background:var(--card); border-color:var(--act);
                        box-shadow:0 0 0 3px rgba(56,189,248,.1); }
.thd-find input{ border:0; outline:none; background:transparent; font:inherit; font-size:13px;
                 flex:1; min-width:0; color:var(--text); }
/* Крестик «закрыть поиск» был 10×15 — область нажатия доведена до 24×24
   невидимым слоем, сам знак не изменился (04.09.2026). */
.thd-x{ border:0; background:none; color:var(--text2); cursor:pointer; font:inherit; font-size:13px; position:relative; }
.thd-x::after{ content:''; position:absolute; left:50%; top:50%; width:24px; height:24px; transform:translate(-50%,-50%); }
.thd-x:hover{ color:var(--text); }

/* Вторая строка: чипы включённых фильтров, дубликаты, легенда, «Показано X из Y». */
.thd-line2{ display:flex; align-items:flex-start; gap:16px; margin-top:12px; flex-wrap:wrap; }
/* «Показано N» и чипы — по базовой линии крупного числа, а не по верху блока. */
.thd-line2 > .thd-shown, .thd-line2 > .thd-chip, .thd-line2 > .thd-dupes { margin-top:6px; }
.thd-chip{ display:inline-flex; align-items:center; gap:8px; padding:5px 9px 5px 11px; border-radius:99px;
           border:1px solid rgba(37,99,235,.25); background:var(--blue-bg); color:var(--blue2,#2563EB);
           font-size:12px; font-weight:600; white-space:nowrap;
           animation:thdChipIn .18s cubic-bezier(.2,.8,.2,1) both; }
.thd-chip button{ border:0; background:none; color:inherit; cursor:pointer; font:inherit; opacity:.6;
                  padding:0 1px; transition:opacity .15s, transform .12s ease-out; }
.thd-chip button:hover{ opacity:1; transform:scale(1.15); }
@keyframes thdChipIn{ from{ opacity:0; transform:scale(.92) } to{ opacity:1; transform:scale(1) } }
/* Отключённое движение уважаем (CLAUDE.md §13). Чип и плашка архива никуда не
   деваются — просто появляются сразу, без наплыва. */
@media (prefers-reduced-motion: reduce){
  .thd-chip, .thd-arch{ animation:none; }
  .thd-chip button, .thd-dupes{ transition:none; }
}
.thd-clr{ font-size:12px; font-weight:600; color:#DC2626; background:none; border:0; cursor:pointer;
          padding:4px 8px; border-radius:8px; font-family:inherit; }
.thd-clr:hover{ background:var(--red-bg); }
/* «Показано N» — это содержание, а не служебная подсказка: у --text3 контраст
   2.39 при норме 4.5, и им нельзя писать текст (свод, п. 6). */
.thd-shown{ font-size:12px; color:var(--text2); font-weight:500; white-space:nowrap; }
.thd-dupes{ display:inline-flex; align-items:center; gap:8px; padding:4px 12px; border-radius:99px;
            cursor:pointer; font-size:12px; font-weight:600; color:var(--red); background:var(--red-bg);
            border:1px solid var(--red); transition:transform .12s ease-out; }
.thd-dupes:hover{ transform:translateY(-1px); }
.thd-leg{ display:flex; align-items:center; gap:16px; }

/* Плашка «архив — только чтение». */
.thd-arch{ display:flex; align-items:center; gap:12px; margin-top:11px; padding:12px 16px;
           border-radius:12px; background:var(--orange-bg); border:1px solid var(--orange);
           font-size:13px; color:var(--text); animation:thdChipIn .2s both; }

/* Панели «Фильтры» и «⋯». «Стикер» справа у пункта — тихая подпись значения. */
.thd-pop{ position:fixed; z-index:3000; background:var(--card); border:1px solid var(--border);
          border-radius:12px; box-shadow:0 16px 40px rgba(20,40,70,.16); overflow:auto;
          opacity:0; transform:translateY(-6px) scale(.985);
          transition:opacity .15s ease-out, transform .15s ease-out; transform-origin:top right; }
.thd-pop.on{ opacity:1; transform:translateY(0) scale(1); }
.thd-pop .g{ padding:8px 12px; font-size:11px; font-weight:600; 
             color:var(--text3); background:var(--card2);
             border-bottom:1px solid var(--border); position:sticky; top:0; }
.thd-pop .i{ display:flex; align-items:center; gap:12px; padding:8px 12px; font-size:13px;
             color:var(--text); cursor:pointer; transition:background .12s, padding-left .12s; }
.thd-pop .i:hover{ background:var(--card2); padding-left:16px; }
.thd-pop .i s{ text-decoration:none; color:var(--text3); font-size:12px; font-weight:600;
               margin-left:auto; background:var(--card2); border:1px solid var(--border);
               border-radius:99px; padding:1px 8px; white-space:nowrap; }
.thd-pop .i.act{ color:var(--blue2,#2563EB); font-weight:600; }
.thd-pop .i.act s{ color:var(--blue2,#2563EB); background:var(--blue-bg); border-color:rgba(37,99,235,.25); }
.thd-pop .i.dang{ color:#DC2626; }
.thd-pop .i.dang s{ color:#DC2626; background:var(--red-bg); border-color:var(--red); }
.thd-pop .sep{ height:1px; background:var(--border); }
.thd-pop .foot{ display:flex; gap:8px; padding:12px 12px; border-top:1px solid var(--border);
                background:var(--card2); position:sticky; bottom:0; }

/* Шаги сжатия — по ширине самой шапки. Ничего не переносится на новую строку:
   сначала уходят подписи, затем длинные слова, затем числа под шкалой. */
@container (max-width:1360px){ .thd-ttl i, .thd-w3{ display:none; } }
@container (max-width:1180px){ .thd-w4{ display:none; } }
@container (max-width:1060px){ .thd-barl{ display:none; } .thd-num s{ display:none; } }

/* ═══ ОКНО «КТО В КАКОМ ЮРЛИЦЕ» (app-orgcheck.js) ═══════════════════════════
   ТЗ владельца 09.08.2026: после загрузки выгрузки не в то юрлицо нужно было
   глазами разобрать, кто где числится. Устроено как таблица учёта: закреплённая
   шапка с вкладками, прокручиваемое тело, закреплённый подвал. */
.och{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.och-head{ padding:16px 24px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
.och-t{ font-size:15px; font-weight:600; letter-spacing:-.3px; }
.och-x{ margin-top:5px; font-size:13px; color:var(--text3); line-height:1.5; }
.och-x b{ color:var(--text2); }
.och-tabs{ display:flex; gap:8px; margin-top:12px; flex-wrap:wrap; }
.och-tab{ display:inline-flex; align-items:center; gap:8px; padding:7px 13px; border-radius:8px;
          border:1px solid var(--border); background:var(--card); color:var(--text2);
          font:inherit; font-size:13px; font-weight:600; cursor:pointer;
          transition:transform .12s ease-out, border-color .15s, color .15s; }
.och-tab:hover{ border-color:var(--text3); color:var(--text); transform:translateY(-1px); }
.och-tab.on{ background:var(--text,#111827); border-color:var(--text,#111827); color:#fff; font-weight:600; }
.och-tab .n{ font-size:11px; font-weight:600; padding:1px 7px; border-radius:99px;
             background:var(--border); color:var(--text2); }
.och-tab.on .n{ background:rgba(255,255,255,.22); color:#fff; }

.och-body{ flex:1 1 auto; min-height:120px; overflow-y:auto; padding:6px 24px 10px; }
.och-note{ margin:12px 0 8px; padding:12px 12px; border-radius:12px; background:var(--card2);
           border:1px solid var(--border); font-size:13px; color:var(--text2); line-height:1.5; }
.och-empty{ padding:30px 12px; text-align:center; color:var(--text2); font-size:13px; }
.och-row{ padding:12px 0; border-bottom:1px solid var(--border); }
.och-fio{ font-size:13px; font-weight:600; color:var(--text); display:flex; align-items:baseline; gap:8px; }
.och-tab-num{ font-size:12px; font-weight:600; color:var(--text3); }
.och-places{ display:flex; flex-wrap:wrap; gap:8px; margin-top:6px; }
.och-place{ font-size:12px; color:var(--text2); background:var(--card2); border:1px solid var(--border);
            border-radius:8px; padding:4px 12px; }
.och-place b{ color:var(--text); }
.och-vac{ color:var(--text3); }
.och-acts{ display:flex; align-items:center; gap:8px; margin-top:8px; flex-wrap:wrap; }
.och-done{ font-size:12px; font-weight:600; color:var(--green); background:var(--green-bg);
           border:1px solid var(--green); border-radius:99px; padding:3px 12px; }
.och-foot{ display:flex; align-items:center; gap:8px; padding:16px 24px;
           border-top:1px solid var(--border); background:var(--card); flex-shrink:0; }
.och-hint{ font-size:12px; color:var(--text3); }

/* ═══════════════════════════════════════════════════════════════════════════
   ЛИЧНЫЙ КАБИНЕТ СОТРУДНИКА (app-profile.js)
   Перенесено с утверждённого макета profile-mockup.html, 09.08.2026.
   Аватар по умолчанию — фиолетовый человечек: решение владельца, инициалов
   в портале больше нет нигде, где показывается карточка человека.
   ═══════════════════════════════════════════════════════════════════════════ */
/* КАБИНЕТ — ПОЛНОЦЕННАЯ СТРАНИЦА (25.08.2026).
   Первый перенос из окна дал вкладку, но содержимое осталось одной карточкой
   в 860 px посреди пустого экрана: «выглядит инородно, а должно выглядеть как
   страница» (владелец). Теперь страница собрана из блоков, как остальные
   разделы: шапка во всю ширину, ряд плиток, две колонки. Общей рамки у корня
   нет — рамки несут сами блоки, иначе получается карточка в карточке. */
/* Потолка ширины у страницы нет (25.08.2026). Было max-width:1280px, и на
   мониторе 1920 кабинет занимал 1280 из 1700 — справа пустовало 420 px, а
   карточка жалась к левому краю. Замер по остальным разделам на том же
   экране: «Структура» 1700, «Календарь» и «Настройки» 1652, «Главная»,
   «Задачи», «Отпуска», «Аналитика» 1641 — то есть все берут ширину поля
   целиком, и только кабинет вёл себя как окно посреди пустоты. Одинаковый
   вид на любом мониторе достигается тем, что правило ОДНО на все страницы,
   а не своим числом у каждой. */
.prof-wrap{ position:relative; }
.prof-head{ display:flex; gap:16px; align-items:flex-start; margin-bottom:14px; }
.prof-av{ border-radius:var(--r2); flex-shrink:0; overflow:hidden; background:#DDD6FE;
          box-shadow:var(--shadow-md); }
.prof-av img{ width:100%; height:100%; object-fit:cover; display:block; }
.prof-av-empty{ background:#DDD6FE url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='76' height='76'%3E%3Ccircle cx='38' cy='30' r='13' fill='%238B5CF6'/%3E%3Cpath d='M10 76c0-16 12-24 28-24s28 8 28 24z' fill='%238B5CF6'/%3E%3C/svg%3E") center/cover no-repeat; }
.prof-head-main{ min-width:0; }
/* 20/600, а не 19/800: и размер, и насыщенность — из шкалы свода (пп. 1–2). */
.prof-name{ font-size:20px; font-weight:600; letter-spacing:-.02em; line-height:1.25; }
.prof-meta{ font-size:13px; color:var(--text2); margin-top:3px; }
.prof-org{ font-size:12px; color:var(--text3); margin-top:2px; }
.prof-statline{ margin-top:10px; display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
.prof-stat{ display:inline-flex; align-items:center; gap:8px; background:var(--green-bg); color:#15803D;
            border-radius:99px; padding:4px 12px; font-size:12px; font-weight:500; }
.prof-stat-away{ background:var(--orange-bg); color:#92400E; }
.prof-stat-none{ background:var(--card2); color:var(--text3); }
.prof-dot{ width:7px; height:7px; border-radius:50%; background:currentColor; flex-shrink:0; }
/* «это поставил портал, а не человек» — иначе статус читается как чужие слова */
.prof-auto{ font-size:11px; color:var(--text3); }
/* Кнопки — своей строкой под именем. В углу столбиком они стояли из-за крестика
   закрытия окна; крестика нет, а в колонке 380 px рядом с аватаром они не
   помещаются. */
.prof-acts{ display:flex; gap:8px; flex-wrap:wrap; padding-bottom:16px; }

/* ЕДИНОЕ ОКНО КАБИНЕТА. Одна рамка на всё; разделы внутри разведены линиями.
   Отдельных рамок у плиток и у списка отпусков больше нет — из-за них экран
   распадался на набор виджетов (замечание владельца 25.08.2026). */
/* Тень --shadow-md, а не --shadow: с самой лёгкой окно сливалось с фоном
   страницы и экран читался плоским (замечание владельца 25.08.2026). Слои
   набираем ТОКЕНАМИ, новых цветов и градиентов не заводим (свод, п. 12). */
.prof-card{ background:var(--card); border:1px solid var(--border);
            border-radius:var(--r2); box-shadow:var(--shadow-md); overflow:hidden; }
.prof-card > .prof-head,
.prof-card > .prof-acts{ padding-left:24px; padding-right:24px; }
.prof-card > .prof-head{ padding-top:24px; }

/* Две колонки ВНУТРИ окна: слева сведения о человеке, справа его отпуска.
   Вертикальная линия между ними — часть того же документа, а не зазор между
   двумя карточками. На узком экране колонки складываются в одну. */
.prof-cols{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
            align-items:stretch; border-top:1px solid var(--border); }
.prof-col{ min-width:0; padding:16px 24px 16px; }
.prof-col-vac{ border-left:1px solid var(--border); }
@media (max-width:1000px){
  .prof-cols{ grid-template-columns:1fr; }
  .prof-col-vac{ border-left:none; border-top:1px solid var(--border); }
}
/* Части одного раздела — линией, а не рамкой. */
.prof-sub{ border-top:1px solid var(--card2); padding-top:12px; margin-top:12px; }
.prof-sec-t{ font-size:13px; font-weight:600; color:var(--text); margin-bottom:8px; }
.prof-row{ display:flex; gap:12px; padding:8px 0; font-size:13px; }
.prof-row + .prof-row{ border-top:1px solid var(--card2); }
/* 110, а не 150: в колонке 380 px подпись съедала почти половину строки. */
.prof-k{ width:110px; flex-shrink:0; color:var(--text2); font-size:12px; padding-top:1px; }
.prof-v{ flex:1; min-width:0; }
.prof-muted{ color:var(--text3); }
.prof-about{ font-size:13px; color:var(--text2); line-height:1.6; background:var(--card2);
             border-radius:8px; padding:12px 12px; margin-top:2px; }

/* ПОЛОСА ПОКАЗАТЕЛЕЙ — часть окна, а не отдельные плашки: своих рамок и
   скруглений у них нет, соседей разделяет вертикальная линия. */
.prof-tiles{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
             border-top:1px solid var(--border); background:var(--card2); }
.prof-tile{ padding:16px 24px; }
.prof-tile + .prof-tile{ border-left:1px solid var(--border); }
/* Было 10.5/800 ЗАГЛАВНЫМИ С ТРЕКИНГОМ — свод запрещает и дробный размер (п. 2),
   и насыщенность 800 (п. 1), и заглавные с трекингом (п. 8: на Windows они
   слипаются, а разрабатывают на маке и этого не видят). */
.prof-tl{ font-size:12px; font-weight:500; color:var(--text2); }
.prof-tv{ font-size:20px; font-weight:600; letter-spacing:-.3px; margin-top:4px;
          font-variant-numeric:tabular-nums; }
.prof-tv-warn{ color:var(--orange); }
.prof-tv-none{ font-size:15px; color:var(--text3); }
.prof-ts{ font-size:11px; color:var(--text3); margin-top:2px; line-height:1.4; }

.prof-vac{ margin-top:6px; }
.prof-vrow{ display:flex; align-items:center; gap:8px; padding:8px 0;
            border-bottom:1px solid var(--card2); font-size:13px; }
.prof-vrow:last-child{ border-bottom:none; }
.prof-vdays{ margin-left:auto; color:var(--text3); font-size:12px; }
.prof-foot{ padding:12px 24px; font-size:11px; color:var(--text3); background:var(--card2);
            border-top:1px solid var(--border); display:flex; gap:16px; flex-wrap:wrap; }
.prof-empty{ background:var(--card); border:1px solid var(--border); border-radius:var(--r2);
             padding:34px 24px; text-align:center; color:var(--text2); font-size:13px; max-width:520px; }

.prof-fld{ margin-bottom:12px; }
.prof-fld label{ display:block; font-size:12px; font-weight:500; color:var(--text2); margin-bottom:4px; }
.prof-fld input, .prof-fld textarea{ width:100%; border:1px solid var(--border); border-radius:8px;
  padding:8px 12px; font-size:13px; font-family:inherit; color:var(--text); background:var(--card);
  box-sizing:border-box; resize:vertical; }
.prof-fld input:focus, .prof-fld textarea:focus{ outline:none; border-color:var(--act); }

/* ============================================================================
   ДВИЖЕНИЕ КАДРОВ — макет «Вариант Б», утверждён владельцем 11.08.2026.
   Страница = аналитика; приёмы, переводы и увольнения открываются окном.
   Движение только transform/opacity, выход быстрее входа, при
   prefers-reduced-motion всё замирает (см. конец блока).
   ========================================================================== */

/* Шапка вкладки — общий блок .page-head (27.08.2026). Свои .hrm-head-t (13/500)
   и .hrm-head-s (12) убраны: строка «кто мы и какой горизонт» из макета
   17.08.2026 сохранена целиком, она стала подписью под заголовком. */

/* Полоса разделов под сводкой */
.hrm-strip{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:12px; }
/* Цвет у самой кнопки задан не был — <button> брал чёрный по умолчанию, и на
   тёмной теме подписи внутри спасал только собственный цвет у span/b, а всё
   остальное (в том числе стрелка) уходило в чёрное (дозор 16.08.2026).
   Тень и подъём при наведении убраны 17.08.2026: карточка, которая всплывает,
   была в портале одна — здесь; свод оставляет за наведением только подсветку. */
.hrm-chip{ display:flex; align-items:center; gap:8px; font-family:inherit; cursor:pointer;
  min-height:34px; box-sizing:border-box;
  background:var(--card); border:1px solid var(--border); border-radius:8px;
  color:var(--text2);
  /* 6, а не 8: у чипа min-height:34, и при 8 содержимое даёт 37 — чип
     вставал выше соседних кнопок (замер 03.09.2026). Отступ здесь подчинён
     высоте контрола, как у .btn-s. */
  padding:6px 12px; transition:background-color .15s ease, border-color .15s ease; }
.hrm-chip i{ width:8px; height:8px; border-radius:3px; display:block; }
.hrm-chip span{ font-size:13px; font-weight:500; color:var(--text); }
.hrm-chip b{ font-size:12px; font-weight:500; padding:2px 8px; border-radius:99px;
  background:var(--card2); color:var(--text2); font-variant-numeric:tabular-nums; }
.hrm-chip u{ display:inline-flex; align-items:center; color:var(--text2); text-decoration:none; }
.hrm-chip:hover{ background:var(--card2); }
.hrm-chip:active{ transform:scale(.99); }

/* ── ПАНЕЛИ СВОДКИ ────────────────────────────────────────────────────────
   Скругление 12 (свод, п. 3; было 16 — своей ступени у него нет). */
.hrm-panel{ background:var(--card); border:1px solid var(--border); border-radius:12px;
  box-shadow:var(--shadow); padding:16px 24px; margin-bottom:12px; }
.hrm-panel-h{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-bottom:8px; }
.hrm-panel-t{ font-size:15px; font-weight:600; color:var(--text); }
.hrm-panel-s{ font-size:12px; color:var(--text2); margin:2px 0 12px; }
.hrm-two{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:12px; }
@media (max-width:900px){ .hrm-two{ grid-template-columns:1fr; } }

.hrm-sum{ display:flex; align-items:center; gap:24px; flex-wrap:wrap; }
.hrm-sum-net{ display:flex; align-items:baseline; gap:12px; }
.hrm-sum-i{ display:flex; flex-direction:column; gap:4px; min-width:96px; }
.hrm-sum-i.hrm-clickable{ cursor:pointer; }
.hrm-sum-l{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--text2); font-weight:500; }
.hrm-sum-l i{ width:8px; height:8px; border-radius:3px; display:block; }
/* 20/600 — верхняя ступень шкалы свода. До 17.08.2026 здесь стояли 38 и 24 px
   весом 800: самый крупный шрифт портала жил на редко открываемой вкладке. */
.hrm-sum-n{ font-size:20px; font-weight:600; line-height:1.15; color:var(--text);
  font-variant-numeric:tabular-nums; }
.hrm-sum-u{ font-size:13px; font-weight:500; color:var(--text2); margin-left:1px; }
.hrm-sum-w{ font-size:12px; color:var(--text2); line-height:1.35; max-width:120px; }
.hrm-sum-h{ font-size:12px; color:var(--text2); }
.hrm-vline{ width:1px; align-self:stretch; background:var(--border); }

/* Ступени тона: слово берёт затемнённый (в тёмной теме осветлённый) оттенок —
   свод «Оформление», п. 12. Полный --green/--red остаётся у точек и полос.
   Ноль серым: ноль приёмов — это не событие, а отсутствие события. */
.hrm-up{ color:#15803D; }
.hrm-down{ color:#B91C1C; }
.hrm-zero{ color:var(--text2); font-weight:500; }
.hrm-sep{ color:var(--text2); }
[data-theme="dark"] .hrm-up{ color:#4ADE80; }
[data-theme="dark"] .hrm-down{ color:#F87171; }

.hrm-legend{ display:flex; gap:16px; flex-wrap:wrap; }
.hrm-legend span{ display:flex; align-items:center; gap:4px; font-size:12px; color:var(--text2); }
.hrm-legend i{ width:9px; height:9px; border-radius:2px; display:block; }
.hrm-legend i.hrm-lg-line{ width:14px; height:2px; border-radius:0; background:var(--slate); }

/* Раскрывашка «Просроченные записи» */
/* Отступы 8, а не 9 (03.09.2026): при 9 содержимое давало 36 px, и заявленный
   min-height:34 не помогал — он поднимает, но не сжимает. Кнопка была на два
   пикселя выше остальных на вкладке. */
.hrm-drill{ width:100%; padding:8px; min-height:34px; box-sizing:border-box; border:1px solid var(--border); background:var(--card);
  border-radius:8px; font-size:13px; font-weight:500; color:var(--text2); cursor:pointer;
  font-family:inherit; display:flex; align-items:center; justify-content:center; gap:8px; }
.hrm-drill:hover{ background:var(--card2); }

/* ═══ ОКНО РАЗДЕЛА — ШАПКА, ТЕЛО, ПОДВАЛ (переделано 27.08.2026) ═══════════
   Было: шапка с отступами 11 × 14, сразу под ней жёлтая полоса отката, список
   ростом ровно 56vh и никакого подвала. Замер на боевом снимке: окно вставало
   460 px при доступных 662, нижняя строка резалась пополам и упиралась в
   скруглённый угол, заголовок стоял в 11 px от края. Владелец 27.08.2026:
   «обрезанность по бокам и сверху, полоса отката висит и мешается».
   Стало: отступы 16 × 20 во всех трёх частях, тело тянется на остаток окна,
   подвал закрывает нижний край. */
#mc.hrm-win{ overflow:hidden; }
.hrm-wh{ padding:16px 24px 0; border-bottom:1px solid var(--border); background:var(--card); }
.hrm-wh-1{ display:flex; align-items:baseline; gap:12px; }
/* Заголовок окна — как у любого окна портала: 15/600 (было 15/800). */
.hrm-wh-t{ font-size:15px; font-weight:600; color:var(--text); }
.hrm-wh-s{ font-size:12px; color:var(--text2); }
.hrm-wh-x{ margin-left:auto; width:28px; height:28px; border:0; background:transparent;
  border-radius:8px; color:var(--text2); cursor:pointer; font-family:inherit;
  display:flex; align-items:center; justify-content:center; align-self:flex-start; }
.hrm-wh-x:hover{ background:var(--card2); color:var(--text); }
/* Вторая строка: разделы слева, действия справа. */
.hrm-wh-2{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:12px 0; }
.hrm-wh-acts{ margin-left:auto; display:flex; align-items:center; gap:8px; }
/* Переключатель разделов внутри окна — форма «сегмент» (свод, п. 10): меняем
   показ одного и того же, а не уходим в другой раздел портала. */
.hrm-wt{ display:flex; gap:2px; padding:2px; background:var(--card2); border-radius:8px; }
.hrm-wt-i{ display:flex; align-items:center; gap:8px; font-family:inherit; font-size:13px;
  font-weight:500; padding:8px 12px; border:0; border-radius:6px; background:transparent;
  color:var(--text2); cursor:pointer; }
.hrm-wt-i i{ width:7px; height:7px; border-radius:3px; display:block; }
.hrm-wt-i b{ font-size:12px; font-weight:500; color:var(--text2); font-variant-numeric:tabular-nums; }
.hrm-wt-i.on{ background:var(--card); color:var(--text); box-shadow:0 1px 2px rgba(15,23,42,.10); }
.hrm-wt-i.on b{ color:var(--text); }
[data-theme="dark"] .hrm-wt-i.on{ box-shadow:0 1px 2px rgba(0,0,0,.32); }
/* Поиск — общее поле портала (.fi), своей формы у него больше нет. */
.hrm-wh-find{ width:230px; height:34px; padding:0 11px; }
/* ── ПОДВАЛ ────────────────────────────────────────────────────────────────
   Отвечает на два вопроса, которых в окне не было: сколько строк показано и по
   чему они отсортированы. И закрывает нижний край окна. */
.hrm-wf{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:12px 24px; border-top:1px solid var(--border); background:var(--card); }
.hrm-wf-s{ font-size:12px; color:var(--text2); }
.hrm-wf-r{ margin-left:auto; display:flex; align-items:center; gap:8px; }
/* Откат импорта: тихая строка вместо жёлтой полосы в 52 px (владелец 27.08.2026). */
.hrm-wf-undo{ font-size:12px; color:var(--text2); }
.hrm-wf-undo button{ font-family:inherit; font-size:12px; background:none; border:0; padding:0;
  color:var(--blue2); cursor:pointer; text-decoration:underline; text-underline-offset:2px; }
/* Список внутри окна: своей рамки и радиуса у него нет — окно уже рамка.
   Тело — колонка на весь остаток окна: панель выбранных сверху, прокрутка под ней. */
.hrm-sec{ position:relative; flex:1; min-height:0; display:flex; flex-direction:column; }
.hrm-sec thead th{ z-index:3; }
/* Всё влезает в окно: фиксированная раскладка, переносы по словам, длинная
   плашка статьи больше не распирает таблицу (жалоба владельца 11.08.2026). */
.hrm-fixed{ table-layout:fixed; width:100%; border-collapse:collapse; font-size:13px; }
.hrm-fixed td, .hrm-fixed th{ overflow-wrap:break-word; word-break:normal; }
.hrm-fixed td.hrm-nowrap{ white-space:nowrap; }
.hrm-sec .hrm-tbl{ position:relative; flex:1; min-height:0;
  overflow-y:auto; overflow-x:hidden; }
/* Затухание внизу списка убрано 17.08.2026: край окна и так очерчен рамкой,
   а маска градиентом гасила последнюю строку. */

/* ── ШАПКА И СТРОКИ СПИСКА ────────────────────────────────────────────────
   Было 10 px, вес 700, ЗАГЛАВНЫМИ, --text3 — контраст 2,0 (свод, пп. 6 и 8).
   Теперь 12/500 и --text2, как на восьми других экранах портала. */
.hrm-sec thead tr{ background:var(--card2); }
.hrm-sec thead th{ padding:8px 12px; text-align:left; font-size:12px; font-weight:500;
  color:var(--text2); background:var(--card2); position:sticky; top:0;
  cursor:pointer; user-select:none; }
.hrm-sec thead th.hrm-sorted{ color:var(--text); }
.hrm-sec thead th svg{ vertical-align:-2px; }
/* Заголовок, которому не хватило ширины, переносится ПО СЛОГАМ, а не как
   попало: на узком окне «Дата увольнения» рвалась как «увольне|ния» и читалась
   браком. С переносом выходит «уволь-|нения» — видно, что так и задумано.
   Проверено на стенде 27.08.2026 при ширине окна 701 px. */
.hrm-sec thead th{ hyphens:auto; -webkit-hyphens:auto; }
/* Крайние колонки отбиты от края окна на те же 20 px, что шапка и подвал. */
.hrm-sec thead th:first-child, .hrm-sec tbody td:first-child{ padding-left:24px; }
.hrm-sec thead th:last-child,  .hrm-sec tbody td:last-child{ padding-right:24px; }
/* Стрелка сортировки: у активной колонки сплошная, у остальных проступает под
   курсором — иначе по шапке не видно, что сортируется КАЖДЫЙ заголовок. */
.hrm-arr{ display:inline-flex; margin-left:3px; color:var(--text3);
  opacity:0; transition:opacity .12s ease; }
.hrm-sec thead th:hover .hrm-arr{ opacity:.75; }
.hrm-sec thead th.hrm-sorted .hrm-arr{ opacity:1; color:var(--text); }
@media (prefers-reduced-motion: reduce){ .hrm-arr{ transition:none; } }
.hrm-sec tbody tr{ border-bottom:1px solid var(--border); cursor:pointer; }
.hrm-sec tbody tr:hover{ background:var(--card2); }
.hrm-sec tbody tr.hrm-row-on{ background:var(--blue-bg); }
.hrm-sec td{ padding:12px 16px; color:var(--text); }
.hrm-td-cb{ width:38px; padding:12px 0 10px 20px !important; }
.hrm-td-fio{ font-weight:500; }
.hrm-td-date{ font-variant-numeric:tabular-nums; }
.hrm-td-sub{ color:var(--text2); }
/* ГАЛОЧКИ ПРОСТУПАЮТ ПРИ НАВЕДЕНИИ (свод, «Плотные списки», 27.08.2026).
   65 пустых квадратов в первой колонке читались частоколом. Место под галочку
   остаётся всегда (колонка 38 px), поэтому строка не дёргается. Пока что-то
   отмечено — видны все: отмечают обычно пачкой. Тот же приём, что в реестре
   сверки (.reg-r). */
.hrm-cb{ width:15px; height:15px; cursor:pointer; accent-color:var(--blue2);
  opacity:0; transition:opacity .12s ease; }
.hrm-sec tbody tr:hover .hrm-cb, .hrm-cb:checked,
.hrm-sec tbody tr.hrm-row-on .hrm-cb, .hrm-sec:focus-within .hrm-cb,
.hrm-sec.hrm-has-sel .hrm-cb{ opacity:1; }
@media (prefers-reduced-motion: reduce){ .hrm-cb{ transition:none; } }
/* Ссылка на статью ТК рядом с названием: её сверяют, а не читают. */
.hrm-ref{ color:var(--text2); }
/* Единственное цветное место в списке: статью нужно дозаполнить. */
.hrm-nobasis{ color:#B91C1C; }
[data-theme="dark"] .hrm-nobasis{ color:#F87171; }

/* ── КАРТОЧКА ЗАПИСИ: ТО ЖЕ ОКНО, ЧТО И СПИСОК (27.08.2026) ───────────────
   Было: обычное .mc — 520 px, padding 24 по кругу, ни шапки, ни подвала. В
   одном окне жили два разных языка: нажимаешь строку списка — окно съёживается
   втрое, а поле «Добавить комментарий» зажималось кнопкой «Отправить» (на
   колонку оставалось 230 px). Теперь отступы и полосы те же, что у списка, а
   ширина 880 — из набора портала (420 / 560 / 880 / 960). */
.mc.mc-wide.hrm-cardwin{ max-width:880px; }
/* У карточки нет второй строки в шапке — закрываем отступ снизу сами. */
.hrm-wh-card{ padding-bottom:16px; }
.hrm-cardbody{ flex:1; min-height:0; overflow-y:auto; padding:16px 20px; }
.hrm-card{ max-width:none; }
.hrm-card-fio{ font-size:15px; font-weight:600; color:var(--text); }
.hrm-card-sub{ font-size:12px; color:var(--text2); margin-top:2px; }
.hrm-cg{ display:grid; grid-template-columns:1fr 1fr; gap:8px 14px; margin-bottom:9px; }
.hrm-cg2{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:12px; }
@media (max-width:680px){ .hrm-cg, .hrm-cg2{ grid-template-columns:1fr; } }
.hrm-cf{ display:block; }
.hrm-cf-l{ display:block; font-size:12px; color:var(--text2); font-weight:500; margin-bottom:4px; }
.hrm-cf .fi, .hrm-cf .fs{ width:100%; box-sizing:border-box; }
.hrm-cf textarea.fi{ min-height:44px; resize:vertical; }
.hrm-cbox{ border:1px solid var(--border); border-radius:12px; background:var(--card2); padding:12px 12px; }
.hrm-cbox > div:first-child{ margin-top:0; }
/* Подписи блоков «Комментарии» и «Задачи»: были 11 px весом 700 ЗАГЛАВНЫМИ с
   трекингом 1 px — на Windows такие буквы слипаются (свод, п. 8). */
.hrm-cbox-t{ font-size:12px; font-weight:500; color:var(--text2); margin:0 0 8px; }
.hrm-empty{ font-size:13px; color:var(--text2); margin-bottom:8px; }
/* Строка «поле + кнопка» переносится на узком окне, а не давит поле до нечитаемого. */
.hrm-cbox-add{ display:flex; gap:8px; margin-top:8px; flex-wrap:wrap; }
.hrm-cbox-add .fi{ flex:1 1 160px; min-width:0; }
.hrm-cbox-add .btn{ flex:0 0 auto; }

/* Строка комментария и строка задачи в карточке */
.hrm-cm{ background:var(--card); border:1px solid var(--border); border-radius:8px;
  padding:8px 12px; margin-bottom:6px; }
.hrm-cm-t{ font-size:13px; color:var(--text); white-space:pre-wrap; }
.hrm-cm-a{ font-size:12px; color:var(--text2); margin-top:3px; }
.hrm-task{ display:flex; align-items:center; gap:8px; padding:8px 0; }
.hrm-task-t{ font-size:13px; color:var(--text); }
.hrm-task.done .hrm-task-t{ color:var(--text2); text-decoration:line-through; }
.hrm-task-d{ font-size:12px; color:var(--text2); }
.hrm-task-d.late{ color:#B91C1C; }
[data-theme="dark"] .hrm-task-d.late{ color:#F87171; }

/* ── ОКНО ИМПОРТА ────────────────────────────────────────────────────────
   Жило инлайновыми стилями: заголовок 18/800, подсказки на --text3 (2,0),
   шапка предпросмотра 10 px ЗАГЛАВНЫМИ, слово на цветной заливке без ступени. */
.hrm-imp-note{ font-size:12px; color:var(--text2); line-height:1.5;
  margin-bottom:12px; padding:8px 12px; background:var(--card2); border-radius:8px; }
/* <b> по умолчанию 700 — в своде такой насыщенности нет (п. 1). */
.hrm-imp-note b{ font-weight:500; color:var(--text); }
.hrm-imp-pill{ padding:6px 12px; border-radius:8px; font-size:13px; font-weight:500; }
.hrm-imp-green{ background:var(--green-bg); color:#15803D; }
.hrm-imp-blue{ background:var(--blue-bg); color:var(--blue2); }
.hrm-imp-slate{ background:var(--slate-bg); color:#475569; }
.hrm-imp-red{ background:var(--red-bg); color:#B91C1C; }
[data-theme="dark"] .hrm-imp-green{ color:#4ADE80; }
[data-theme="dark"] .hrm-imp-blue{ color:var(--act-hover); }
[data-theme="dark"] .hrm-imp-slate{ color:#CBD5E1; }
[data-theme="dark"] .hrm-imp-red{ color:#F87171; }
.hrm-imp-tbl{ max-height:300px; overflow:auto; border:1px solid var(--border); border-radius:8px; }
.hrm-imp-tbl table{ width:100%; border-collapse:collapse; font-size:13px; }
.hrm-imp-tbl thead tr{ background:var(--card2); }
.hrm-imp-tbl th{ padding:8px 12px; text-align:left; font-size:12px; font-weight:500;
  color:var(--text2); position:sticky; top:0; background:var(--card2); }
.hrm-imp-tbl td{ padding:8px 12px; color:var(--text); vertical-align:top; }
.hrm-imp-tbl tbody tr{ border-top:1px solid var(--border); }
.hrm-imp-sub{ font-size:12px; color:var(--text2); margin-top:2px; }
.hrm-imp-sub s{ color:var(--text2); }
.hrm-imp-warn{ font-size:12px; color:#B45309; margin-top:2px; }
[data-theme="dark"] .hrm-imp-warn{ color:var(--orange); }
.hrm-imp-add{ color:var(--act); font-weight:600; }
[data-theme="dark"] .hrm-imp-add{ color:var(--act-hover); }

/* Форма «Новая запись» */
.hrm-form-sub{ font-size:12px; color:var(--text2); margin-bottom:16px; }
.hrm-fld{ margin-bottom:10px; }
.hrm-req{ color:#B91C1C; }
[data-theme="dark"] .hrm-req{ color:#F87171; }

/* ПОЛЕ В ОКНАХ ДВИЖЕНИЯ КАДРОВ — ОДНО НА ВСЕ ТИПЫ (17.08.2026).
   Было: обычное поле 37 px, а датапикер 40 px, шрифт у всех 14 px мимо общего
   слоя, — в одном ряду «ФИО» и «Дата увольнения» стояли разной высоты.
   Правим ТОЛЬКО внутри .hrm-form: .dp-field и .ep-input живут ещё на десятке
   экранов, общая правка — отдельная задача. */
.hrm-form .fi, .hrm-form .fs, .hrm-form .dp-field, .hrm-form .ep-input{
  font-size:13px; border-radius:8px; padding:8px 11px; min-height:34px;
  height:auto; box-sizing:border-box; }
.hrm-form .dp-field{ height:34px; }
.hrm-form .ep-input{ padding-right:32px; }
.hrm-form textarea.fi{ min-height:54px; }
.hrm-form select.fs{ -webkit-appearance:none; appearance:none; cursor:pointer; padding-right:32px;
  background-image:url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http://www.w3.org/2000/svg%27%20width%3D%2712%27%20height%3D%2712%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27%239CA3AF%27%20stroke-width%3D%272.5%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpolyline%20points%3D%276%209%2012%2015%2018%209%27/%3E%3C/svg%3E);
  background-repeat:no-repeat; background-position:right 11px center; background-size:12px; }

/* Диаграмма «Приход и уход»: объём градиентом, реакция — только яркостью.
   Растягивать столбцы и увеличивать точку на линии владелец забраковала:
   при движении мыши между месяцами картинка дёргалась. */
.hrm-chart-box{ position:relative; }
.hrm-chart{ display:block; }
.hrm-hit{ fill:transparent; }
.hrm-grow{ transform-box:fill-box; opacity:0; animation:hrmGrowY .5s cubic-bezier(.2,.7,.3,1) forwards; }
.hrm-grow-in{ transform-origin:bottom; }
.hrm-grow-out{ transform-origin:top; }
@keyframes hrmGrowY{ from{ opacity:0; transform:scaleY(.02); } to{ opacity:1; transform:scaleY(1); } }
.hrm-bar{ transition:opacity .18s ease; }
.hrm-chart:hover .hrm-m:not(:hover) .hrm-bar{ opacity:.32; }
.hrm-chart:hover .hrm-m:not(:hover) .hrm-lbl{ opacity:.45; }
.hrm-lbl{ transition:opacity .18s ease; }
.hrm-m:hover .hrm-lbl{ fill:var(--text); font-weight:600; }
.hrm-dot{ pointer-events:none; }
.hrm-chart-line{ opacity:0; animation:hrmFadeIn .6s .3s ease forwards; }
@keyframes hrmFadeIn{ to{ opacity:.8; } }
.hrm-tip{ position:absolute; top:4px; pointer-events:none; background:var(--card);
  border:1px solid var(--border); border-radius:12px; box-shadow:0 12px 28px rgba(15,23,42,.16);
  padding:8px 12px; font-size:12px; color:var(--text); min-width:140px; opacity:0;
  transform:translateY(-4px); transition:opacity .14s ease, transform .14s ease; z-index:2; }
.hrm-tip.on{ opacity:1; transform:none; }
.hrm-tip b{ font-variant-numeric:tabular-nums; }
.hrm-tip-l{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:3px; }
.hrm-tip-m{ font-size:11px; color:var(--text3); font-weight: 600; }

/* «Почему уходят».
   ЦВЕТ ПОЛОСЫ УБРАН 17.08.2026: он брался из словаря статей, и четыре строки
   выходили четырёх цветов, хотя статья не бывает «лучше» или «хуже». Красной
   осталась одна полоса — «Статья не проставлена»: с ней надо что-то сделать. */
.hrm-rrow{ padding:4px 8px; margin:0 -8px; border-radius:8px;
  transition:background-color .14s ease, transform .14s ease; }
.hrm-rrow:hover{ background:var(--card2); transform:translateX(2px); }
.hrm-rtop{ display:flex; justify-content:space-between; gap:12px; font-size:13px; margin-bottom:4px; }
.hrm-rref{ color:var(--text2); font-size:12px; }
.hrm-rn{ font-weight:600; font-variant-numeric:tabular-nums; transition:transform .14s ease; }
.hrm-rrow:hover .hrm-rn{ transform:scale(1.12); }
.hrm-rbar{ height:8px; border-radius:99px; background:var(--card2); overflow:hidden; }
.hrm-rfill{ display:block; height:100%; border-radius:99px; background:var(--slate);
  transform-origin:left center;
  transform:scaleX(0); animation:hrmGrowX .55s cubic-bezier(.2,.7,.3,1) forwards; }
.hrm-rfill-bad{ background:var(--red); }
@keyframes hrmGrowX{ to{ transform:scaleX(1); } }

/* «Где движение» */
.hrm-drow{ padding:8px 8px; margin:0 -8px 5px; border-radius:8px; transition:background-color .14s ease; }
.hrm-drow:hover{ background:var(--card2); }
.hrm-dtop{ display:flex; justify-content:space-between; font-size:13px; margin-bottom:4px; }
.hrm-dn{ font-variant-numeric:tabular-nums; }
.hrm-dn b{ font-weight:600; }
.hrm-dbars{ display:flex; align-items:center; gap:4px; height:9px; max-width:420px; }
.hrm-dleft{ flex:1; display:flex; justify-content:flex-end; }
.hrm-dright{ flex:1; }
.hrm-dfill{ display:block; height:9px; transform:scaleX(0);
  animation:hrmGrowX .55s cubic-bezier(.2,.7,.3,1) forwards; }
.hrm-dfill-in{ border-radius:99px 3px 3px 99px; transform-origin:right center; background:var(--green); }
.hrm-dfill-out{ border-radius:3px 99px 99px 3px; transform-origin:left center; background:var(--red); }

/* Бережный режим: всё замирает */
@media (prefers-reduced-motion: reduce){
  .hrm-chip, .hrm-chip u, .hrm-rrow, .hrm-rn, .hrm-drow, .hrm-bar, .hrm-lbl, .hrm-tip{
    transition-duration:.001ms !important; }
  .hrm-grow, .hrm-rfill, .hrm-dfill, .hrm-chart-line{
    animation-duration:.001ms !important; animation-delay:0ms !important; }
  .hrm-grow, .hrm-rfill, .hrm-dfill{ opacity:1 !important; transform:none !important; }
  .hrm-chart-line{ opacity:.8 !important; }
}

/* ============================================================================
   ЖУРНАЛ ДЕЙСТВИЙ — свод правил, 17.08.2026 (макет утверждён владельцем).
   До правки это был худший экран портала по контрасту: 745 надписей из 1467
   ниже 4.5. Причина одна и системная — вторая строка КАЖДОЙ записи (кто и по
   кому) и время стояли на --text3: 2.54 в светлой теме и 2.22 в тёмной.
   Классы общие для app-log.js и app-jsummary.js: сводка и список — один экран,
   разъехаться им нельзя.
   ========================================================================== */
/* Селектор с .scard: у карточки есть своё правило для h2 (16/700), и без
   уточнения оно перебивает класс. */
/* .lg-h1/.lg-sub убраны 27.08.2026: шапка «Журнала» — общий блок .page-head. */

/* ── Сводка работы ── */
.lg-sum-t{ font-size:15px; font-weight:600; color:var(--text); }
.lg-sum-s{ font-size:12px; color:var(--text2); }
.lg-who{ background:var(--card); border:1px solid var(--border); border-radius:8px;
  padding:8px 12px; min-width:150px; }
.lg-who-n{ font-size:13px; font-weight:500; color:var(--text); }
.lg-who-s{ font-size:12px; color:var(--text2); }

/* ЧИПЫ КАТЕГОРИЙ. Их одиннадцать, и каждый был своей краской на своей заливке:
   красный, зелёный, оранжевый, синий, фиолетовый, жёлтый… Это перечень
   сделанного за неделю, а не тревога (свод, п. 4). Цветным остался один —
   «удалено»: он единственный про потерю данных. */
.lg-chip{ padding:6px 12px; border-radius:8px; background:var(--card2); font-size:12px; }
.lg-chip b{ font-weight:600; color:var(--text); font-variant-numeric:tabular-nums; }
.lg-chip span{ color:var(--text2); }
.lg-chip.del b{ color:#B91C1C; }
[data-theme="dark"] .lg-chip.del b{ color:#F87171; }
.lg-del{ font-size:13px; font-weight:500; color:#B91C1C; }
[data-theme="dark"] .lg-del{ color:#F87171; }
.lg-del-s{ font-size:12px; font-weight:400; color:var(--text2); }

/* ── Строка журнала ── */
.lg-row{ display:flex; align-items:center; gap:12px; padding:8px 8px;
  border-bottom:1px solid var(--border); }
.lg-dot{ width:8px; height:8px; border-radius:50%; flex-shrink:0; display:block; }
.lg-act{ font-size:13px; font-weight:500; color:var(--text); }
.lg-meta{ font-size:12px; color:var(--text2); }
.lg-meta b{ font-weight:500; color:var(--text2); }
.lg-time{ font-size:12px; color:var(--text2); white-space:nowrap; flex-shrink:0;
  font-variant-numeric:tabular-nums; }
.lg-date{ padding:8px 0; margin-top:8px; font-size:12px; font-weight:500;
  color:var(--text2); border-bottom:1px solid var(--border); }

/* ── Поиск и полоса глубины ── */
.lg-find{ border-radius:8px; }
.lg-find input{ font-size:13px; padding:8px 12px 8px 34px; }
.lg-note{ border-radius:8px; font-size:12px; color:var(--text2); }
.lg-note b{ font-weight:500; color:var(--text); }

/* ===== ПЛАШКА ПРИЛОЖЕННОГО ФАЙЛА В ТАБЛИЦЕ УЧЁТА =====================
   ТЗ владельца 11.08.2026, вариант Б макета docchips-mockup.html.

   Файл подписывается ВИДОМ документа («заявление», «приказ», «документ»), а не
   именем: имя бывает в несколько предложений и разносит строку. Бирюзовый цвет
   отличает приложенный файл от синей ссылки — сразу видно, что лежит в портале,
   а что снаружи. Имена файлов — в подсказке при наведении. */
/* ПЛАШКА ДОКУМЕНТА — ВЛОЖЕНИЕ, А НЕ ДЕЙСТВИЕ (макет _maket-ritm-akcent.html,
   утверждён владельцем 04.09.2026). Раньше чип брал .lnk-act, и в таблице
   выходило 24 индиговых ссылки против одной кнопки: акцент переставал
   означать «сюда нажимают». Цвет — вторая ступень текста (7.5 на карточке),
   вид документа несёт значок, а не длинная подпись. */
.lp-doc-chip{
  display:inline-flex; align-items:center; gap:4px; min-width:0;
  font-size:11px; white-space:nowrap; cursor:pointer;
  color:var(--text2); overflow:hidden; text-overflow:ellipsis;
}
.lp-doc-chip:hover{ color:var(--text); text-decoration:underline; }
.lp-doc-chip svg{ flex-shrink:0; opacity:.75; }
[data-theme="dark"] .lp-doc-chip{ color:var(--text2); }
[data-theme="dark"] .lp-doc-chip:hover{ color:var(--text); }

/* ПРИЛОЖЕННЫЙ ДОКУМЕНТ — ВАРИАНТ «В» (выбран владельцем 07.09.2026 по макету).
   Было: эмодзи-скрепка и слово «приказ» в бирюзовой каёмке. Владелец: «выглядит
   некрасиво, выделяется в такой каёмочке — сделаем в стиле портала». Две беды
   разом: эмодзи рисуется по-своему на Mac и Windows (запрет 04.08.2026), а
   цветная плашка спорила с плашкой ССЫЛКИ в той же ячейке — та давно нарисована
   значком линиями, без рамки и серым.
   Теперь: значок ЛИСТА (это документ, а не «вложение вообще»), без заливки и
   рамки, серым; при наведении — фирменное индиго. Ссылки не тронуты: их вид
   владелец оставила как есть. Замер: плашка была 88×22 px, стала 73×14. */
.lp-file-pill{
  display:inline-flex; align-items:center; gap:5px;
  font-size:11px; white-space:nowrap; cursor:pointer;
  color:var(--text2);
}
.lp-file-pill:hover{ color:var(--act); }
.lp-file-pill svg{ flex-shrink:0; opacity:.8; }
.lp-file-pill .lp-fp-n{ opacity:.7; font-variant-numeric:tabular-nums; }
[data-theme="dark"] .lp-file-pill:hover{ color:var(--act-hover); }

/* ===== ПЕСОЧНИЦА (app-sandbox.js, ТЗ владельца 17.08.2026) ===== */
/* Полоса СВЕРХУ и НЕСКРЫВАЕМАЯ. Единственная её задача — не дать перепутать,
   где ты находишься: спрятанная полоса однажды означала бы уверенность
   «я в песочнице» над правками, которые уходят в бой.
   Оранжевый, а не красный: это не авария и не ошибка — это режим работы.
   Красный в портале занят просрочкой и опасным действием. */
.sbx-banner{
  position:fixed; top:0; left:0; right:0; z-index:1200;
  height:32px; display:flex; align-items:center; gap:12px;
  padding:0 16px;
  background:var(--orange-bg); border-bottom:1px solid var(--orange);
  font-size:12px; color:var(--text);
}
.sbx-banner b{ font-weight:600; }
/* Страница уезжает вниз ровно на высоту полосы — иначе она накрыла бы шапку. */
body.sbx-on .app-layout{ padding-top:32px; }
.sbx-dot{
  width:8px; height:8px; border-radius:50%;
  background:var(--orange); flex-shrink:0;
}
/* «Выйти» — своя роль, а не общая тихая кнопка. Замер на стенде 17.08.2026:
   обычная .btn на этой полосе давала заметность 1.11 в тёмной теме — слово
   читалось (13.85), а границ кнопки видно не было, и она висела в воздухе.
   Норма 4.5 к кнопке как к объекту не применяется, но 1.11 означает «кнопки
   нет». Поэтому фон прозрачный, а форму держит рамка цветом полосы: она
   заметна в обеих темах, и слово берёт цвет текста (17.11 / 15.33).
   Селектор с ДВУМЯ классами намеренно: у общей кнопки это .btn.btn-s, то есть
   вес 0-2-0, и одиночный .sbx-out ей проигрывал — правило не применялось вовсе,
   а замер показывал прежние 1.31 (17.08.2026).
   Цвет слова взят СТУПЕНЯМИ ИЗ СВОДА (ОФОРМЛЕНИЕ.md, п. 12: оранжевый —
   #B45309 на светлой, --orange на тёмной), а не через --text: замер на стенде
   показал, что общая кнопка тянет свой цвет и слово оставалось светлым на
   кремовой полосе (1.06). Явное значение здесь надёжнее наследования. */
.sbx-banner .sbx-out{
  margin-left:auto;
  background:transparent;
  border:1px solid #B45309;
  color:#B45309;
}
[data-theme="dark"] .sbx-banner .sbx-out{
  border-color:var(--orange);
  color:var(--orange);
}
.sbx-banner .sbx-out:hover{ background:rgba(245,158,11,.14); }

/* Раздел в настройках */
.sbx-acts{ display:flex; gap:8px; flex-wrap:wrap; margin-top:14px; }
.sbx-note{ font-size:11px; color:var(--text2); line-height:1.55; margin:10px 0 0; }
.sbx-q{ font-size:13px; color:var(--text); line-height:1.6; margin:0 0 12px; }
.sbx-two{ display:grid; grid-template-columns:1fr 1fr; gap:24px; }
@media (max-width:720px){ .sbx-two{ grid-template-columns:1fr; } }
.sbx-cap{ font-size:12px; font-weight:600; color:var(--text2); margin-bottom:6px; }
.sbx-list{ margin:0; padding-left:16px; }
.sbx-list li{ font-size:12px; color:var(--text); line-height:1.65; margin-bottom:4px; }
.sbx-info-dot{
  display:inline-block; width:8px; height:8px; border-radius:50%;
  background:var(--blue); margin-top:5px;
}
.sbx-info-dot-a{ background:var(--orange); }

/* Выбор при выходе: две крупные цели вместо кнопок в ряд — «забыть»
   необратимо, и промахнуться мимо него нельзя. */
.sbx-choice{ display:grid; gap:8px; }
.sbx-pick{
  display:block; width:100%; text-align:left; cursor:pointer;
  background:var(--card); border:1px solid var(--border); border-radius:8px;
  padding:12px 16px; font-size:13px; font-weight:500; color:var(--text);
  font-family:inherit;
}
.sbx-pick:hover{ border-color:var(--act); }
.sbx-pick span{
  display:block; font-size:11px; font-weight:400; color:var(--text2);
  margin-top:3px; line-height:1.5;
}

/* Должность «Владелец» в списке пользователей. Не роль (роль у всех троих
   hr_admin), а признак на учётке — но владелец просила видеть его как
   должность, поэтому и выглядит словом, а не галочкой (ТЗ 17.08.2026).
   Цвет — синий: это не отклонение и не тревога, а отличительная подпись.
   Замер: #2563EB на --blue-bg даёт 5.17 на светлой, --blue2 на тёмной — 5.9. */
.stt-owner{
  display:inline-block; padding:2px 8px; border-radius:8px;
  background:var(--blue-bg); color:var(--blue2);
  font-size:12px; font-weight:500;
}

/* Таблица копий данных (app-sandbox.js, экран «Копии»). Шапка как везде после
   свода: 12/500, --text2, без заглавных. */
.sbx-tbl{ width:100%; border-collapse:collapse; font-size:13px; }
.sbx-tbl th{
  padding:8px 12px; text-align:left;
  color:var(--text2); font-size:12px; font-weight:500;
  background:var(--card2);
}
.sbx-tbl td{ padding:8px 12px; border-bottom:1px solid var(--border); }
.sbx-td-d{ color:var(--text); font-weight:500; white-space:nowrap; }
.sbx-td-k{ color:var(--text2); }
.sbx-td-s{ color:var(--text2); white-space:nowrap; }
.sbx-td-a{ text-align:right; white-space:nowrap; }
/* Цвет ТОЛЬКО на отклонении (свод, п. 4): копия заметно меньше текущей базы —
   первый признак, что она не та. У остальных строк никакой пометки нет. */
.sbx-warn{ color:var(--orange); }
.sbx-empty{ font-size:13px; color:var(--text2); text-align:center; padding:16px 0; }
/* Поле подтверждения: слово набирают руками — это защита от случайного нажатия,
   и она должна выглядеть как отдельный шаг, а не как ещё одна строка формы. */
.sbx-conf{ margin:14px 0 4px; }
.sbx-conf label{ display:block; font-size:12px; color:var(--text2); margin-bottom:6px; }
.sbx-conf input{ width:100%; }

/* ===== «ЧТО ИЗМЕНИЛОСЬ» (app-changes.js, ТЗ владельца 17.08.2026) ===== */
.lg-view{ margin-bottom:16px; }
.chg-head{ margin-bottom:14px; }
.chg-note{ font-size:13px; color:var(--text2); padding:16px 0; }
.chg-bad{ color:var(--red); }
.chg-empty{ font-size:13px; color:var(--text2); text-align:center; padding:26px 0; }
.chg-pick{ display:flex; align-items:center; gap:12px; margin-bottom:18px; flex-wrap:wrap; }
.chg-pick-l{ font-size:12px; color:var(--text2); }
.chg-sel{ min-width:280px; }

/* Сводка. Цвет ТОЛЬКО у исчезнувшего и только когда оно есть (свод, п. 4):
   ноль пропаж — норма, и красить её незачем. */
.chg-sum{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:20px; }
.chg-t{
  background:var(--card2); border:1px solid var(--border); border-radius:8px;
  padding:12px 16px; min-width:130px;
}
.chg-t-n{ font-size:20px; font-weight:600; color:var(--text); font-variant-numeric:tabular-nums; }
.chg-t-l{ font-size:11px; color:var(--text2); margin-top:2px; }
/* Ступени красного из свода (п. 12): чистый --red на подложке --card2 даёт
   4.03 в тёмной теме — замер на стенде 17.08.2026, чуть ниже нормы 4.5. */
.chg-t-bad .chg-t-n{ color:#B91C1C; }
[data-theme="dark"] .chg-t-bad .chg-t-n{ color:#F87171; }

.chg-sec{ margin-bottom:22px; }
.chg-sec-h{ font-size:13px; font-weight:600; color:var(--text); margin-bottom:4px; }
.chg-n{ color:var(--text2); font-weight:400; }
.chg-sec-p{ font-size:11px; color:var(--text2); line-height:1.55; margin-bottom:8px; }

.chg-row{
  display:grid; grid-template-columns:1fr 1.4fr auto; gap:12px;
  padding:8px 0; border-bottom:1px solid var(--border); align-items:baseline;
}
@media (max-width:820px){ .chg-row{ grid-template-columns:1fr; gap:2px; } }
.chg-who{ font-size:13px; font-weight:500; color:var(--text); }
.chg-what{ font-size:12px; color:var(--text2); line-height:1.6; }
.chg-fld{ color:var(--text); }
.chg-minus{ color:#B91C1C; }
[data-theme="dark"] .chg-minus{ color:#F87171; }
.chg-plus{ color:var(--text2); }

/* «Нет записей в журнале» — это и есть отклонение, ради которого экран сделан.
   Оранжевый, а не красный: это повод посмотреть, а не авария. Ступень слова
   взята из свода (п. 12): #B45309 на светлой, --orange на тёмной. */
.chg-trace{ font-size:11px; text-align:right; white-space:nowrap; }
.chg-no{ color:#B45309; }
[data-theme="dark"] .chg-no{ color:var(--orange); }
.chg-more{ font-size:11px; color:var(--text2); padding-top:8px; }

/* ===== «ВСЁ ЛИ В ПОРЯДКЕ» (app-checkup.js, ТЗ владельца 17.08.2026) ===== */
.chk-h{ display:flex; align-items:flex-start; gap:16px; margin-bottom:16px; }
.chk-title{ font-size:15px; font-weight:600; color:var(--text); margin:0; }
.chk-sub{ font-size:12px; color:var(--text2); margin-top:2px; }

/* Один ответ крупно — ради него экран и сделан. Цвет только на отклонении:
   «чисто» словом без заливки, найденное — числом со ступенью свода. */
.chk-verdict{
  font-size:15px; font-weight:600; color:var(--text);
  padding:12px 16px; border-radius:8px; background:var(--card2);
  margin-bottom:18px;
}
.chk-ok{ color:var(--text); }
.chk-bad{ color:#B91C1C; background:var(--red-bg); }
[data-theme="dark"] .chk-bad{ color:#F87171; }

.chk-list{ border-top:1px solid var(--border); }
.chk-row{
  display:grid; grid-template-columns:46px 1fr auto; gap:12px;
  padding:12px 0; border-bottom:1px solid var(--border); align-items:center;
}
.chk-n{
  font-size:20px; font-weight:600; color:var(--text2);
  text-align:right; font-variant-numeric:tabular-nums;
}
/* Ноль — норма, и он не должен кричать. Цвет появляется только у найденного. */
.chk-есть .chk-n{ color:#B91C1C; }
[data-theme="dark"] .chk-есть .chk-n{ color:#F87171; }
/* Тире у непроверенной строки: --text3 даёт 2.22 в тёмной теме и для текста
   не годится (свод, п. 4). Замер на стенде 17.08.2026. */
.chk-нет .chk-n{ color:var(--text2); }
/* СПРАВКА — НЕ НАХОДКА (27.08.2026). «Остаток больше, чем запланировано» есть
   почти у всех и нарушением не является. Число у неё обычного цвета: красная
   цифра означала бы отклонение там, где его нет (свод, п. 4). */
.chk-справка .chk-n{ color:var(--text2); }
.chk-spravka{ font-size:12px; color:var(--text2); margin:-12px 0 18px; padding:0 16px; }
.chk-t{ font-size:13px; font-weight:500; color:var(--text); }
.chk-why{ font-size:11px; color:var(--text2); line-height:1.55; margin-top:2px; }
.chk-det{ font-size:11px; color:var(--text2); margin-top:2px; }
/* Непроверенное не прячем: сводка, которая молчит о том, чего не сделала,
   опаснее отсутствующей. Оранжевый — «посмотрите», а не «авария». */
.chk-нет .chk-why{ color:#B45309; }
[data-theme="dark"] .chk-нет .chk-why{ color:var(--orange); }
.chk-note{ font-size:11px; color:var(--text2); line-height:1.6; margin-top:16px; }

.chk-tbl{ width:100%; border-collapse:collapse; font-size:13px; }
.chk-tbl th{
  padding:8px 12px; text-align:left; background:var(--card2);
  color:var(--text2); font-size:12px; font-weight:500;
}
.chk-tbl td{ padding:8px 12px; border-bottom:1px solid var(--border); color:var(--text); }
/* Число в виджете «Всё ли в порядке»: ступень красного из свода — чистый --red
   на карточке в тёмной теме не дотягивает до 4.5. */
[data-theme="dark"] .chk-w-n{ color:#F87171 !important; }
/* Отступы окна «Всё ли в порядке»: общий .mc-wide идёт с padding:0 (им живут
   широкие окна с таблицами во всю ширину), поэтому свои поля — здесь. */
.chk-wrap{ padding:24px 24px; }

/* ===== «КТО НЕ ОТГУЛЯЕТ ДО КОНЦА ГОДА» (app-vacplan.js, 17.08.2026) ===== */
.vpl-wrap{ padding:24px 24px; }
.vpl-head{ display:flex; align-items:flex-start; gap:16px; margin-bottom:16px; }
.vpl-title{ font-size:15px; font-weight:600; color:var(--text); margin:0; }
.vpl-sub{ font-size:12px; color:var(--text2); margin-top:2px; }

.vpl-sum{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:20px; }
.vpl-t{
  background:var(--card2); border:1px solid var(--border); border-radius:8px;
  padding:12px 16px; min-width:120px;
}
.vpl-t-n{ font-size:20px; font-weight:600; color:var(--text); font-variant-numeric:tabular-nums; }
.vpl-t-l{ font-size:11px; color:var(--text2); margin-top:2px; }
/* Цвет только на отклонении: «без плана» и «больше 28 дней» — то, с чего
   начинают разговор. Общее число людей и дней — не тревога, а масштаб. */
.vpl-t-bad .vpl-t-n{ color:#B91C1C; }
[data-theme="dark"] .vpl-t-bad .vpl-t-n{ color:#F87171; }

.vpl-org{
  font-size:12px; font-weight:600; color:var(--text2);
  margin:18px 0 8px;
}
.vpl-dep{ border:1px solid var(--border); border-radius:8px; margin-bottom:10px; overflow:hidden; }
.vpl-dep-h{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  padding:12px 16px; background:var(--card2);
}
.vpl-dep-n{ font-size:13px; font-weight:500; color:var(--text); }
.vpl-dep-c{ font-size:12px; color:var(--text2); margin-left:auto; }

/* Месяцы до конца года. Свободный подписан цветом — это подсказка «сюда можно»,
   единственное место экрана, где цвет означает не отклонение, а возможность. */
.vpl-mon{ display:flex; gap:8px; flex-wrap:wrap; padding:12px 16px; }
.vpl-m{
  font-size:11px; padding:3px 8px; border-radius:8px;
  background:var(--card2); color:var(--text2); border:1px solid var(--border);
}
/* Красим ЗАНЯТЫЕ месяцы — это отклонение. Свободные не перечисляем вовсе:
   на боевом снимке свободны почти все, и пять зелёных меток не помогали
   выбрать ничего (замер 17.08.2026). */
.vpl-m-busy{ background:var(--orange-bg); color:#B45309; border-color:transparent; }
[data-theme="dark"] .vpl-m-busy{ color:var(--orange); }
.vpl-mon-l{ font-size:11px; color:var(--text2); align-self:center; }

.vpl-tbl{ width:100%; border-collapse:collapse; font-size:13px; }
.vpl-tbl th{
  padding:8px 16px; text-align:left; color:var(--text2);
  font-size:12px; font-weight:500; border-top:1px solid var(--border);
}
.vpl-tbl td{ padding:8px 16px; border-top:1px solid var(--border); color:var(--text); }
.vpl-r-bad td:last-child{ color:#B91C1C; }
[data-theme="dark"] .vpl-r-bad td:last-child{ color:#F87171; }
.vpl-noplan{ color:#B45309; }
[data-theme="dark"] .vpl-noplan{ color:var(--orange); }
.vpl-note{ font-size:11px; color:var(--text2); line-height:1.6; margin-top:14px; padding:0 2px; }
.vpl-warn{ color:#B45309; }
[data-theme="dark"] .vpl-warn{ color:var(--orange); }
.vpl-empty{ font-size:13px; color:var(--text2); text-align:center; padding:26px 0; }

/* ═══════════════════════════════════════════════════════════════════════
   ОБОИ КАЛЕНДАРЯ (app-calwall.js) — заказ владельца 19.08.2026
   Пять светлых вариантов из макета cal-wallpaper-mockup.html. Тёмные
   (Графит, Северное сияние, Сталь) владелец переносить не велела.

   УСТРОЙСТВО. Обои — ДВА слоя под вкладкой: ::before держит градиент
   (глубину), ::after — текстуру (зерно, ткань, изолинии). Одним градиентом
   выходит плоскость, поэтому слоя два. Панели календаря сверху получают
   «стекло»: полупрозрачный фон, светлый край и тень — окошки читаются
   приподнятыми над поверхностью, а не наклеенными на неё.

   ЧИТАЕМОСТЬ. Ячейки почти непрозрачны (0.93–0.94), панель вокруг них — 0.58–0.62:
   на панели текст стоит редко (заголовок месяца, шапка «Производств.»), а сквозь
   неё как раз и видно поверхность. Замер композита 19.08.2026, худший угол
   градиента:

     вариант     панель text/text2     ячейка text/text2
     Бумага      16.11 / 6.86          17.35 / 7.39
     Лён         15.79 / 6.73          17.62 / 7.51
     Туман       16.84 / 7.17          17.68 / 7.53
     Изолинии    16.43 / 7.00          17.66 / 7.52
     Сумерки     16.62 / 7.08          17.67 / 7.53

   Эталон без обоев — 17.85 и 7.56. Худшая потеря 2.06 у --text на панели «Лён»,
   норма 4.5 (свод, п. 6) выдерживается с восьмикратным запасом.

   ТОЛЬКО СВЕТЛАЯ ТЕМА — отсюда html:not([data-theme="dark"]) в каждом
   селекторе: на тёмной те же обои просвечивают сквозь панели грязным пятном
   (проверено на стенде). Окно выбора объясняет это словами.

   ПАЛИТРА НЕ ТРОНУТА (свод, п. 12): все оттенки здесь — нейтральный бежевый,
   серо-голубой и шалфейный, ни одного статусного цвета. Зелёный и оранжевый
   в фоне означали бы состояние отпуска, а фон ничего означать не должен.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Переменные варианта ── */
html:not([data-theme="dark"])[data-calwall="paper"]{
  --cw-grad:
    radial-gradient(1200px 600px at 12% -10%, #FFFDF7 0%, rgba(255,253,247,0) 60%),
    radial-gradient(900px 700px at 100% 110%, #EFE7DA 0%, rgba(239,231,218,0) 65%),
    linear-gradient(160deg,#FAF6EE 0%,#F3ECE0 55%,#EDE4D5 100%);
  --cw-tex:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.10'/%3E%3C/svg%3E");
  --cw-glass:rgba(255,253,248,.62); --cw-cell:rgba(255,253,248,.93);
  --cw-cell2:rgba(244,238,228,.93);
  --cw-line:rgba(255,255,255,.75); --cw-brd:rgba(140,120,90,.22);
  --cw-shadow:0 10px 30px -12px rgba(90,70,40,.28);
}
html:not([data-theme="dark"])[data-calwall="linen"]{
  --cw-grad:
    radial-gradient(900px 500px at 80% 0%, #FFFFFF 0%, rgba(255,255,255,0) 55%),
    linear-gradient(155deg,#F2F1EC 0%,#E9E8E1 60%,#DFDED5 100%);
  --cw-tex:
    repeating-linear-gradient(45deg, rgba(255,255,255,.28) 0 2px, rgba(0,0,0,.025) 2px 4px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.22) 0 2px, rgba(0,0,0,.02) 2px 4px);
  --cw-glass:rgba(255,255,255,.60); --cw-cell:rgba(255,255,255,.94);
  --cw-cell2:rgba(243,242,237,.94);
  --cw-line:rgba(255,255,255,.8); --cw-brd:rgba(90,90,75,.2);
  --cw-shadow:0 10px 28px -14px rgba(60,60,45,.3);
}
html:not([data-theme="dark"])[data-calwall="mist"]{
  --cw-grad:
    radial-gradient(700px 500px at 15% 10%, #DCE9F7 0%, rgba(220,233,247,0) 60%),
    radial-gradient(600px 600px at 85% 20%, #E7E2F5 0%, rgba(231,226,245,0) 62%),
    radial-gradient(800px 500px at 60% 110%, #DFF0EE 0%, rgba(223,240,238,0) 60%),
    linear-gradient(170deg,#F4F7FB 0%,#EDF1F7 100%);
  --cw-tex:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.07'/%3E%3C/svg%3E");
  --cw-glass:rgba(255,255,255,.58); --cw-cell:rgba(255,255,255,.93);
  --cw-cell2:rgba(240,244,249,.93);
  --cw-line:rgba(255,255,255,.85); --cw-brd:rgba(70,95,130,.18);
  --cw-shadow:0 12px 32px -14px rgba(40,70,110,.28);
}
html:not([data-theme="dark"])[data-calwall="topo"]{
  --cw-grad:
    radial-gradient(900px 600px at 90% 0%, #EEF3EF 0%, rgba(238,243,239,0) 60%),
    linear-gradient(165deg,#EFF2EE 0%,#E4E9E3 100%);
  --cw-tex:
    repeating-radial-gradient(circle at 18% 22%, rgba(70,95,80,.12) 0 1px, rgba(0,0,0,0) 1px 26px),
    repeating-radial-gradient(circle at 82% 78%, rgba(70,95,80,.09) 0 1px, rgba(0,0,0,0) 1px 34px);
  --cw-glass:rgba(255,255,255,.62); --cw-cell:rgba(255,255,255,.94);
  --cw-cell2:rgba(240,244,240,.94);
  --cw-line:rgba(255,255,255,.8); --cw-brd:rgba(60,85,70,.2);
  --cw-shadow:0 10px 28px -14px rgba(40,70,50,.3);
}
html:not([data-theme="dark"])[data-calwall="dusk"]{
  --cw-grad:
    radial-gradient(700px 500px at 10% 0%, #FBE7DD 0%, rgba(251,231,221,0) 58%),
    radial-gradient(700px 600px at 95% 30%, #E6DEF2 0%, rgba(230,222,242,0) 60%),
    linear-gradient(160deg,#FAF3F0 0%,#F1EAF2 100%);
  --cw-tex:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.09'/%3E%3C/svg%3E");
  --cw-glass:rgba(255,255,255,.60); --cw-cell:rgba(255,255,255,.94);
  --cw-cell2:rgba(246,240,244,.94);
  --cw-line:rgba(255,255,255,.85); --cw-brd:rgba(120,90,110,.2);
  --cw-shadow:0 12px 30px -14px rgba(110,70,100,.26);
}

/* Селектор — просто .main-calwall, без .main: у контейнера #main класс
   «app-body», а правило .main в этом файле досталось от старой вёрстки и ни на
   что не попадает (со связкой .main.main-calwall не применялось НИЧЕГО —
   стенд 19.08.2026).

   ПОЧЕМУ ФОНОМ КОНТЕЙНЕРА, А НЕ СЛОЯМИ ПОД ВКЛАДКОЙ. Сначала обои лежали
   двумя псевдоэлементами под .cal-v2-wrap. Две беды, обе найдены на стенде:
   на вкладке «Производств.» разметка своя, .cal-v2-wrap там нет — и фон
   пропадал при переключении вида; а #main прокручивается, и абсолютный слой
   уезжал вместе с содержимым, обрываясь на высоте первого экрана.

   Теперь оба слоя — background-image самого #main: текстура сверху, градиент
   под ней. background-attachment:fixed держит рисунок неподвижным
   относительно окна, но показывает его ТОЛЬКО в границах вкладки: левое меню
   и шапка портала остаются как были. Прозрачность текстуры вшита в неё саму
   (opacity у SVG, альфа у градиентов) — у фонового слоя своей нет.
   background-size: auto для текстуры (иначе тайл шума растянется в мыло)
   и cover для градиента. */
html:not([data-theme="dark"]) .main-calwall{
  background-image: var(--cw-tex), var(--cw-grad);
  background-repeat: repeat, no-repeat;
  background-size: auto, cover;
  background-attachment: fixed, fixed;
  background-position: center, center;
}

/* ── Панели: «стекло» вместо сплошного --card ── */
html:not([data-theme="dark"]) .main-calwall .cal-v2-topbar,
html:not([data-theme="dark"]) .main-calwall .cal-v2-fbar{
  background: var(--cw-glass); border-color: var(--cw-brd);
  box-shadow: inset 0 1px 0 var(--cw-line);
}
html:not([data-theme="dark"]) .main-calwall .cal-v2-layout{
  background: var(--cw-glass); border-color: var(--cw-brd);
  box-shadow: var(--cw-shadow);
}
html:not([data-theme="dark"]) .main-calwall .cal-v2-grid{
  background: var(--cw-brd); border-color: var(--cw-brd);
}
html:not([data-theme="dark"]) .main-calwall .cal-v2-cell{ background: var(--cw-cell); }
html:not([data-theme="dark"]) .main-calwall .cal-v2-cell.wknd{ background: var(--cw-cell2); }
/* Чужой месяц — прозрачный: сквозь него видно саму поверхность обоев.
   Приглушение числа осталось прежним (правило .other-m .cal-v2-cell-num). */
html:not([data-theme="dark"]) .main-calwall .cal-v2-cell.other-m{ background: transparent; }
/* Кнопки и чипы шапки — на том же стекле, иначе белые пятна на цветном фоне */
html:not([data-theme="dark"]) .main-calwall .cal-v2-nav-btn,
html:not([data-theme="dark"]) .main-calwall .cal-v2-today-btn,
html:not([data-theme="dark"]) .main-calwall .cal-v2-filter-chip{
  background: var(--cw-cell); border-color: var(--cw-brd);
}
/* Акцентные кнопки («Новая задача», включённая правка календаря) свою заливку
   сохраняют: цвет здесь означает действие, а не оформление. */
html:not([data-theme="dark"]) .main-calwall .cal-v2-today-btn.cal-v2-btn-accent{
  background: var(--blue-bg); border-color: #38BDF8;
}
html:not([data-theme="dark"]) .main-calwall .cal-v2-today-btn.cal-v2-btn-editing{
  background: var(--orange-bg); border-color: var(--orange);
}
html:not([data-theme="dark"]) .main-calwall .cal-v2-filter-chip.active{
  background: var(--blue-bg); border-color: var(--blue);
}
/* Полоса «задач в этом месяце нет» под сеткой: её --card2 на обоях читался
   серой заплаткой. */
html:not([data-theme="dark"]) .main-calwall .cal-v2-empty-hint{
  background: var(--cw-cell2); border-color: var(--cw-brd);
}
/* Недельный вид: строки дня — свои карточки на --card, и на обоях они
   выглядели белыми заплатками. Списочному виду правило не нужно: там строки
   без фона, только разделители. */
html:not([data-theme="dark"]) .main-calwall .cal-week-row{
  background: var(--cw-cell); border-color: var(--cw-brd);
}
html:not([data-theme="dark"]) .main-calwall .cal-week-row.wknd{ background: var(--cw-cell2); }
html:not([data-theme="dark"]) .main-calwall .cal-v2-list-month{
  background: var(--cw-cell2); border-color: var(--cw-brd);
}

/* ── Плитки в окне выбора: каждая рисует свой вариант ── */
.cw-gal{ display:flex; flex-wrap:wrap; gap:12px; }
.cw-tile{
  width:140px; padding:0; text-align:left; cursor:pointer; font-family:inherit;
  background:var(--card); border:1px solid var(--border); border-radius:12px;
  overflow:hidden; transition:transform .15s, box-shadow .15s, border-color .15s;
}
.cw-tile:hover{ transform:translateY(-2px); box-shadow:var(--shadow-lg); }
.cw-tile.on{ border-color:var(--act); box-shadow:0 0 0 2px rgba(56,189,248,.35); }
.cw-pic{ display:block; height:74px; position:relative; }
.cw-pic i{ position:absolute; inset:0; display:block; }
.cw-pic-g{ background:var(--cw-tg); }
.cw-pic-t{ background:var(--cw-tt); opacity:var(--cw-tto,0); }
/* Полоска внизу превью — то самое «окошко» поверх обоев: по ней видно, как
   ляжет панель календаря, а не только сам фон. */
.cw-pic b{
  position:absolute; left:12px; right:12px; bottom:10px; height:24px; border-radius:8px;
  background:var(--cw-tglass); border:1px solid var(--cw-tbrd);
  box-shadow:inset 0 1px 0 var(--cw-tline);
}
.cw-cap{ display:block; padding:8px 12px 8px; }
.cw-nm{ display:block; font-size:12px; font-weight:500; color:var(--text); }
.cw-hint{ display:block; font-size:11px; color:var(--text2); margin-top:1px; }
@media (prefers-reduced-motion: reduce){ .cw-tile{ transition:none; } }

/* ═══════════════════════════════════════════════════════════════════════
   КАРТОЧКА ЗАДАЧИ — ОКНО ПО МАКЕТУ cal-week-v2-mockup.html
   Перенесено 19.08.2026 дословно, по требованию владельца «переносим до
   пикселя». Замер ДО правки на стенде: окно 520 px, а разделительная линия
   шапки — 472. Разница в 48 px — это padding:24px у .mc: карточка рисовала
   свою шапку с собственными отступами ВНУТРИ уже отступленного окна, и
   линии обрывались, не доходя до краёв. Отсюда ощущение «модалка съехала».

   Лечится не подгонкой чисел, а ролью: у окна отступов нет вовсе (padding:0),
   отступы задают его части — шапка, тело, футер. Тогда линия идёт от края до
   края по определению, а не потому, что подобрали значение.
   ═══════════════════════════════════════════════════════════════════════ */
.mc.mc-card{
  /* Ширина под две колонки: 560 px было ровно на одну, и карточка вытягивалась
     вниз на весь экран (22.08.2026). 880 — сумма двух колонок и отступов,
     считана от содержимого, а не подобрана на глаз. */
  max-width: 880px; width: 94%; max-height: 88vh;
  padding: 0; overflow: hidden;
  display: flex; flex-direction: column;
}
.tkc-head{
  display: flex; align-items: center; gap: 12px;
  padding: 16px 24px; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
/* Плашка типа — «таблетка» 99, как фильтры по всему порталу. Была r6 и
   насыщенность 700: ни того скругления, ни той насыщенности в своде нет
   (пп. 1 и 3). Цвет пары «заливка + слово» приходит переменными от типа. */
.tkc-tag{
  font-size: 11px; font-weight: 500; padding: 3px 8px; border-radius: 99px;
  white-space: nowrap;
}
/* Пары «заливка + слово» по тонам. Ступени слова взяты из свода
   «Оформление» (таблица в п. 12), отдельно на светлую и тёмную тему:
   оттенок, проходящий на белом, на тёмном проваливается, и наоборот. */
.tkc-tag.tkc-t-blue  { background: var(--blue-bg);   color: #2563EB; }
.tkc-tag.tkc-t-green { background: var(--green-bg);  color: #15803D; }
.tkc-tag.tkc-t-pink  { background: var(--pink-bg);   color: #BE185D; }
.tkc-tag.tkc-t-orange{ background: var(--orange-bg); color: #B45309; }
.tkc-tag.tkc-t-purple{ background: var(--purple-bg); color: #6D28D9; }
[data-theme="dark"] .tkc-tag.tkc-t-blue  { color: #60A5FA; }
[data-theme="dark"] .tkc-tag.tkc-t-green { color: #4ADE80; }
[data-theme="dark"] .tkc-tag.tkc-t-pink  { color: #F472B6; }
[data-theme="dark"] .tkc-tag.tkc-t-orange{ color: var(--orange); }
[data-theme="dark"] .tkc-tag.tkc-t-purple{ color: #A78BFA; }
.tkc-title{ flex: 1; margin: 0; font-size: 15px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.tkc-x{
  border: none; background: var(--card2); border-radius: 8px;
  width: 30px; height: 30px; cursor: pointer; font-size: 13px; color: var(--text2);
  font-family: inherit; flex-shrink: 0;
}
.tkc-x:hover{ background: var(--border); }
/* Прокручивается ТЕЛО, а не окно: иначе шапка и футер уезжают вместе с
   содержимым — та же беда, что у .mc-wide без внутреннего тела. */
.tkc-body{ padding: 16px 20px; overflow-y: auto; flex: 1; min-height: 0; }
/* ДВЕ КОЛОНКИ В КАРТОЧКЕ (22.08.2026). Слева — что делаем, справа — свойства;
   чек-лист и комментарии идут во всю ширину под ними. До правки все одиннадцать
   полей стояли одной колонкой: окно 560 × 792 при экране 900 и ещё 102 px
   прокрутки внутри.
   Ниже 900 px окна колонки схлопываются в одну — порядок остаётся прежним,
   сверху вниз, поэтому на узком экране карточка выглядит как раньше. */
.tkc-cols{ display: grid; grid-template-columns: 1.15fr 1fr; gap: 0 22px; align-items: start; }
/* Новая задача — одна колонка: заполнять вторую нечем (чек-лист, вложения и
   комментарии появляются только у сохранённой), и окно выглядело полупустым. */
.tkc-cols-one{ grid-template-columns: 1fr; }
.mc.mc-card.mc-card-one{ max-width: 560px; }
.tkc-col-main{ min-width: 0; grid-column: 1; grid-row: 1; }
/* Свойства держат обе строки правого столбца, а работа по задаче (чек-лист и
   переписка) встаёт ПОД ОПИСАНИЕМ, второй строкой левого. Иначе с одним
   пунктом чек-листа слева зияло 268 px пустоты, а сам пункт лежал полосой
   под окном (жалоба владельца 26.08.2026, замеры — в app-tasks.js). */
.tkc-col-side{ min-width: 0; grid-column: 2; grid-row: 1 / span 2; }
.tkc-col-work{ min-width: 0; grid-column: 1; grid-row: 2; }
/* Одна колонка (узкое окно или новая задача) — порядок источника: название,
   описание, свойства, и только потом чек-лист с перепиской. Сроки и время не
   должны уезжать под комментарии. */
.tkc-cols-one .tkc-col-main,
.tkc-cols-one .tkc-col-side,
.tkc-cols-one .tkc-col-work{ grid-column: 1; grid-row: auto; }
@media (max-width: 900px){
  .tkc-cols{ grid-template-columns: 1fr; }
  .tkc-col-main, .tkc-col-side, .tkc-col-work{ grid-column: 1; grid-row: auto; }
}
.tkc-foot{
  display: flex; align-items: center; gap: 8px;
  padding: 16px 24px; border-top: 1px solid var(--border); flex-shrink: 0;
}
.tkc-foot-sp{ flex: 1; }
/* Ряды полей: две и три колонки. Третья строка — «Дата · Время с · до». */
.tkc-row2{ display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tkc-row3{ display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 12px; }
/* В боковой колонке три поля в ряд не помещаются: при ширине колонки 380 px
   «Выполнено» обрезалось до «Выполнен» (замер 22.08.2026). Даём два в ряд;
   третье поле встаёт под ними ПОЛОВИНОЙ ширины, а не во всю: растянутый
   «Приоритет» выглядел важнее «Вида» и «Статуса», хотя он им ровня. */
.tkc-col-side .tkc-row3{ grid-template-columns: 1fr 1fr; }
/* В одноколоночной форме (новая задача) места хватает на все три поля в ряд —
   иначе «Приоритет» стоял один в строке, а рядом с ним зияла пустая половина. */
.tkc-cols-one .tkc-col-side .tkc-row3{ grid-template-columns: 1.2fr 1fr 1fr; }
/* Поля времени — обычные <select> портала (шаг 15 минут, tkTimeOptions в
   app-tasks.js). Нативный input[type=time] здесь был и убран 19.08.2026:
   на маке и на Windows он рисуется по-разному, а пустое значение показывает
   как «--:--» — в форме портала это выглядело чужеродно. Своих стилей полю
   не нужно: оно берёт общий _TK_SELECT, как «Статус» и «Приоритет». */
/* Подсказка под полями времени — почему пусто значит «весь день» */
.tkc-note{
  font-size: 11px; color: var(--text2); line-height: 1.55;
  padding: 12px 12px; background: var(--card2); border-radius: 8px; margin-top: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════
   НЕДЕЛЯ ПО ЧАСАМ (app-calweek.js) — макеты cal-week-hours-mockup.html и
   cal-week-v2-mockup.html, приняты владельцем 19.08.2026, перенос дословный.

   Три яруса одной grid-раскладкой: шапка дней, полоса «весь день», сетка
   часов. Колонка времени и колонки дней описаны одним grid-template в трёх
   местах — так линии совпадают по пикселю, а не «на глаз».

   Линии часов и получасов — фоном колонки, а не отдельными элементами: при
   сутках и семи днях это 336 лишних узлов на экран.
   ═══════════════════════════════════════════════════════════════════════ */
.cw{ display:flex; flex-direction:column; flex:1; min-height:0; --cw-gut:58px; }

/* Панель вида: диапазон часов и масштаб */
.cw-bar{ display:flex; align-items:center; gap:8px; padding:0 0 4px; flex-shrink:0; }
.cw-bar-sp{ flex:1; }
.cw-bar-lbl{ font-size:11px; color:var(--text2); }
.cw-seg{ display:flex; background:var(--border); border-radius:8px; padding:3px; gap:2px; }
.cw-seg-b{ padding:5px 12px; border-radius:8px; border:none; background:none; font-size:12px;
  font-weight:500; color:var(--text2); cursor:pointer; font-family:inherit; }
.cw-seg-b.on{ background:var(--card); color:var(--text); box-shadow:0 1px 4px rgba(0,0,0,.08); }
.cw-zoom{ width:28px; height:28px; border-radius:8px; border:1px solid var(--border);
  background:var(--card); color:var(--text2); cursor:pointer; font-size:13px; font-family:inherit; }
.cw-zoom:hover{ border-color:var(--act); color:var(--act); }

/* Шапка дней */
.cw-head{ display:grid; grid-template-columns:var(--cw-gut) repeat(7,minmax(0,1fr));
  border:1px solid var(--border); border-radius:12px 12px 0 0; background:var(--card); flex-shrink:0; }
.cw-head-gut{ border-right:1px solid var(--border); }
/* День в шапке кликабелен — заводит задачу на весь день (07.09.2026, взамен
   входа, который был у скрытой теперь полосы «весь день»). Подсветка тихая:
   это не кнопка, а место, куда можно нажать. */
.cw-day-act{ cursor:pointer; transition:background-color .12s linear; }
.cw-day-act:hover{ background:var(--card2); }
/* ШАПКА ДНЕЙ КОМПАКТНЕЕ (ТЗ владельца 07.09.2026): день недели и число стоят в
   одну строку, а не столбиком. Было 64 px, стало 44 — на ноутбуке 1280×720 это
   почти полтора часа сетки. Кружок «сегодня» сохранён. */
.cw-day{ padding:6px 8px; text-align:center; border-left:1px solid var(--border);
  display:flex; align-items:center; justify-content:center; gap:6px; }
.cw-day:first-of-type{ border-left:none; }
.cw-dname{ font-size:11px; font-weight:500; color:var(--text2); }
.cw-day.wknd .cw-dname{ color:#B91C1C; }
[data-theme="dark"] .cw-day.wknd .cw-dname{ color:#F87171; }
.cw-dnum{ display:inline-flex; align-items:center; justify-content:center; min-width:26px; height:26px;
  padding:0 5px; border-radius:99px; font-size:14px; font-weight:500;
  color:var(--text); font-variant-numeric:tabular-nums; }
.cw-day.today .cw-dnum{ background:var(--blue2); color:#fff; font-weight:600; }
.cw-day.today .cw-dname{ color:var(--blue2); }
[data-theme="dark"] .cw-day.today .cw-dnum{ background:#38BDF8; color:var(--accent-text); }
[data-theme="dark"] .cw-day.today .cw-dname{ color:#60A5FA; }

/* Полоса «весь день» */
.cw-allday{ display:grid; grid-template-columns:var(--cw-gut) repeat(7,minmax(0,1fr));
  border:1px solid var(--border); border-top:none; background:var(--card2); flex-shrink:0; }
.cw-allday-lbl{ font-size:11px; color:var(--text2); padding:8px 8px 8px 0; text-align:right;
  border-right:1px solid var(--border); }
.cw-allday-col{ border-left:1px solid var(--border); padding:8px 4px; display:flex;
  flex-direction:column; gap:4px; min-height:38px; cursor:pointer; }
.cw-allday-col:first-of-type{ border-left:none; }
.cw-ad{ display:flex; align-items:center; gap:4px; padding:2px 8px; border-radius:8px;
  font-size:11px; color:var(--text); background:var(--card); border:1px solid var(--border);
  white-space:nowrap; overflow:hidden; cursor:pointer; }
.cw-ad i{ width:6px; height:6px; border-radius:50%; flex-shrink:0; }
.cw-ad span{ overflow:hidden; text-overflow:ellipsis; }
/* ЗАЧЁРКНУТО ОДНОЙ ЧЕРТОЙ (ТЗ владельца 25.08.2026). Здесь стояло обратное
   решение от 19.08.2026 — «приглушаем, но не зачёркиваем, а по фильтру
   „Активные“ его тут и не бывает». Вторая половина довода отпала: календарь
   открывается на «Все» (CAL_TASK_STATUS в app-calendar.js), завершённое
   теперь на экране всегда, и приглушения мало — сделанное надо отличать от
   бледного, а не угадывать. Месяц и список зачёркивают с самого начала,
   неделя была единственной, кто выбивался. */
.cw-ad.done{ opacity:.55; text-decoration:line-through; }
.cw-ad-more{ font-size:11px; color:var(--text2); padding:1px 8px; }

/* Сетка часов */
.cw-scroll{ overflow-y:auto; flex:1; min-height:0; border:1px solid var(--border);
  border-top:none; border-radius:0 0 12px 12px; background:var(--card); }
.cw-grid{ display:grid; grid-template-columns:var(--cw-gut) repeat(7,minmax(0,1fr)); }
.cw-gutter{ border-right:1px solid var(--border); position:relative; }
.cw-hour-lbl{ position:absolute; right:8px; font-size:11px; color:var(--text2);
  font-variant-numeric:tabular-nums; transform:translateY(-50%); }
/* Первый ярлык часа не срезаем: ярлыки центрируются по линии часа
   (translateY(-50%)), и у самого верхнего половина уходила за край — «09:00»
   читалось наполовину (замер 21.08.2026: срезано 7 px из 13). */
.cw-gutter .cw-hour-lbl:first-child { transform: translateY(0); }

.cw-col{ position:relative; border-left:1px solid var(--border);
  background-image:
    repeating-linear-gradient(to bottom, var(--border) 0 1px, transparent 1px var(--cw-hour)); }
.cw-col:first-of-type{ border-left:none; }
.cw-col.wknd{ background-color:var(--card2); }
.cw-col.today{ background-color:var(--blue-bg); }
.cw-off{ position:absolute; left:0; right:0; background:rgba(100,116,139,.07); pointer-events:none; }

/* Событие */
.cw-ev{ position:absolute; border-radius:8px; padding:3px 8px 4px 8px; overflow:hidden;
  cursor:pointer; font-size:11px; line-height:1.3; border:1px solid transparent;
  box-shadow:0 1px 2px rgba(0,0,0,.06); transition:box-shadow .12s; }
.cw-ev:hover{ box-shadow:var(--shadow-lg); z-index:5; }
.cw-ev-t{ font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cw-ev-m{ font-variant-numeric:tabular-nums; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; opacity:.8; }
.cw-ev.done{ opacity:.55; text-decoration:line-through; }
/* Время внутри строки названия у низкой плашки: табличные цифры и чуть тише
   названия, чтобы читалось как приписка, а не как часть заголовка. */
.cw-ev-t-tm{ font-variant-numeric:tabular-nums; opacity:.75; font-weight:400; }
/* Плановый срок в неделе — тот же контур, что и в месяце (.cal-v2-ev.ev-plan).
   Курсор обычный: тянуть нечего, записи в данных нет. */
.cw-ev.cw-plan, .cw-ad.cw-plan{
  background:transparent; background-image:none;
  border:1px dashed var(--border-strong,#CBD5E1); color:var(--text2); cursor:pointer;
}
.cw-ev.cw-plan::before{ background:var(--border-strong,#CBD5E1); }
.cw-ev.now{ box-shadow:0 0 0 2px #38BDF8; }
/* Высокий приоритет — точка перед названием, как в месяце */
.cw-ev-hi{ display:inline-block; width:6px; height:6px; border-radius:50%;
  background:#DC2626; margin-right:5px; vertical-align:middle; }
/* Тона: заливка бледная, слово затемнённой ступенью (свод, п. 12). Плотного
   цвета с белым текстом здесь нет: белым по --blue контраст 3.68, по --orange
   2.15 — норму 4.5 не проходит (замер 19.08.2026). */
.cw-ev.cw-t-task  { background:var(--blue-bg);   color:#2563EB; }
.cw-ev.cw-t-report{ background:var(--orange-bg); color:#B45309; }
.cw-ev.cw-t-remind{ background:var(--purple-bg); color:#6D28D9; }
[data-theme="dark"] .cw-ev.cw-t-task  { color:#60A5FA; }
[data-theme="dark"] .cw-ev.cw-t-report{ color:var(--orange); }
[data-theme="dark"] .cw-ev.cw-t-remind{ color:#A78BFA; }

/* РУЧКИ РАЗМЕРА (ТЗ владельца 25.08.2026). Полоски по верхнему и нижнему краю
   плашки — за них тянут время начала и конца. Проявляются при наведении: на
   получасовой записи высотой 18 px две постоянные полоски закрыли бы собой всю
   запись. Зона захвата 6 px — палец мыши в 3 px не попадает, а больше отняло бы
   у клика по самой плашке. */
.cw-rz{ position:absolute; left:0; right:0; height:6px; cursor:ns-resize; z-index:3; }
.cw-rz-t{ top:0; }
.cw-rz-b{ bottom:0; }
.cw-rz::after{ content:''; position:absolute; left:50%; transform:translateX(-50%);
  width:22px; height:3px; border-radius:2px; background:currentColor;
  opacity:0; transition:opacity .12s; }
.cw-rz-t::after{ top:1px; }
.cw-rz-b::after{ bottom:1px; }
.cw-ev:hover .cw-rz::after{ opacity:.45; }
/* Пока тащат — полоски прячем: они мигали бы под курсором у каждой плашки,
   мимо которой проезжаешь. */
body.cw-drag-on .cw-rz::after{ opacity:0; }
@media (prefers-reduced-motion: reduce){ .cw-rz::after{ transition:none; } }

/* Линия «сейчас» */
.cw-now{ position:absolute; left:0; right:0; height:0; border-top:2px solid var(--red);
  z-index:6; pointer-events:none; }
.cw-now::before{ content:''; position:absolute; left:-4px; top:-4px; width:7px; height:7px;
  border-radius:50%; background:var(--red); }

.cw-empty{ font-size:13px; color:var(--text2); text-align:center; padding:16px 0 2px; flex-shrink:0; }

/* Обои: панели недели живут на том же стекле, что и остальной календарь */
html:not([data-theme="dark"]) .main-calwall .cw-head,
html:not([data-theme="dark"]) .main-calwall .cw-scroll{ background:var(--cw-glass); border-color:var(--cw-brd); }
html:not([data-theme="dark"]) .main-calwall .cw-allday{ background:var(--cw-cell2); border-color:var(--cw-brd); }
html:not([data-theme="dark"]) .main-calwall .cw-head-gut,
html:not([data-theme="dark"]) .main-calwall .cw-day,
html:not([data-theme="dark"]) .main-calwall .cw-allday-lbl,
html:not([data-theme="dark"]) .main-calwall .cw-allday-col,
html:not([data-theme="dark"]) .main-calwall .cw-gutter,
html:not([data-theme="dark"]) .main-calwall .cw-col{ border-color:var(--cw-brd); }
html:not([data-theme="dark"]) .main-calwall .cw-col{
  background-image: repeating-linear-gradient(to bottom, var(--cw-brd) 0 1px, transparent 1px var(--cw-hour)); }
html:not([data-theme="dark"]) .main-calwall .cw-col.wknd{ background-color:var(--cw-cell2); }
html:not([data-theme="dark"]) .main-calwall .cw-ad{ background:var(--cw-cell); border-color:var(--cw-brd); }
html:not([data-theme="dark"]) .main-calwall .cw-seg-b.on,
html:not([data-theme="dark"]) .main-calwall .cw-zoom{ background:var(--cw-cell); border-color:var(--cw-brd); }

/* Три коротких списка времени в карточке задачи: час · минуты ·
   продолжительность (app-tasks.js, tkTimeRow). Один список на 24 часа с шагом
   15 минут — это 97 строк, владелец назвала это «бесконечным полотном»
   (19.08.2026). Здесь самый длинный список — 24 строки. */
.tkc-time-row{ display:grid; grid-template-columns:1fr 1fr 1.4fr; gap:8px; }
.tkc-time-lbl{ font-size:11px; color:var(--text3); margin-bottom:3px; }
.tkc-time-out{ font-size:11px; color:var(--text2); margin-top:6px; font-variant-numeric:tabular-nums; }

/* Значок вида задачи (встреча / задача / напоминание) в календаре.
   Заведено 19.08.2026: три одинаковые точки разного цвета человек не
   различает, а календарь, галочку и колокольчик узнаёт не читая.
   Значок берёт цвет вида через color у обёртки — сама графика в
   currentColor, как svgPlus и svgChev (свод «Оформление», п. 9). */
.cal-v2-ev-ic, .cw-ic{ display:inline-flex; align-items:center; flex-shrink:0; }
.cal-v2-ev-ic svg, .cw-ic svg{ display:block; }
.cw-ev-t .cw-ic{ margin-right:4px; vertical-align:-2px; }
/* В блоке события значок берёт цвет слова: у блока уже своя пара
   «заливка + слово», и второй оттенок рядом читался бы как ошибка. */
.cw-ev .cw-ic{ color:currentColor; opacity:.85; }

/* Тон «задача» — серый: заливка --slate-bg, слово затемнённой ступенью
   (свод, п. 12; сам --slate на своей заливке даёт 3.4). */
.cw-ev.cw-t-meeting{ background:var(--blue-bg);   color:#2563EB; }
.cw-ev.cw-t-task   { background:var(--slate-bg);  color:#475569; }
[data-theme="dark"] .cw-ev.cw-t-meeting{ color:#60A5FA; }
[data-theme="dark"] .cw-ev.cw-t-task   { color:#CBD5E1; }

/* Границы своего рабочего дня в панели недели (ТЗ владельца 19.08.2026:
   «а вдруг я работаю по 12 часов»). Список короткий — только часы. */
.cw-hsel{
  padding:4px 8px; border-radius:8px; border:1px solid var(--border);
  background:var(--card); color:var(--text); font-size:12px; font-family:inherit;
  font-variant-numeric:tabular-nums; cursor:pointer;
}
.cw-hsel:focus{ outline:none; border-color:var(--act); }
.cw-now-btn{ width:auto; padding:0 10px; font-size:12px; font-weight:500; }

/* «Есть куда крутить»: тень у края, за которым спрятаны часы. Появляется
   и исчезает по прокрутке (cwShadeUpdate). Без неё сетка выглядела
   законченной, и казалось, что портал показывает только рабочий день. */
.cw-scroll{ position:relative; }
.cw-scroll.shade-top{ box-shadow: inset 0 8px 8px -8px rgba(15,23,42,.28); }
.cw-scroll.shade-bot{ box-shadow: inset 0 -8px 8px -8px rgba(15,23,42,.28); }
.cw-scroll.shade-top.shade-bot{
  box-shadow: inset 0 8px 8px -8px rgba(15,23,42,.28),
              inset 0 -8px 8px -8px rgba(15,23,42,.28);
}
[data-theme="dark"] .cw-scroll.shade-top{ box-shadow: inset 0 8px 8px -8px rgba(0,0,0,.6); }
[data-theme="dark"] .cw-scroll.shade-bot{ box-shadow: inset 0 -8px 8px -8px rgba(0,0,0,.6); }
[data-theme="dark"] .cw-scroll.shade-top.shade-bot{
  box-shadow: inset 0 8px 8px -8px rgba(0,0,0,.6), inset 0 -8px 8px -8px rgba(0,0,0,.6);
}
html:not([data-theme="dark"]) .main-calwall .cw-hsel{ background:var(--cw-cell); border-color:var(--cw-brd); }

/* ПЕРЕТАСКИВАНИЕ ЗАПИСЕЙ В НЕДЕЛЕ (app-calweek.js, ТЗ владельца 19.08.2026).
   Блок под курсором приподнят тенью и слегка прозрачен — видно, что он
   «взят», и не теряется из виду то, что под ним. Курсор grab/grabbing:
   единственный способ сказать «это можно тянуть» до того, как потянули. */
.cw-ev, .cw-ad{ cursor: grab; }
.cw-ev.cw-dragging{
  cursor: grabbing; z-index: 20; opacity: .9;
  box-shadow: 0 10px 20px -6px rgba(15,23,42,.35);
  transform: scale(1.01);
}
[data-theme="dark"] .cw-ev.cw-dragging{ box-shadow: 0 10px 20px -6px rgba(0,0,0,.7); }
/* Во время переноса гасим выделение текста и подсветку ховера: иначе строки
   мигают под курсором, пока тянешь. */
body.cw-drag-on{ user-select: none; cursor: grabbing; }
body.cw-drag-on .cw-ev:hover{ box-shadow: none; }
/* Подпись «куда встанет»: день и время под курсором. Без неё целиться
   приходится вслепую и проверять результат после отпускания. */
.cw-hint{
  position: fixed; display: none; z-index: 1200; transform: translate(-50%, -100%);
  background: var(--text); color: var(--card); border-radius: 8px;
  padding: 4px 8px; font-size: 11px; font-weight: 500; white-space: nowrap;
  font-variant-numeric: tabular-nums; pointer-events: none;
  box-shadow: var(--shadow-md);
}
@media (prefers-reduced-motion: reduce){ .cw-ev.cw-dragging{ transform: none; } }

/* ═══════════════════════════════════════════════════════════════════════
   ОФОРМЛЕНИЕ ПЛАШЕК КАЛЕНДАРЯ (app-calstyle.js)
   ═══════════════════════════════════════════════════════════════════════
   Заказ владельца 19.08.2026: «плашки выглядят очень плоско, не хватает
   текстуры — и чтобы я могла менять по настроению». Вариантов два, оба
   перенесены из макета maket-plashki.html дословно; выбор — личный, живёт
   атрибутом data-calplash на <html>.

   Селекторы всегда парой: html[data-calplash="…"] — сам календарь,
   .cst-pic[data-calplash-demo="…"] — образец в окне выбора. Иначе плитка «Карточка»
   в окне красилась бы текущим оформлением и обе плитки выглядели одинаково.

   ПРО ЦВЕТА. Новых нет: заливка — примесь существующего токена к карточке по
   правилу «доля от 8 % сверху до 12 % снизу» (свод, п. 12, «производные»).
   Потолок 12 % не вкусовой: слово встречи #2563EB на такой заливке даёт
   контраст 4.51, на 13 % — уже 4.45, ниже нормы 4.5 (замер 19.08.2026).
   Слово, полоса и значок берут ступени из таблицы свода.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Общее для обоих вариантов: место под полосу и сама полоса слева ─── */
html[data-calplash] .cw-ev,
[data-calplash-demo] .cw-ev{
  padding:4px 8px 4px 12px;
  border:1px solid transparent;
}
html[data-calplash] .cw-ev::before,
[data-calplash-demo] .cw-ev::before{
  content:''; position:absolute; left:0; top:0; bottom:0; width:3px;
}
html[data-calplash] .cw-ev-m,
[data-calplash-demo] .cw-ev-m{ margin-top:1px; }

/* ── Вариант «Фактура»: цвет плюс поверхность ─────────────────────────
   У каждого вида своя поверхность и свой рисунок полосы, поэтому вид
   различим и без цвета — это важно тем, кто путает синий с фиолетовым
   (свод, п. 9: различать должен не только оттенок). */
html[data-calplash="tex"] .cw-ev.cw-t-meeting,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-meeting{
  background:linear-gradient(180deg,rgba(59,130,246,.08),rgba(59,130,246,.12));
  border-color:rgba(59,130,246,.24); color:#2563EB;
}
html[data-calplash="tex"] .cw-ev.cw-t-meeting::before,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-meeting::before{ background:var(--blue); }

/* Задача — бирюза в тетрадную клетку (макет makety-zadacha, выбор владельца
   21.08.2026). БЫЛО: серая заливка, косая штриховка 135° и пунктирная полоса
   слева. Владелец: «выглядит как будто задача выполнена» — и это не вкус, а
   три сигнала «погашено» разом: диагональю в этом же календаре помечено «вне
   нормы 28», пунктир читается как «неполное», а выполненное гасится
   прозрачностью — выцветший серый в штриховке от него не отличить.
   СТАЛО: тон --cyan (тот же, что у статуса «В работе» в таблице учёта, новых
   цветов нет), сетка из прямых линий вместо диагоналей, полоса слева
   сплошная. Слово #155E75 даёт на этой заливке контраст 6.49 (замер
   21.08.2026), с запасом к норме 4.5. */
html[data-calplash="tex"] .cw-ev.cw-t-task,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-task{
  background-color:rgba(6,182,212,.12);
  background-image:
    repeating-linear-gradient(to right, rgba(6,182,212,.14) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(to bottom, rgba(6,182,212,.14) 0 1px, transparent 1px 6px);
  border-color:rgba(6,182,212,.28); color:#155E75;
}
html[data-calplash="tex"] .cw-ev.cw-t-task::before,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-task::before{ background:var(--cyan); }

html[data-calplash="tex"] .cw-ev.cw-t-remind,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-remind{
  background-color:rgba(139,92,246,.10);
  background-image:radial-gradient(rgba(139,92,246,.16) 1px, transparent 1.2px);
  background-size:7px 7px;
  border-color:rgba(139,92,246,.24); color:#6D28D9;
}
html[data-calplash="tex"] .cw-ev.cw-t-remind::before,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-remind::before{
  background:linear-gradient(180deg, var(--purple) 0 8px, rgba(139,92,246,.35) 8px);
}

html[data-calplash="tex"] .cw-ev.cw-t-report,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-report{
  background:linear-gradient(180deg,rgba(245,158,11,.08),rgba(245,158,11,.12));
  border-color:rgba(245,158,11,.24); color:#B45309;
}
html[data-calplash="tex"] .cw-ev.cw-t-report::before,
.cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-report::before{ background:var(--orange); }

html[data-theme="dark"][data-calplash="tex"] .cw-ev.cw-t-meeting,
[data-theme="dark"] .cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-meeting{ color:#60A5FA; }
html[data-theme="dark"][data-calplash="tex"] .cw-ev.cw-t-task,
[data-theme="dark"] .cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-task{ color:#A5F3FC; }
html[data-theme="dark"][data-calplash="tex"] .cw-ev.cw-t-remind,
[data-theme="dark"] .cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-remind{ color:#A78BFA; }
html[data-theme="dark"][data-calplash="tex"] .cw-ev.cw-t-report,
[data-theme="dark"] .cst-pic[data-calplash-demo="tex"] .cw-ev.cw-t-report{ color:var(--orange); }

/* ── Вариант «Карточка»: цвет только в полосе и значке ────────────────
   Название берёт полный --text (17.85 и 15.35), поэтому такой ряд читается
   поверх любых обоев и не рябит на плотной неделе. Под белой карточкой
   оставлена примесь тона 5 → 9 %: без неё плашка на белой колонке держалась
   бы одной тенью (проверено на стенде 19.08.2026). */
html[data-calplash="card"] .cw-ev,
.cst-pic[data-calplash-demo="card"] .cw-ev{
  padding-left:12px; background:var(--card); border-color:var(--border); color:var(--text);
  box-shadow:0 1px 2px rgba(0,0,0,.06), 0 4px 10px -6px rgba(0,0,0,.14);
}
html[data-calplash="card"] .cw-ev-m,
.cst-pic[data-calplash-demo="card"] .cw-ev-m{ color:var(--text2); opacity:1; }

html[data-calplash="card"] .cw-ev.cw-t-meeting,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-meeting{
  background:linear-gradient(180deg,rgba(59,130,246,.05),rgba(59,130,246,.09)),var(--card); }
html[data-calplash="card"] .cw-ev.cw-t-task,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-task{
  background:linear-gradient(180deg,rgba(100,116,139,.05),rgba(100,116,139,.09)),var(--card); }
html[data-calplash="card"] .cw-ev.cw-t-remind,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-remind{
  background:linear-gradient(180deg,rgba(139,92,246,.05),rgba(139,92,246,.09)),var(--card); }
html[data-calplash="card"] .cw-ev.cw-t-report,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-report{
  background:linear-gradient(180deg,rgba(245,158,11,.05),rgba(245,158,11,.09)),var(--card); }

/* Цвет слова у образца задаётся на уровне вида: правило «сам календарь»
   (html[data-calplash="tex"] .cw-ev.cw-t-meeting) сильнее общего правила
   образца, и в плитке «Карточка» название оставалось синим (стенд 19.08.2026). */
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-meeting,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-task,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-remind,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-report{ color:var(--text); }

html[data-calplash="card"] .cw-ev.cw-t-meeting::before,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-meeting::before{ background:var(--blue); }
html[data-calplash="card"] .cw-ev.cw-t-task::before,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-task::before{ background:var(--slate); }
html[data-calplash="card"] .cw-ev.cw-t-remind::before,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-remind::before{ background:var(--purple); }
html[data-calplash="card"] .cw-ev.cw-t-report::before,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-report::before{ background:var(--orange); }

/* Значок здесь единственный носитель цвета в тексте — он не текст, норма 4.5
   к нему не применяется (свод, п. 12), поэтому берёт полный тон. */
html[data-calplash="card"] .cw-ev.cw-t-meeting .cw-ic,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-meeting .cw-ic{ color:#2563EB; opacity:1; }
html[data-calplash="card"] .cw-ev.cw-t-task .cw-ic,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-task .cw-ic{ color:#475569; opacity:1; }
html[data-calplash="card"] .cw-ev.cw-t-remind .cw-ic,
.cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-remind .cw-ic{ color:#6D28D9; opacity:1; }
html[data-theme="dark"][data-calplash="card"] .cw-ev.cw-t-meeting .cw-ic,
[data-theme="dark"] .cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-meeting .cw-ic{ color:#60A5FA; }
html[data-theme="dark"][data-calplash="card"] .cw-ev.cw-t-task .cw-ic,
[data-theme="dark"] .cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-task .cw-ic{ color:#CBD5E1; }
html[data-theme="dark"][data-calplash="card"] .cw-ev.cw-t-remind .cw-ic,
[data-theme="dark"] .cst-pic[data-calplash-demo="card"] .cw-ev.cw-t-remind .cw-ic{ color:#A78BFA; }

/* ── То же в сетке месяца, только тише ────────────────────────────────
   Чип месяца — строка в 11 px, полноценная заливка с фактурой там была бы
   шумом: остаётся полоса слева и лёгкая примесь тона. Просроченное
   (.ev-late) не трогаем ни в одном варианте — красная заливка сильнее вида,
   это единственный сигнал «горит» в сетке. */
html[data-calplash] .cal-v2-ev[class*="cv-k-"]:not(.ev-late){
  position:relative; padding-left:8px;
}
html[data-calplash] .cal-v2-ev[class*="cv-k-"]:not(.ev-late)::before{
  content:''; position:absolute; left:0; top:2px; bottom:2px; width:3px; border-radius:2px;
}
html[data-calplash] .cal-v2-ev.cv-k-meeting:not(.ev-late)::before{ background:var(--blue); }
/* Полоса задачи в месяце своя у каждого оформления: в «Фактуре» задача
   бирюзовая, в «Карточке» осталась серой — общая полоса спорила бы с заливкой. */
html[data-calplash="tex"] .cal-v2-ev.cv-k-task:not(.ev-late)::before{ background:var(--cyan); }
html[data-calplash="card"] .cal-v2-ev.cv-k-task:not(.ev-late)::before{ background:var(--slate); }
html[data-calplash] .cal-v2-ev.cv-k-remind:not(.ev-late)::before{ background:var(--purple); }
html[data-calplash] .cal-v2-ev.cv-k-report:not(.ev-late)::before{ background:var(--orange); }

html[data-calplash="tex"] .cal-v2-ev.cv-k-meeting:not(.ev-late){ background:rgba(59,130,246,.10); }
html[data-calplash="tex"] .cal-v2-ev.cv-k-task:not(.ev-late){
  background-color:rgba(6,182,212,.10); }
html[data-calplash="tex"] .cal-v2-ev.cv-k-remind:not(.ev-late){
  background-color:rgba(139,92,246,.10);
  background-image:radial-gradient(rgba(139,92,246,.16) 1px, transparent 1.2px);
  background-size:7px 7px; }
html[data-calplash="tex"] .cal-v2-ev.cv-k-report:not(.ev-late){ background:rgba(245,158,11,.10); }

html[data-calplash="card"] .cal-v2-ev.cv-k-meeting:not(.ev-late){ background:rgba(59,130,246,.05); }
html[data-calplash="card"] .cal-v2-ev.cv-k-task:not(.ev-late){ background:rgba(100,116,139,.05); }
html[data-calplash="card"] .cal-v2-ev.cv-k-remind:not(.ev-late){ background:rgba(139,92,246,.05); }
html[data-calplash="card"] .cal-v2-ev.cv-k-report:not(.ev-late){ background:rgba(245,158,11,.05); }

/* ── Окно «Оформление календаря» ──────────────────────────────────────── */
.cst-tabs{ display:flex; gap:8px; margin-bottom:14px; }
.cst-tab{
  font:inherit; font-size:12px; padding:8px 12px; border-radius:99px; cursor:pointer;
  border:1px solid var(--border); background:var(--card); color:var(--text2);
}
.cst-tab.on{ border-color:var(--act); color:var(--text); background:var(--act-bg); }
/* Окно оформления: своя ширина, а не общий .mc-wide (960 px). На нём две
   плитки занимали половину окна, а вторая половина оставалась пустой —
   владелец 19.08.2026: «окно выглядит не очень». Ширина считана от
   содержимого: две плитки по 1fr и отступы = 600 px (замер на стенде). */
.mc.mc-calst{ max-width:600px; width:94%; }
/* Плитки строго в две колонки одной ширины: сравнивают их бок о бок, а
   flex-wrap делал их разной длины при разной длине подписи. */
.cst-gal{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.cst-tile{
  font:inherit; text-align:left; cursor:pointer; padding:0; overflow:hidden;
  width:auto; border-radius:12px; border:1px solid var(--border); background:var(--card);
  transition:transform .12s, box-shadow .12s, border-color .12s;
}
.cst-tile:hover{ transform:translateY(-2px); box-shadow:var(--shadow-lg); }
.cst-tile.on{ border-color:var(--act); box-shadow:0 0 0 2px rgba(56,189,248,.35); }
.cst-pic{ display:block; padding:10px 12px 4px; background:var(--card2); }
.cst-cap{ display:block; padding:8px 12px 8px; }
.cst-nm{ display:block; font-size:13px; font-weight:500; color:var(--text); }
.cst-hint{ display:block; font-size:11px; color:var(--text2); margin-top:1px; }
/* Образец — та же плашка, что в сетке, но в потоке: в календаре она стоит
   по координатам времени, здесь координат нет. */
.cst-demo{ position:relative; display:block; left:auto; right:auto; top:auto;
  height:auto; margin-bottom:6px; }
.cst-demo .cw-ev-t, .cst-demo .cw-ev-m{ display:block; }

/* ═══════════════════════════════════════════════════════════════════════
   КОТИКИ НА ГЛАВНОЙ (app-cats.js) — перенос дизайн-передачи владельца
   design_handoff_hr_portal_cats, 19.08.2026.

   Котик собран из обычных div-ов: border-radius, градиенты, clip-path.
   Ни картинок, ни SVG — слой невесомый и красится одними цветами меха.
   Цвета переведены из OKLCH в hex (в портале цветовая модель не меняется),
   шрифт один — Inter: Quicksand из прототипа тянулся бы с Google Fonts,
   а портал работает в закрытом контуре.

   Движение — только transform и opacity, как требует правило анимации
   проекта; при системном «меньше движения» слой не включается вовсе
   (проверка в catsEnabled/catsApply, здесь дублируется @media).
   ═══════════════════════════════════════════════════════════════════════ */
.cats-layer{
  position: fixed; inset: 0; z-index: 50; pointer-events: none; overflow: hidden;
}
/* Котик ловит мышь сам, слой под ним — нет: иначе он перехватывал бы клики
   по всей главной. */
/* Точка отсчёта — левый верхний угол: движок ставит координаты в пикселях
   экрана, и масштаб не должен уводить кота от заданной точки. */
.cat{ position: absolute; left: 0; top: 0; transform-origin: 0 0;
  pointer-events: auto; cursor: grab; user-select: none; }
.cat.cat-held{ cursor: grabbing; }
.cat-pose{ position: relative; width: 84px; height: 62px; transform-origin: center 85%; }

.cat-shadow{
  position: absolute; left: 14px; top: 52px; width: 52px; height: 8px;
  border-radius: 50%; background: rgba(80,69,61,.16); filter: blur(3px);
}
/* Хвост: восемь вложенных сегментов, каждый доворачивается относительно
   предыдущего — так он гнётся дугой, а не ломается в одной точке. */
/* Хвост. Два слоя на звено: сам сегмент держит базовый доворот, обёртка
   внутри — покачивание. На одном элементе они не уживаются: анимация
   перезаписывает transform, изгиб пропадает и хвост торчит палкой. */
/* Основание хвоста сидит ВЫШЕ низа тела и заходит под него: тело рисуется
   после хвоста и перекрывает стык, поэтому хвост читается продолжением
   спины, а не приставленной палкой (ТЗ владельца 19.08.2026 — «а то хвост
   выглядит инородным»). База 34 вместо 40 и сдвиг вправо на 3 px. */
.cat-tail{
  position: absolute; left: 23px; top: 34px; width: 11px; height: 12px;
  border-radius: 5.5px; transform: rotate(-38deg); transform-origin: center bottom;
  filter: blur(.35px);
}
.cat-tail-anim{ position: absolute; inset: 0; transform-origin: center bottom; }
.cat-tail-idle{ animation: catTailIdle 7s ease-in-out infinite; }
.cat-tail-wave{ animation: catTailWave 4.6s ease-in-out infinite; }
.cat-tail-seg{ position: absolute; left: .4px; top: -8px; height: 11px; transform-origin: center bottom; }
.cat-tail-fur{ position: absolute; inset: 0; }
.cat-move.cat-fast .cat-tail-wave{ animation-duration: .7s; }

.cat-body{
  position: absolute; left: 16px; top: 20px; width: 46px; height: 32px;
  border-radius: 50% 50% 46% 46%;
}
.cat-stripe{ position: absolute; border-radius: 50%; }
.cat-stripe-1{ left: 6px; top: 10px; width: 14px; height: 5px; background: rgba(54,43,37,.18); }
.cat-stripe-2{ left: 8px; top: 14px; width: 16px; height: 5px; background: rgba(54,43,37,.14); }

/* Лап две, и это решение владельца 19.08.2026: задняя пара пробовалась и была
   отвергнута — на 84 px позы четыре лапы читаются как каша, а котик из
   прототипа узнаваем именно таким. Не возвращать. */
/* Лапа. Геометрия из передачи дизайна, цвет приходит инлайном от самого
   котика — он зависит от его шерсти (ТЗ владельца 19.08.2026). Ни свечения,
   ни размытия: пушистость пробовали и отвергли, она остаётся только у хвоста. */
.cat-paw{
  position: absolute; top: 44px; width: 15px; height: 9px; border-radius: 50%;
}
.cat-paw-1{ left: 34px; }
.cat-paw-2{ left: 50px; }
/* Задние — вытянутая СТОПА, а не овал: у кошки сбоку задняя лапа лежит на
   земле длинной плюсной, и круглая форма читалась «как яйца» (ТЗ владельца
   19.08.2026). Отсюда 13×5 и разное скругление концов: спереди пальцы —
   край круглее, сзади пятка — почти прямой. Цвет furDark приходит инлайном:
   задние в тени тела и дальше от зрителя. */
/* Задняя — та же круглая форма, что у передних, только меньше: 12×7 против
   15×9. Вытянутая «стопа» пробовалась и не подошла (19.08.2026). */
.cat-paw-3{ left: 19px; top: 46px; width: 12px; height: 7px; }
/* Ходьба по диагонали, как у настоящей кошки: задняя работает в противофазе
   к ближней передней. Одна фаза на всех выглядит как прыжки кролика. */
.cat-move .cat-paw-1{ animation: catPaw .42s ease-in-out infinite; }
.cat-move .cat-paw-2, .cat-move .cat-paw-3{ animation: catPawAlt .42s ease-in-out infinite; }
.cat-move.cat-fast .cat-paw{ animation-duration: .24s; }

.cat-head{ position: absolute; left: 36px; top: 2px; width: 36px; height: 32px; transform-origin: center bottom; }
.cat-move .cat-head{ animation: catHeadBob .42s ease-in-out infinite; }
.cat-move.cat-fast .cat-head{ animation-duration: .24s; }
.cat-ear{ position: absolute; top: 0; width: 13px; height: 13px; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.cat-ear-1{ left: 1px;  animation: catEar 5s ease-in-out infinite; }
.cat-ear-2{ left: 21px; animation: catEar 5s ease-in-out .4s infinite; }
.cat-ear-in{ position: absolute; top: 5px; width: 7px; height: 7px; background: #E2AFAE;
  clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.cat-ear-in-1{ left: 4px; }
.cat-ear-in-2{ left: 24px; }
.cat-face{ position: absolute; left: 1px; top: 5px; width: 34px; height: 28px; border-radius: 50%; }
.cat-eye{ position: absolute; top: 15px; width: 6px; height: 7px; border-radius: 50%;
  background: #1A1513; animation: catBlink 5.5s infinite; }
.cat-eye-1{ left: 11px; }
.cat-eye-2{ left: 21px; }
.cat-shine{ position: absolute; top: 16px; width: 2px; height: 2px; border-radius: 50%; background: #fff; }
.cat-shine-1{ left: 12.5px; }
.cat-shine-2{ left: 22.5px; }
.cat-nose{ position: absolute; left: 16px; top: 23px; width: 6px; height: 4px;
  border-radius: 50% 50% 60% 60%; background: #DC8B8B; }
.cat-whisker{ position: absolute; width: 15px; height: 1.5px; background: rgba(68,55,51,.6); }
.cat-w1{ left: -8px; top: 20px; transform: rotate(-10deg); }
.cat-w2{ left: -8px; top: 25px; transform: rotate(6deg); }
.cat-w3{ left: 29px; top: 20px; transform: rotate(10deg); }
.cat-w4{ left: 29px; top: 25px; transform: rotate(-6deg); }

/* Спящий: тело оседает и дышит, глаза закрыты, рядом «z z». Отдельной
   разметки не заводим — те же части, другая поза. */
.cat-sleep .cat-pose{ transform-origin: center bottom; }
.cat-sleep .cat-body{ animation: catBreathe 3.4s ease-in-out infinite; }
.cat-sleep .cat-head{ transform: translate(-14px, 18px) scale(.92); }
.cat-sleep .cat-eye{ height: 2px; border-radius: 0 0 4px 4px; background: #26201E; animation: none; }
.cat-sleep .cat-shine{ display: none; }
.cat-sleep .cat-paw{ opacity: .6; }
.cat-zzz{
  position: absolute; left: 52px; top: 2px; font-size: 12px; font-weight: 600;
  color: #6E605B; opacity: 0; pointer-events: none;
}
.cat-sleep .cat-zzz{ animation: catZzz 2.6s ease-out infinite; }

/* Реплики котика: «мя-я-у!», «а-а-а!», «ой!» */
.cat-bubble{
  position: absolute; left: 44px; top: -18px; padding: 3px 8px;
  border-radius: 12px 12px 12px 2px; background: #FDFBF9; border: 1px solid #E1DDD8;
  box-shadow: 0 2px 6px rgba(80,69,61,.12); font-size: 11px; font-weight: 600;
  color: #443733; white-space: nowrap; pointer-events: none; display: none;
}
.cat-bubble.show{ display: block; animation: catBubble .25s ease-out both; }

/* Поглаживание — кружки всплывают и гаснут */
.cat-heart{
  position: absolute; width: 10px; height: 10px; border-radius: 50%;
  background: rgba(242,167,161,.8); pointer-events: none;
  animation: catHeart 1.1s ease-out forwards;
}

/* В руках болтается, лапами перебирает; при приземлении сплющивается */
.cat-held .cat-pose{ animation: catDangle .5s ease-in-out infinite; }
.cat-held .cat-paw-1{ animation: catFlail .18s ease-in-out infinite; }
.cat-held .cat-paw-2{ animation: catFlail .18s ease-in-out infinite reverse; }
.cat-squash .cat-pose{ animation: catSquash .42s cubic-bezier(.2,1.4,.4,1) both; }

@keyframes catTailWave{ 0%,100%{ transform: rotate(-6deg); } 50%{ transform: rotate(6deg); } }
@keyframes catTailIdle{ 0%,80%,100%{ transform: rotate(0); } 86%{ transform: rotate(-4deg); }
  92%{ transform: rotate(3deg); } }
@keyframes catPaw{    0%,100%{ transform: translateY(0); } 50%{ transform: translateY(-3px); } }
@keyframes catPawAlt{ 0%,100%{ transform: translateY(-3px); } 50%{ transform: translateY(0); } }
@keyframes catHeadBob{ 0%,100%{ transform: translateY(0) rotate(-1deg); }
  50%{ transform: translateY(-1.5px) rotate(1deg); } }
@keyframes catEar{ 0%,89%,100%{ transform: rotate(0); } 92%{ transform: rotate(-12deg); } }
@keyframes catBlink{ 0%,95%,100%{ transform: scaleY(1); } 97%{ transform: scaleY(.1); } }
@keyframes catBreathe{ 0%,100%{ transform: scale(1,1); } 50%{ transform: scale(1.03,1.06); } }
@keyframes catZzz{ 0%{ opacity: 0; transform: translate(0,0) scale(.8); }
  20%{ opacity: .9; } 100%{ opacity: 0; transform: translate(14px,-26px) scale(1.1); } }
@keyframes catBubble{ 0%{ opacity: 0; transform: translateY(4px) scale(.7); }
  100%{ opacity: 1; transform: translateY(0) scale(1); } }
@keyframes catHeart{ 0%{ opacity: .9; transform: translateY(0) scale(.6); }
  100%{ opacity: 0; transform: translateY(-46px) scale(1); } }
@keyframes catDangle{ 0%,100%{ transform: rotate(-7deg); } 50%{ transform: rotate(7deg); } }
@keyframes catFlail{ 0%,100%{ transform: translateY(-4px) rotate(-14deg); }
  50%{ transform: translateY(4px) rotate(14deg); } }
@keyframes catSquash{ 0%{ transform: scale(1.25,.72); } 60%{ transform: scale(.94,1.06); }
  100%{ transform: scale(1,1); } }

/* Системная просьба «меньше движения» — слой не запускается (см. catsApply);
   это правило страхует на случай, если он всё же оказался на экране. */
@media (prefers-reduced-motion: reduce){
  .cats-layer{ display: none; }
}

/* ЧИСЛА — ТАБЛИЧНЫМИ ЦИФРАМИ (свод, п. 10). Правило стоит В КОНЦЕ ФАЙЛА
   НАРОЧНО: у .sgm-i задан font:inherit, и краткая запись font сбрасывает
   font-variant-numeric в normal. Объявленное выше правило она перебивала —
   поймано на стенде 27.08.2026. Иначе колонки «пляшут»: у единицы
   ширина меньше остальных цифр, и по-разному на macOS и Windows. Замер
   27.08.2026: из 763 чисел на экранах портала 166 шли пропорциональными —
   подписи плашек диаграммы отпусков, счётчики отбора и структуры, числа в
   выводах аналитики. Перечислены классы, а не «всё подряд»: правило
   касается чисел, а не текста. */
.vac-bar-txt, .tsel-n, .oti-cnt, .sgm-i, .sgm-i .cnt, .tbs-i .cnt,
.anx-ins .t b, .anx-note b, .anx-histx span {
  font-variant-numeric: tabular-nums;
}

/* ═══ ЯЧЕЙКА «ПРИКАЗ (1С)»: НОМЕР ПОД НАВЕДЕНИЕМ ══════════════════════════════
   ТЗ владельца 28.08.2026, макет _maket-prikaz.html (вариант «Б»). В ячейке
   видны только документы и ссылки — как раньше; нет ничего — прочерк. Номер и
   дата приказа приходят окошком при наведении на ячейку и по фокусу с
   клавиатуры (иначе до них не добраться без мыши).

   ПОЧЕМУ УРОВЕНЬ ПОДНИМАЕТ ЯЧЕЙКА, А НЕ ОКОШКО: следующие строки таблицы идут
   в разметке позже и при равном уровне рисуются ПОВЕРХ окошка — сквозь него
   просвечивал чужой текст (поймано на стенде 28.08.2026). */
.ord-cell{ position:relative; z-index:1; }
.ord-cell:hover, .ord-cell:focus-within{ z-index:70; }
/* ПЛАШКИ ДОКУМЕНТОВ — В ОДНУ СТРОКУ (макет 04.09.2026). Было flex-wrap:wrap:
   два документа не помещались в ширину колонки (113 px, внутри 89), второй
   уезжал на новую строку, ячейка вырастала с 34 до 55 px и тянула за собой всю
   строку таблицы — 70 вместо 49. Отсюда и брались пять разных высот. Теперь
   перенос запрещён, а подпись при нехватке места обрезается многоточием;
   полное название документа остаётся в подсказке. */
/* line-height задан числом: без него ПУСТАЯ ячейка (прочерк) выходила на 2 px
   выше заполненной — 36 против 34, и строка без документов оказывалась самой
   высокой в таблице. Мелочь, но именно из таких мелочей и складывались пять
   высот (замер 04.09.2026). */
.ord-vis{ display:flex; gap:8px; flex-wrap:nowrap; align-items:center; padding:10px 12px;
          min-height:20px; overflow:hidden; line-height:14px; }
.ord-no{ color:var(--text3); }
/* Точка = «приказ есть, документов нет». Без неё такая строка выглядела бы
   ровно как строка вовсе без приказа — обе с прочерком. */
.ord-dot{ width:5px; height:5px; border-radius:99px; background:var(--text3); display:inline-block; }

.ord-pop{ position:absolute; left:12px; top:calc(100% - 6px); z-index:80; display:block;
          min-width:196px; padding:8px 12px; border-radius:8px;
          background:var(--card); border:1px solid var(--border);
          box-shadow:0 8px 24px rgba(15,23,42,.14); white-space:nowrap;
          opacity:0; visibility:hidden; transition:opacity .12s linear; }
.ord-cell:hover .ord-pop, .ord-cell:focus-within .ord-pop{ opacity:1; visibility:visible; }
/* Пока правят номер, окошко держится открытым, даже если мышь ушла: иначе оно
   прячется вместе с полем ввода, и набранное уходит в никуда (поймано на
   стенде 28.08.2026 — поле было, фокус в него не вставал). */
.ord-cell.ord-edit-on .ord-pop{ opacity:1; visibility:visible; }
/* Внизу экрана окошко открывается ВВЕРХ, иначе его срежет край прокрутки.
   Класс ставит _tblOrderPopSide (app-table.js) по замеру места: в разметке
   строки идут окном виртуализации, поэтому «последние в списке» по nth-child
   определить нельзя — там всегда лежат последние строки ОКНА, а не таблицы. */
.ord-cell.ord-up .ord-pop{ top:auto; bottom:calc(100% - 6px); }
.ord-num{ display:block; font-size:13px; font-weight:600; color:var(--text);
          font-variant-numeric:tabular-nums; }
.ord-num-no{ font-weight:500; color:var(--text2); }
.ord-meta{ display:block; font-size:11px; color:var(--text2); margin-top:3px; }
.ord-edit{ display:block; margin-top:8px; padding:5px 10px; font-size:12px; font-family:inherit;
           border:1px solid var(--border); border-radius:8px; background:var(--card2);
           color:var(--text2); cursor:pointer; }
.ord-edit:hover{ border-color:var(--act); color:var(--act); }
.ord-inp{ width:100%; min-width:150px; padding:4px 8px; font-size:12px; font-family:inherit;
          border:1px solid var(--blue); border-radius:8px; background:var(--card); color:var(--text); }

/* ═══ КОНСТРУКТОР ВИДЖЕТОВ ГЛАВНОЙ (app-hwconstruct.js, 29.08.2026) ═════════
   Окно вместо двух панелей, которые раздвигали саму главную: «Настройка
   главной» под шапкой (445 px) и «Виджеты аналитики» на отметке 2143 px.
   Три части, как у всех окон портала: шапка 16×20, тело на остаток высоты,
   подвал 11×20 с полосой; отступы задают части, у .mc-wide padding:0.
   Высота окна задана явно: сцена ужата через transform, своей высоты для окна
   у неё нет, и окно, растущее от содержимого, схлопнулось бы (замер на стенде
   при разработке макета). */
#mc.hwk-win{ height:92vh; overflow:hidden; }
.hwk-head{ padding:16px 24px 0; border-bottom:1px solid var(--border); background:var(--card); }
.hwk-h1{ display:flex; align-items:baseline; gap:12px; }
.hwk-t{ font-size:15px; font-weight:600; color:var(--text); }
.hwk-s{ font-size:12px; color:var(--text2); }
.hwk-x{ margin-left:auto; width:28px; height:28px; border:0; background:transparent; border-radius:8px;
        color:var(--text2); cursor:pointer; font-family:inherit; display:inline-flex;
        align-items:center; justify-content:center; align-self:flex-start; }
.hwk-x:hover{ background:var(--card2); color:var(--text); }
.hwk-h2{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:12px 0; }
.hwk-h2-r{ margin-left:auto; display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.hwk-hint{ font-size:12px; color:var(--text2); }

/* Сегмент профилей — форма портала (та же, что .hrm-wt в окне кадровых
   движений): переключаем показ одного и того же, а не уходим в другой раздел.
   Профилей может стать больше, чем влезает, — сегмент листается вбок. */
.hwk-seg{ display:flex; gap:2px; padding:2px; background:var(--card2); border-radius:8px;
          max-width:520px; overflow-x:auto; scrollbar-width:thin; }
.hwk-seg-i{ flex:0 0 auto; max-width:190px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
            display:inline-flex; align-items:center; gap:8px; font-family:inherit; font-size:12px;
            font-weight:500; padding:8px 12px; border:0; border-radius:8px; background:transparent;
            color:var(--text2); cursor:pointer; }
.hwk-seg-i.on{ background:var(--card); color:var(--text); box-shadow:0 1px 2px rgba(15,23,42,.10); }
[data-theme="dark"] .hwk-seg-i.on{ box-shadow:0 1px 2px rgba(0,0,0,.32); }
.hwk-seg-i b{ font-size:11px; font-weight:500; color:var(--text2); font-variant-numeric:tabular-nums; }
.hwk-seg-i.on b{ color:var(--text); }
.hwk-prof-add{ width:28px; height:28px; border:1px solid var(--border); border-radius:8px;
               background:var(--card); color:var(--text2); cursor:pointer; font-family:inherit;
               display:inline-flex; align-items:center; justify-content:center; }
.hwk-prof-add:hover{ border-color:var(--act); color:var(--act); }

/* ── Тело: список слева, предпросмотр справа ─────────────────────────────── */
.hwk-body{ flex:1; min-height:0; display:flex; }
.hwk-side{ width:300px; flex:0 0 300px; border-right:1px solid var(--border);
           padding:16px 16px 24px; overflow-y:auto; background:var(--card); }
.hwk-side.over{ background:var(--card2); }
@media (max-width:1120px){ .hwk-side{ width:240px; flex:0 0 240px; } }
.hwk-find{ height:34px; }
.hwk-grp{ font-size:12px; font-weight:500; color:var(--text2); margin:16px 0 8px;
          display:flex; align-items:center; gap:8px; }
.hwk-grp .n{ font-size:11px; color:var(--text3); font-variant-numeric:tabular-nums; }
.hwk-cat{ display:flex; align-items:flex-start; gap:8px; border:1px solid var(--border);
          border-radius:8px; background:var(--card); padding:8px 12px; margin-bottom:7px;
          cursor:grab; user-select:none; }
.hwk-cat:hover{ border-color:var(--text3); background:var(--card2); }
.hwk-cat.dragging{ opacity:.4; }
.hwk-cat-txt{ min-width:0; flex:1; }
.hwk-cat-n{ font-size:13px; font-weight:500; color:var(--text); }
.hwk-cat-d{ font-size:11px; color:var(--text2); margin-top:2px; }
.hwk-hnd{ color:var(--text3); flex:0 0 auto; margin-top:1px; display:inline-flex; }
.hwk-tag{ font-size:11px; color:var(--text2); border:1px solid var(--border); border-radius:99px;
          padding:0 7px; white-space:nowrap; display:inline-block; }
.hwk-add{ width:24px; height:24px; flex:0 0 auto; border:1px solid var(--border); border-radius:8px;
          background:var(--card); color:var(--text2); cursor:pointer; font-family:inherit;
          display:inline-flex; align-items:center; justify-content:center;
          opacity:0; transition:opacity .12s ease; }
.hwk-cat:hover .hwk-add, .hwk-cat:focus-within .hwk-add{ opacity:1; }
.hwk-add:hover{ border-color:var(--act); color:var(--act); background:var(--act-bg); }
.hwk-empty{ font-size:12px; color:var(--text3); padding:12px 0; }
@media (prefers-reduced-motion: reduce){ .hwk-add{ transition:none; } }

/* Правка профиля — в той же панели, а не вторым окном поверх первого:
   окно в портале одно (#mo), вкладывать их друг в друга нельзя. */
.hwk-props-h{ display:flex; align-items:center; gap:8px; margin-bottom:4px; }
.hwk-back{ border:0; background:none; padding:0; color:var(--blue2); font-family:inherit;
           font-size:12px; font-weight:500; cursor:pointer; }
[data-theme="dark"] .hwk-back{ color:#60A5FA; }
.hwk-props-n{ font-size:13px; font-weight:600; margin:8px 0 2px; color:var(--text); }
.hwk-props-d{ font-size:11px; color:var(--text2); margin-bottom:12px; }
.hwk-lbl{ display:block; font-size:12px; color:var(--text2); margin:10px 0 5px; }
.hwk-props-foot{ border-top:1px solid var(--border); margin-top:14px; padding-top:12px;
                 display:flex; flex-direction:column; gap:8px; }

/* ── Сцена: главная в уменьшенном виде ───────────────────────────────────── */
.hwk-stage{ flex:1; min-width:0; display:flex; flex-direction:column; background:var(--bg); }
.hwk-stage-bar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:8px 16px;
                background:var(--card); border-bottom:1px solid var(--border);
                font-size:12px; color:var(--text2); }
.hwk-stage-r{ margin-left:auto; }
.hwk-canvas{ flex:1; overflow:auto; padding:16px; }
.hwk-scale{ transform-origin:top left; position:relative; }
.hwk-page-head{ display:flex; align-items:center; gap:12px; margin-bottom:16px; opacity:.6; }
.hwk-page-head .h1{ font-size:20px; font-weight:600; color:var(--text); }
.hwk-page-head .sub{ font-size:13px; color:var(--text2); }
.hwk-kpi{ display:grid; grid-template-columns:1fr 1fr .72fr .72fr; gap:16px; margin-bottom:20px; }
.hwk-kpi-c{ background:var(--card); border:1px solid var(--border); border-left:3px solid var(--text3);
            border-radius:12px; padding:12px 15px; }
.hwk-kpi-c .l{ font-size:12px; color:var(--text2); }
.hwk-kpi-c .v{ font-size:20px; font-weight:600; letter-spacing:-.6px; margin:2px 0 3px;
               font-variant-numeric:tabular-nums; color:var(--text); }
.hwk-kpi-c .s{ font-size:11px; color:var(--text2); }
.hwk-grid{ display:grid; grid-template-columns:1fr 320px; gap:24px; align-items:start; }
.hwk-col{ display:grid; gap:16px; align-content:start; min-height:96px; border-radius:12px; }
.hwk-col.wide{ grid-template-columns:1fr 1fr; }
.hwk-col.narrow{ grid-template-columns:1fr; }
.hwk-col.over{ outline:1px dashed var(--blue); outline-offset:6px; }
.hwk-col.no{ outline:1px dashed var(--red); outline-offset:6px; }
.hwk-colempty{ grid-column:1 / -1; border:1px dashed var(--border); border-radius:12px;
               padding:24px; text-align:center; font-size:12px; color:var(--text3); }
.hwk-ph{ grid-column:1 / -1; border:1px dashed var(--blue); background:var(--blue-bg);
         border-radius:12px; min-height:56px; }
.hwk-ph.half{ grid-column:auto; }

/* ── Плашка виджета в предпросмотре ──────────────────────────────────────── */
.hwk-tile{ position:relative; min-width:0; border-radius:12px; }
.hwk-tile.full{ grid-column:1 / -1; }
.hwk-tile:not(.lock){ cursor:grab; }
.hwk-tile.dragging{ opacity:.4; }
/* Виджет показывается настоящий, но «под стеклом»: id сняты в разметке, а
   нажатия гасятся здесь — иначе клик в окне управлял бы самой главной. */
.hwk-glass{ pointer-events:none; }
.hwk-glass *{ pointer-events:none !important; }
body.hwk-drag, body.hwk-drag *{ cursor:grabbing !important; user-select:none; }
.hwk-ghost{ position:fixed; z-index:1300; pointer-events:none; background:var(--card);
            border:1px solid var(--blue); border-radius:8px; box-shadow:var(--shadow-lg);
            padding:8px 12px; font-size:12px; font-weight:500; color:var(--text); }
.hwk-bar{ position:absolute; top:8px; right:8px; z-index:2; display:flex; align-items:center; gap:2px;
          padding:3px; background:var(--card); border:1px solid var(--border); border-radius:8px;
          box-shadow:var(--shadow-lg); opacity:0; transition:opacity .12s ease; }
.hwk-tile:hover .hwk-bar, .hwk-tile:focus-within .hwk-bar{ opacity:1; }
.hwk-b{ min-width:24px; height:24px; padding:0 6px; border:0; background:none; border-radius:8px;
        color:var(--text2); font-size:11px; font-weight:500; font-family:inherit; cursor:pointer;
        display:inline-flex; align-items:center; justify-content:center; }
.hwk-b:hover{ background:var(--card2); color:var(--text); }
.hwk-b.on{ background:var(--act-bg); color:var(--act); }
.hwk-b.grab{ cursor:grab; color:var(--text3); }
.hwk-b:disabled{ opacity:.35; cursor:default; }
.hwk-b.del:hover{ background:var(--red-bg); color:#B91C1C; }
[data-theme="dark"] .hwk-b.del:hover{ color:#F87171; }
@media (prefers-reduced-motion: reduce){ .hwk-bar{ transition:none; } }

/* ── Подвал ──────────────────────────────────────────────────────────────── */
.hwk-foot{ display:flex; align-items:center; gap:12px; padding:12px 24px;
           border-top:1px solid var(--border); background:var(--card); }
.hwk-foot-s{ font-size:12px; color:var(--text2); font-variant-numeric:tabular-nums; }
.hwk-foot-r{ margin-left:auto; display:flex; gap:8px; }

/* ── Панель свойств виджета внутри конструктора (шаг 4, 29.08.2026) ──────── */
.hwk-fld{ margin-bottom:12px; }
.hwk-chips{ display:flex; gap:8px; flex-wrap:wrap; }
.hwk-chip{ font-size:12px; font-weight:500; font-family:inherit; padding:5px 11px; border-radius:99px;
           border:1px solid var(--border); background:var(--card); color:var(--text2); cursor:pointer; }
.hwk-chip:hover{ border-color:var(--text3); color:var(--text); }
.hwk-chip.on{ border-color:var(--act); background:var(--act-bg); color:var(--act); }
[data-theme="dark"] .hwk-chip.on{ color:#60A5FA; }
.hwk-check{ display:flex; align-items:flex-start; gap:8px; font-size:12px; color:var(--text);
            cursor:pointer; padding:8px 0; }
.hwk-check input{ margin:2px 0 0; accent-color:var(--blue2); width:15px; height:15px; }
.hwk-check .d{ display:block; font-size:11px; color:var(--text2); margin-top:2px; }
/* Выбранная плашка и та, что на главной сейчас спряталась бы за пустотой. */
.hwk-tile.sel{ outline:1px solid var(--act); outline-offset:3px; }
.hwk-tile.willhide{ opacity:.55; }
.hwk-badge{ position:absolute; top:8px; left:8px; z-index:2; font-size:11px; color:var(--text2);
            background:var(--card); border:1px solid var(--border); border-radius:99px; padding:1px 8px; }

/* ── Линия первого экрана в предпросмотре (шаг 5, 29.08.2026) ─────────────
   Замер: при 1280×720 главной видно 701 px из 1957 — 36 %, и пять виджетов
   из восьми начинаются ниже. Метка стоит слева: справа она ложилась на строку
   отчёта в узкой колонке. */
.hwk-fold{ position:absolute; left:0; right:0; border-top:1px dashed var(--orange); pointer-events:none; }
.hwk-fold span{ position:absolute; left:0; top:-11px; background:var(--orange-bg); color:#B45309;
                border:1px solid var(--orange); border-radius:99px; padding:1px 12px; font-size:11px;
                white-space:nowrap; }
[data-theme="dark"] .hwk-fold span{ color:#FBBF24; }
.hwk-stage-r .hwk-seg{ display:inline-flex; vertical-align:middle; margin-left:6px; max-width:none; }

/* ── Миниатюра виджета в каталоге под курсором (29.08.2026) ───────────────
   Название не отвечает на вопрос «что это»: виджет ставили вслепую и потом
   убирали. Показываем настоящий виджет, ужатый до ширины списка; высота
   ограничена, поэтому длинные списки просто обрезаются — это витрина, а не
   рабочая копия. */
.hwk-cat{ flex-wrap:wrap; }
.hwk-mini{ width:100%; margin-top:8px; border:1px solid var(--border); border-radius:8px;
           background:var(--card2); padding:8px 9px; overflow:hidden; max-height:150px; }
.hwk-mini-w{ transform:scale(.72); transform-origin:top left; width:139%; pointer-events:none; }
.hwk-mini-w *{ pointer-events:none !important; }
