/* ═══════════════════════════════════════════════════════════════════════════
   Пульт БТИ — дизайн-система.

   Правило номер один: НИКАКИХ случайных значений. Любой цвет, размер шрифта и
   отступ берётся из переменных ниже. Если нужного значения нет — сначала
   добавляем его сюда со смыслом, потом используем.

   ── Смысл цвета (один цвет = одно значение, везде одинаково) ───────────────
   красный   --hot     горит: срок уже жмёт или пропущен; сбой, ошибка
   янтарь    --soon    скоро: срок на подходе, нужно внимание
   фиолет.   --new     новое, ещё не прочитанное сообщение от БТИ
   зелёный   --done    сделано: отработано, закрыто, подтверждено
   серо-син. --wait    ход у БТИ, от нас сейчас ничего не требуется
   синий     --accent  интерактив: ссылки, кнопки, выделенная строка
   охра      --client  кабинет клиента — пишем не от своего имени

   Цвет НИКОГДА не единственный носитель смысла: рядом всегда значок и слово.
   ═════════════════════════════════════════════════════════════════════════ */
/* Экран «Заявки» переведён 14.08.2026 (Дмитрий) на минимальный iOS-подобный
   стиль: один акцент, фон-карточки вместо рамок-теней, крупная типографика.
   Остальные экраны (карточка заявки, техраздел, Битрикс) эту переменную базу
   разделяют, но их собственная разметка не переписывалась — задача была
   именно про список и поиск. */
:root {
  /* нейтральная шкала */
  --bg:        #F4F5F7;
  --surface:   #ffffff;
  --surface-2: #f7f9fb;
  --surface-3: #eceff4;
  --line:      #E5E7EB;
  --line-2:    #c5ccd6;
  --ink:       #151a21;   /* главный текст */
  --ink-2:     #4d5765;   /* вторичный текст */
  --ink-3:     #6B7280;   /* служебный текст: подписи, мета, id */
  --dark:      #1d2129;   /* шапка */
  --dark-ink:  #e9edf3;
  --dark-dim:  #aeb8c6;

  /* смысловые */
  --accent:      #1D73CB;  --accent-bg: #e9f1fb;  --accent-line: #b9d5f0;
  --hot:         #b3261e;  --hot-bg:    #fdeceb;  --hot-line:    #eab3ae;
  --soon:        #8a5a00;  --soon-bg:   #fff5e0;  --soon-line:   #e9c887;
  --wait:        #3a5a72;  --wait-bg:   #eef2f6;  --wait-line:   #c2d0dc;
  --done:        #186a3b;  --done-bg:   #e8f5ed;  --done-line:   #a8d5bb;
  --new:         #6a2fa8;  --new-bg:    #f3ecfb;  --new-line:    #cdb6e6;
  --client:      #8a4b12;  --client-bg: #fdf1e4;  --client-line: #e9c39a;

  /* типографика: 3 уровня заголовков, основной текст, два служебных.
     Roboto — системный на Android, подтягивается из Google Fonts на
     остальных ОС (см. подключение в base.html); без него честный fallback. */
  --font: Roboto, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --mono: "DejaVu Sans Mono", Consolas, "Liberation Mono", monospace;
  --fs-xs:   11px;   /* совсем служебное: id, хеши */
  --fs-sm:   12px;   /* подписи, мета */
  --fs-md:   13px;   /* подписи по дизайну списка (13/400) */
  --fs-base: 14px;   /* вторичный текст (14/400) */
  --fs-lg:   16px;   /* адрес в строке списка (16/500), заголовок блока */
  --fs-xl:   19px;   /* заголовок экрана (h1) на прочих страницах */
  --fs-2xl:  27px;
  --fs-screen: 28px; /* заголовок экрана списка (28/500) */
  --lh: 1.45;

  /* сетка отступов и скруглений — кратно 8px */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  --r1: 3px; --r2: 5px; --r3: 8px; --r-card: 12px;
  --sh1: 0 1px 2px rgba(0,0,0,.06);
  --sh2: 0 4px 14px rgba(16,24,40,.13);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: var(--fs-base)/var(--lh) var(--font);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
.mono { font-family: var(--mono); }
.small { font-size: var(--fs-sm); }
.dim   { color: var(--ink-3); }
.err   { color: var(--hot); }
.pre   { white-space: pre-wrap; }
.nowrap { white-space: nowrap; }
h1 { font-size: var(--fs-xl); font-weight: 700; margin: 0 0 var(--s3); letter-spacing: -.2px; }
h2 { font-size: var(--fs-lg); font-weight: 600; margin: var(--s5) 0 var(--s2);
     padding-bottom: var(--s1); border-bottom: 1px solid var(--line); }
h3 { font-size: var(--fs-base); font-weight: 600; margin: var(--s3) 0 var(--s1); }
p  { margin: 0 0 var(--s2); }
section { margin-bottom: var(--s4); }
main { padding: var(--s4) var(--s4) var(--s6); }
main.flush { padding: 0; }

/* ── шапка ────────────────────────────────────────────────────────────────
   Постоянный контекст: где я, каким кабинетом пишу, свежие ли данные. */
header.top {
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
  background: var(--dark); color: var(--dark-ink);
  padding: var(--s2) var(--s4); font-size: var(--fs-md);
}
header.top a { color: var(--dark-ink); text-decoration: none; }
.brand a { font-weight: 700; font-size: var(--fs-base); color: #fff; letter-spacing: .2px; }
header nav { display: flex; gap: var(--s1); }
header nav a { padding: var(--s1) var(--s2); border-radius: var(--r1); color: var(--dark-dim); }
header nav a:hover { background: rgba(255,255,255,.10); color: #fff; }
header nav a.on { background: rgba(255,255,255,.16); color: #fff; font-weight: 600; }
header nav a.nav-primary { background: var(--accent); color: #fff; font-weight: 600;
                           margin-left: var(--s2); }
header nav a.nav-primary:hover { background: #175fac; color: #fff; }
header nav a.nav-primary.on { background: #175fac; color: #fff; }
/* Глобальный поиск в шапке (18.08.2026) — доступен с любой страницы кроме
   самого списка (там уже есть полноценная строка с фильтрами). */
.global-search { flex: 0 1 320px; margin-left: var(--s3); }
.global-search input { width: 100%; padding: 5px var(--s2); border-radius: var(--r2);
                        border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.08);
                        color: #fff; font: var(--fs-md)/1.3 var(--font); }
.global-search input::placeholder { color: var(--dark-dim); }
.global-search input:focus { background: rgba(255,255,255,.14); outline: none;
                              border-color: rgba(255,255,255,.4); }
@media (max-width: 900px) { .global-search { display: none; } }

.top-right { margin-left: auto; display: flex; align-items: center; gap: var(--s3);
             font-size: var(--fs-sm); }
.user { color: var(--dark-dim); }
.sync-info { color: var(--dark-dim); }
.sync-info b { color: var(--dark-ink); font-weight: 600; }
.running { color: #ffd166; margin-left: var(--s1); }
.top-right .logout { color: var(--dark-dim); text-decoration: underline; }

/* режим записи и гостевой вход — защитные метки, всегда заметны */
.badge { padding: 2px var(--s2); border-radius: var(--r1); font-size: var(--fs-sm);
         font-weight: 700; letter-spacing: .3px; white-space: nowrap; }
.badge-read  { background: #3b424c; color: #fff; }
.badge-write { background: var(--hot); color: #fff; }
.badge-acc   { display: inline-flex; align-items: center; gap: 3px; }
.badge-acc svg { display: block; }
.badge-guest { background: var(--new-bg); color: var(--new); border: 1px solid var(--new-line); }

/* ── состояние связи с сайтом (защита, не убирать) ───────────────────────── */
.health {
  padding: var(--s2) var(--s4); font-size: var(--fs-md);
  background: var(--hot-bg); color: var(--hot); border-bottom: 2px solid var(--hot-line);
}
.health-warn { background: var(--soon-bg); color: var(--soon); border-bottom-color: var(--soon-line); }
.health b { margin-right: var(--s1); }
.health .dim { color: inherit; opacity: .8; }
.health-detail { margin-right: var(--s2); font-family: var(--mono); font-size: var(--fs-sm); }
.health a { color: inherit; margin-left: var(--s2); font-weight: 700; }

/* ── хлебные крошки ──────────────────────────────────────────────────────── */
/* Разметку крошек добавили, а оформление — нет, и путь слипался в одну строку
   без отступов. Текущая страница намеренно не ссылка и цветом приглушена:
   кликать по «вы здесь» бессмысленно, а взгляд должен цепляться за путь назад. */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1);
          padding: var(--s2) var(--s4) 0; font-size: var(--fs-sm); }
.crumbs a { color: var(--ink-2); text-decoration: none;
            padding: 2px 4px; border-radius: var(--r1); }
.crumbs a:hover, .crumbs a:focus-visible { color: var(--ink); background: var(--surface);
                                           text-decoration: underline; }
.crumbs .sep { color: var(--line-2); padding: 0 2px; }
.crumbs .here { color: var(--ink-3); }

/* На телефоне путь длинный и норовит занять три строки — оставляем одну и
   прячем переполнение прокруткой, чтобы крошки не съедали пол-экрана. */
@media (max-width: 900px) {
  .crumbs { flex-wrap: nowrap; overflow-x: auto; padding: var(--s2) var(--s3) 0;
            scrollbar-width: none; }
  .crumbs::-webkit-scrollbar { display: none; }
  .crumbs a, .crumbs .here { white-space: nowrap; }
}

/* ── сообщения об итогах действий ────────────────────────────────────────── */
.flash { padding: var(--s2) var(--s3); margin: var(--s2) var(--s4);
         border-radius: var(--r2); font-size: var(--fs-md); }
.flash-ok  { background: var(--done-bg); border: 1px solid var(--done-line); color: var(--done); }
.flash-err { background: var(--hot-bg);  border: 1px solid var(--hot-line);  color: var(--hot); }
.empty { color: var(--ink-3); padding: var(--s3); }

/* ── элементы управления ─────────────────────────────────────────────────── */
button, .btn-link {
  font: 600 var(--fs-md)/1.3 var(--font); padding: 5px var(--s3);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink);
  border-radius: var(--r2); cursor: pointer; text-decoration: none;
  display: inline-block; white-space: nowrap;
}
button:hover, .btn-link:hover { background: var(--surface-3); }
button.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
button.primary:hover { background: #0e4783; }
button.small, .btn-link.small { font-size: var(--fs-sm); padding: 3px var(--s2); }
button[disabled] { background: var(--surface-3); color: #98a0ac;
                   border-color: var(--line); cursor: not-allowed; }
input[type=text], input[type=password], input[type=search], select, textarea {
  font: var(--fs-md)/1.3 var(--font); padding: 5px var(--s2);
  border: 1px solid var(--line-2); border-radius: var(--r2); background: var(--surface);
  color: var(--ink);
}
input:focus, select:focus, textarea:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
textarea { width: 100%; font-family: var(--font); }
form.inline { display: inline-flex; align-items: center; gap: var(--s2); }
.hint { color: var(--ink-3); font-size: var(--fs-sm); margin-left: var(--s2); }
.req { color: var(--hot); }

/* ── таблицы ─────────────────────────────────────────────────────────────── */
table.grid, table.tbl {
  border-collapse: collapse; width: 100%; background: var(--surface);
  margin-bottom: var(--s3); font-size: var(--fs-md);
  border: 1px solid var(--line);
}
table.grid th, table.grid td, table.tbl th, table.tbl td {
  border-bottom: 1px solid var(--line); padding: 5px var(--s2);
  text-align: left; vertical-align: top;
}
table.grid thead th, table.tbl th {
  background: var(--surface-3); font-weight: 600; font-size: var(--fs-sm);
  color: var(--ink-2); white-space: nowrap;
}
table.grid tbody tr:hover { background: var(--surface-2); }
tr.row-err { background: var(--hot-bg); }
table.kv { border-collapse: collapse; background: var(--surface); width: 100%;
           max-width: 900px; margin-bottom: var(--s3); border: 1px solid var(--line);
           font-size: var(--fs-md); }
table.kv th { text-align: left; font-weight: 600; background: var(--surface-2);
              color: var(--ink-2); padding: 5px var(--s3);
              border-bottom: 1px solid var(--line); width: 220px; font-size: var(--fs-sm); }
table.kv td { border-bottom: 1px solid var(--line); padding: 5px var(--s3); }
table.sub { width: 100%; margin: calc(-1 * var(--s1)) 0 var(--s4); }

/* ── метки (чипы) ─────────────────────────────────────────────────────────
   Базовый чип нейтрален; смысл добавляет модификатор. */
.mark {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px var(--s2); border-radius: 10px; font-size: var(--fs-sm);
  font-weight: 600; background: var(--surface-3); color: var(--ink-2);
  border: 1px solid var(--line-2); white-space: nowrap;
}
.mark-new, .mark-manual   { background: var(--new-bg);  color: var(--new);  border-color: var(--new-line); }
.mark-err, .mark-error, .mark-failed { background: var(--hot-bg); color: var(--hot); border-color: var(--hot-line); }
.mark-ok, .mark-verified, .mark-sent { background: var(--done-bg); color: var(--done); border-color: var(--done-line); }
.mark-queued, .mark-sending { background: var(--accent-bg); color: var(--accent); border-color: var(--accent-line); }
.mark-draft { background: var(--surface-3); color: var(--ink-3); }
.acc-own    { background: var(--wait-bg);   color: var(--wait);   border-color: var(--wait-line); }
.acc-client { background: var(--client-bg); color: var(--client); border-color: var(--client-line); }

/* ── плашка режима записи (защита, не убирать) ───────────────────────────── */
.mode-banner { padding: var(--s3) var(--s4); margin: 0 0 var(--s4);
               border-radius: var(--r2); font-size: var(--fs-lg); font-weight: 700;
               letter-spacing: .3px; }
.mode-read  { background: var(--soon-bg); border: 2px solid var(--soon-line); color: var(--soon); }
.mode-write { background: var(--hot-bg);  border: 2px solid var(--hot);       color: var(--hot); }
.mode-why { font-size: var(--fs-md); font-weight: 400; margin-top: var(--s1);
            letter-spacing: 0; }
.block-why { color: var(--hot); font-size: var(--fs-sm); }

/* ═══════════════════════════════════════════════════════════════════════════
   ЭКРАН «ЗАЯВКИ» — режим одного окна
   ═════════════════════════════════════════════════════════════════════════ */
body.screen-list { display: flex; flex-direction: column; overflow: hidden; }
body.screen-list main { flex: 1 1 auto; min-height: 0; }
.one-window { display: grid; grid-template-columns: minmax(380px, 34%) 1fr;
              height: 100%; min-height: 0; }
.lp { display: flex; flex-direction: column; min-height: 0;
      background: var(--bg); border-right: 1px solid var(--line-2); }
/* Живой поиск: между нажатием клавиши и ответом сервера список едва
   тускнеет — не мигает пустотой и не мешает печатать дальше. */
.lp-loading { opacity: .55; transition: opacity .1s linear; }
.rp { min-height: 0; overflow: auto; background: var(--surface); }
.rp-empty { padding: var(--s6); color: var(--ink-3); }

/* ── экран списка: заголовок, поиск, фильтры ──────────────────────────────── */
.lp-head { flex: 0 0 auto; padding: var(--s4) var(--s3) 0; }
.lp-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--s3) var(--s5); }

/* Поиск — самый заметный элемент экрана: крупное поле, всегда в шапке списка. */
.filterbar { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center;
             margin-bottom: var(--s3); }
.filterbar input[type=search] {
  flex: 1 1 260px; min-width: 160px; height: 40px; padding: 0 var(--s3);
  border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface);
  font-size: var(--fs-lg);
}
.filterbar input[type=search]:focus {
  border-color: var(--accent); outline: 2px solid var(--accent-bg);
}
.filterbar select {
  height: 36px; padding: 0 var(--s2); border: 1px solid var(--line);
  border-radius: var(--r2); background: var(--surface); font-size: var(--fs-md);
  color: var(--ink-2);
}
/* активный фильтр — единственным акцентным цветом на экране */
.filterbar select.on, .filterbar input.on {
  border-color: var(--accent); background: var(--accent-bg);
  color: var(--accent); font-weight: 500;
}
.f-reset { color: var(--ink-3); font-size: var(--fs-lg); text-decoration: none;
           padding: 0 var(--s1); line-height: 36px; }
.f-reset:hover { color: var(--ink); }
.f-reset.on { color: var(--accent); }
html.js .f-apply { display: none; }   /* без JS кнопка нужна, с JS — лишняя */

/* ── сортировка: три мелкие текстовые ссылки, не таблица-заголовок ───────── */
.sortbar { display: flex; align-items: center; gap: var(--s4);
           padding: var(--s1) var(--s1) var(--s2); }
.sortbar a { font-size: var(--fs-md); color: var(--ink-3); text-decoration: none; }
.sortbar a:hover { color: var(--ink-2); }
.sortbar a.on { color: var(--accent); font-weight: 500; }
.sortbar a .arr { font-size: 9px; }

/* ── переключатель Список/Канбан (ТЗ 17.08.2026) ─────────────────────────── */
.view-switch { margin-left: auto; display: flex; gap: 2px; padding: 2px;
               background: var(--surface-3); border-radius: var(--r2); }
.view-switch a { padding: 2px 10px; border-radius: var(--r1); font-size: var(--fs-sm);
                 color: var(--ink-2) !important; font-weight: 500; }
.view-switch a.on { background: var(--surface); color: var(--accent) !important;
                    box-shadow: var(--sh1); }

/* ── «Подать» — активная кнопка на строке «Нужно подать» (18.08.2026) ────── */
.btn-podat { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
             background: var(--accent); color: #fff; text-decoration: none;
             font: 600 var(--fs-sm)/1.3 var(--font); padding: 6px 14px; border-radius: var(--r2);
             margin-right: var(--s3); }
.btn-podat:hover { background: #175fac; color: #fff; }
.kb-card .btn-podat { display: block; margin: 0 var(--s2) var(--s2); text-align: center; }

/* ── «Нужно подать»: закреплённая секция сверху (ТЗ 17.08.2026) ──────────── */
.needs-podat { margin-bottom: var(--s3); }
.needs-podat-head { display: flex; align-items: baseline; gap: var(--s2);
                    font: 500 var(--fs-base)/1.3 var(--font); color: var(--ink);
                    padding: 0 var(--s1) var(--s2); }
.needs-podat .req-list { border-radius: var(--r-card); }

/* ── Kanban: колонки-статусы, компактные карточки, горизонтальный скролл ──── */
.kanban { display: flex; gap: var(--s3); align-items: flex-start;
          overflow-x: auto; padding-bottom: var(--s3); }
.kb-col { flex: 0 0 260px; background: var(--surface-2); border-radius: var(--r-card);
          padding: var(--s2); max-height: calc(100vh - 260px); overflow-y: auto; }
.kb-col-head { display: flex; align-items: baseline; justify-content: space-between;
               gap: var(--s2); padding: 2px var(--s1) var(--s2); position: sticky; top: 0;
               background: var(--surface-2); }
.kb-col-title { font: 500 var(--fs-base)/1.3 var(--font); color: var(--ink); }
.kb-col-count { font: 700 var(--fs-sm)/1 var(--font); color: var(--ink-3); }
.kb-list { list-style: none; margin: 0; padding: 0; display: flex;
           flex-direction: column; gap: 6px; }
.kb-card { background: var(--surface); border-radius: var(--r2); box-shadow: var(--sh1); }
.kb-card a { display: block; padding: var(--s2); text-decoration: none; color: var(--ink); }
.kb-card.sel { outline: 2px solid var(--accent); outline-offset: -2px; }
.kb-addr { display: block; font: 500 var(--fs-base)/1.3 var(--font); color: var(--ink);
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-sub  { display: block; font: 400 var(--fs-sm)/1.3 var(--font); color: var(--ink-2);
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.kb-meta { display: flex; align-items: center; gap: 5px; margin-top: 4px; flex-wrap: wrap; }
.kb-empty { font-size: var(--fs-sm); text-align: center; padding: var(--s2) 0; }
.kb-more { display: block; width: 100%; font-size: var(--fs-sm); text-align: center;
           padding: var(--s2) 0; background: none; border: none; color: var(--accent);
           cursor: pointer; }
.kb-more:hover { text-decoration: underline; }
.kb-more:disabled { opacity: .5; cursor: wait; text-decoration: none; }

@media (max-width: 900px) {
  /* Без проработанного мобильного сценария для горизонтальных колонок —
     переключатель прячем (сам редирект на List ниже брейкпоинта — в app.js,
     раз CSS не может подменить уже отрисованный на сервере Kanban на List). */
  .view-switch { display: none; }
}

/* ── список заявок: белые карточки на сером фоне, тонкий разделитель ─────── */
.req-list { list-style: none; margin: 0 0 var(--s2); padding: 0;
            background: var(--surface); border-radius: var(--r-card);
            box-shadow: var(--sh1); overflow: hidden; }
.req { border-bottom: 1px solid var(--line); display: flex; align-items: center; }
.req:last-child { border-bottom: none; }
/* Галочка массового выбора (топ-10 UX, 18.08.2026) — не в самой ссылке-строке:
   клик по чекбоксу не должен открывать заявку. */
.req-check { flex: 0 0 auto; display: flex; align-items: center;
             padding: 0 0 0 var(--s3); cursor: pointer; }
.bulk-check { width: 15px; height: 15px; cursor: pointer; accent-color: var(--accent); }
.req-link { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: var(--s2);
            min-height: 64px; padding: 10px var(--s4); text-decoration: none;
            color: var(--ink); }
.req-link:hover { background: var(--surface-2); }
.req.sel .req-link { background: var(--accent-bg); }
/* Клавиатурная навигация ↑/↓/Enter (топ-10 UX, 18.08.2026) — фокус строки без
   мыши, тот же приём, что выделение текущей заявки (.sel), но своим контуром,
   иначе не отличить «открыта» от «под курсором клавиатуры». */
.req.kbd-focus .req-link { outline: 2px solid var(--accent); outline-offset: -2px; }

.r-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.r-addr { font: 500 var(--fs-lg)/1.3 var(--font); color: var(--ink);
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.r-sub  { font: 400 var(--fs-base)/1.3 var(--font); color: var(--ink-2);
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Третья строка — не текст, а ряд мелких элементов: статус-чип, чип действия
   (не более одного — источник в web.py._action_chip уже гарантирует это),
   время, иконки быстрых документов. Цвет здесь функционален (ТЗ 17.08.2026,
   п.26): статус красится по уже посчитанной срочности, а не рисуется весь
   ряд/карточка одним цветом. */
.r-meta { display: flex; align-items: center; gap: 6px; overflow: hidden; }
.r-time { font: 400 var(--fs-md)/1.3 var(--font); color: var(--ink-3);
          white-space: nowrap; margin-left: 2px; }
.r-chevron { flex: 0 0 auto; color: var(--ink-3); font-size: 20px; line-height: 1; }
/* Подсветка совпадений поиска — акцентом, не жёлтым браузерным умолчанием:
   единственный цвет на экране и здесь тот же самый. */
.r-addr mark, .r-sub mark { background: var(--accent-bg); color: var(--accent);
                            font-weight: 700; border-radius: 2px; padding: 0 1px; }

.status-chip, .action-chip { flex: 0 0 auto; font: 500 var(--fs-sm)/1.3 var(--font);
                             padding: 1px 8px; border-radius: 9px; white-space: nowrap; }
.status-chip { background: var(--surface-3); color: var(--ink-2); }
.status-chip[data-tone="hot"]  { background: var(--hot-bg);  color: var(--hot); }
.status-chip[data-tone="soon"] { background: var(--soon-bg); color: var(--soon); }
.status-chip[data-tone="wait"] { background: var(--wait-bg); color: var(--wait); }
.status-chip[data-tone="done"] { background: var(--surface-3); color: var(--ink-3); }
/* Чип действия — отдельно от статуса БТИ: статус объясняет, что происходит на
   сайте, чип — что сделать нам (Дмитрий, 14.08.2026). */
.action-chip { font-weight: 700; }
.action-chip[data-action="pay"]     { background: var(--hot-bg);    color: var(--hot); }
.action-chip[data-action="reply"]   { background: var(--soon-bg);   color: var(--soon); }
.action-chip[data-action="collect"] { background: var(--accent-bg); color: var(--accent); }

.doc-icon { flex: 0 0 auto; line-height: 1; text-decoration: none; color: var(--ink-2);
            padding: 2px; border-radius: var(--r1); opacity: .8; display: inline-flex; }
.doc-icon:hover { opacity: 1; background: var(--surface-3); }
.doc-icon svg { display: block; }

/* Переписка на отдельной странице заявки (card.html) свёрнута по умолчанию —
   заявка вторичный экран, главное выше (ТЗ 17.08.2026). */
.chat-collapse summary { cursor: pointer; padding: var(--s2) 0; font-weight: 600;
                          list-style: none; display: flex; align-items: center; gap: 6px; }
.chat-collapse summary::-webkit-details-marker { display: none; }
.chat-collapse summary::before { content: '▸ '; color: var(--ink-3); }
.chat-collapse[open] summary::before { content: '▾ '; }

/* «новое сообщение» в переписке (_chat.html) — не про список, оставлен. */
.tag-new  { display: inline-flex; align-items: center; gap: 2px; padding: 0 5px;
            border-radius: 9px; font-size: var(--fs-xs); font-weight: 700;
            border: 1px solid var(--new-line); white-space: nowrap; line-height: 15px;
            background: var(--new-bg); color: var(--new); }

.counters { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
            font-size: var(--fs-sm); color: var(--ink-3); margin-bottom: var(--s2); }
.counters b { color: var(--ink); font-weight: 700; }
.counters .sync-mini { margin-left: auto; }
.more { text-align: center; padding: var(--s2) 0 var(--s4); }

/* ═══════════════════════════════════════════════════════════════════════════
   ПРАВАЯ ПАНЕЛЬ — переписка
   ═════════════════════════════════════════════════════════════════════════ */
.chat-wrap { display: flex; flex-direction: column; min-height: 100%; }
.chat-head { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
             padding: var(--s2) var(--s4); background: var(--surface);
             border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 3; }
.ch-left { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.ch-num { font: 700 var(--fs-xl)/1.2 var(--font); color: var(--ink);
          text-decoration: none; letter-spacing: -.3px; }
.ch-status { font-size: var(--fs-md); font-weight: 600; color: var(--ink-2);
             background: var(--surface-3); border-radius: 10px; padding: 1px var(--s2); }
/* flex-wrap обязателен: за 10.08.2026 в этой панели набралось 4 кнопки
   («Обновить», «Отработано», «Сохранить переписку», «Открыть в БТИ»), и без
   переноса на узком экране (390px) они не помещаются в строку и вылезают
   за край вместо того, чтобы уйти на вторую строку. */
.ch-right { margin-left: auto; display: flex; gap: var(--s1); align-items: center;
            flex-wrap: wrap; }

/* что делать по этой заявке — самое важное на экране после самой ленты */
.chat-hint { padding: var(--s2) var(--s4); font-size: var(--fs-base);
             border-bottom: 1px solid var(--line); }
.chat-hint b { font-weight: 700; }
.chat-hint .why { display: block; font-size: var(--fs-sm); font-weight: 400; margin-top: 1px; }
.chat-hint .deadline { font-weight: 700; margin-left: var(--s2); white-space: nowrap; }
.chat-hint.u-urgent { background: var(--hot-bg);  color: var(--hot);  border-bottom-color: var(--hot-line); }
.chat-hint.u-soon   { background: var(--soon-bg); color: var(--soon); border-bottom-color: var(--soon-line); }
.chat-hint.u-normal { background: var(--wait-bg); color: var(--wait); border-bottom-color: var(--wait-line); }
.chat-hint .why { color: inherit; opacity: .85; }

.chat-meta { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3);
             padding: 5px var(--s4); font-size: var(--fs-sm); color: var(--ink-2);
             background: var(--surface-2); border-bottom: 1px solid var(--line); }
.chat-meta .addr { font-weight: 600; color: var(--ink); }
.bx-block { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s2); align-items: baseline;
            padding: 5px var(--s4); font-size: var(--fs-sm);
            background: var(--surface-2); border-bottom: 1px solid var(--line);
            border-left: 3px solid var(--accent-line); }
.bx-contact { display: inline-flex; gap: var(--s1); align-items: baseline; }
.bx-contact a { color: var(--accent); text-decoration: none; }
.bx-contact a:hover { text-decoration: underline; }

/* Договорённости из docs-right2: другой источник, чем Битрикс — не смешиваем
   визуально, оставляем свободный текст как есть, без попытки его разобрать. */
.agreements-block { padding: 5px var(--s4); font-size: var(--fs-sm);
                     background: var(--surface-2); border-bottom: 1px solid var(--line);
                     border-left: 3px solid var(--line-2); }
.agreement-row { padding: 2px 0; }
.agreement-title { font-weight: 600; color: var(--ink-2); }

/* Комментарий менеджера из сделки (18.08.2026) — свободный текст, тот же
   визуальный ряд, что и договорённости/блок Битрикса выше. */
.manager-comment { padding: 5px var(--s4); font-size: var(--fs-sm); color: var(--ink-2);
                    background: var(--surface-2); border-bottom: 1px solid var(--line);
                    border-left: 3px solid var(--line-2); white-space: pre-wrap; }

/* Наши документы, отданные в docs-right2 (18.08.2026). */
.dr-docs { padding: 5px var(--s4); font-size: var(--fs-sm);
           background: var(--surface-2); border-bottom: 1px solid var(--line);
           border-left: 3px solid var(--accent-line); }
.dr-doc-row { display: flex; align-items: center; gap: var(--s2); padding: 2px 0; }

/* Заметки специалиста: техник БТИ и доступ на объект — наши данные, не с сайта. */
.notes-block { background: var(--surface-2); border-bottom: 1px solid var(--line);
               padding: 0 var(--s4); font-size: var(--fs-sm); }
.notes-block summary { cursor: pointer; padding: 5px 0; color: var(--ink-2);
                       list-style: none; user-select: none; }
.notes-block summary::-webkit-details-marker { display: none; }
.notes-block summary::before { content: '▸ '; }
.notes-block[open] summary::before { content: '▾ '; }
.notes-form { display: flex; flex-direction: column; gap: var(--s2); padding-bottom: var(--s3); }
.notes-row { display: flex; gap: var(--s2); flex-wrap: wrap; }
.notes-row input { flex: 1 1 220px; }
.notes-form textarea { width: 100%; font-family: var(--font); resize: vertical; }
.notes-bottom { display: flex; align-items: center; gap: var(--s2); }

/* лента */
.feed { flex: 1 1 auto; padding: var(--s3) var(--s4); background: var(--surface-2); }
.msg { max-width: 80%; margin-bottom: var(--s2); padding: var(--s2) var(--s3);
       border-radius: var(--r3); background: var(--surface);
       border: 1px solid var(--line); box-shadow: var(--sh1); }
.msg.theirs { border-top-left-radius: 2px; }
.msg.ours { margin-left: auto; background: var(--accent-bg);
            border-color: var(--accent-line); border-top-right-radius: 2px; }
.msg.fresh { border-color: var(--new-line); box-shadow: 0 0 0 2px var(--new-bg); }
.msg.sys { max-width: 100%; margin: 0 auto var(--s1); padding: 1px 0; background: none;
           border: none; box-shadow: none; text-align: center;
           font-size: var(--fs-sm); color: var(--ink-3); }
.msg.sys b { color: var(--ink-2); }
.m-head { display: flex; gap: var(--s2); align-items: baseline;
          font-size: var(--fs-sm); margin-bottom: 2px; }
.m-head .who { font-weight: 700; color: var(--ink-2); }
.m-head .t { color: var(--ink-3); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.m-body { font-size: var(--fs-base); white-space: normal; }
.m-files { margin-top: var(--s1); display: flex; flex-wrap: wrap; gap: var(--s1); }
a.file { display: inline-block; max-width: 100%; padding: 1px var(--s2);
         background: var(--surface-3); border: 1px solid var(--line-2);
         border-radius: var(--r1); font-size: var(--fs-sm); color: var(--accent);
         text-decoration: none; overflow: hidden; text-overflow: ellipsis;
         white-space: nowrap; }
a.file:hover { background: var(--accent-bg); border-color: var(--accent-line); }
a.file::before { content: "📎 "; }
.chat-files { padding: var(--s2) var(--s4); background: var(--surface-2);
              border-top: 1px solid var(--line); display: flex; flex-wrap: wrap;
              gap: var(--s1); align-items: baseline; font-size: var(--fs-sm); }

/* ответ */
.reply { flex: 0 0 auto; padding: var(--s2) var(--s4) var(--s3);
         background: var(--surface); border-top: 1px solid var(--line-2);
         position: sticky; bottom: 0; }
.reply-mode { font-size: var(--fs-sm); font-weight: 600; margin-bottom: var(--s1);
              padding: 3px var(--s2); border-radius: var(--r1); }
.reply-mode.ok      { background: var(--hot-bg); color: var(--hot); }
.reply-mode.blocked { background: var(--surface-3); color: var(--ink-2); }
.templates { display: flex; flex-wrap: wrap; gap: var(--s1); margin-bottom: var(--s1);
             align-items: baseline; }
.tpl { font: 600 var(--fs-sm)/1.3 var(--font); padding: 2px var(--s2);
       border: 1px dashed var(--line-2); border-radius: 10px; background: var(--surface-2);
       color: var(--ink-2); cursor: pointer; }
.tpl:hover { border-style: solid; border-color: var(--accent); color: var(--accent); }
.tpl-warn { border-color: var(--soon-line); color: var(--soon); }
.tpl-warn::after { content: " ⚠"; }
.reply-bottom { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s1); }
.reply-bottom input[type=file] { font-size: var(--fs-sm); flex: 1 1 auto; min-width: 0; }
.outbox-box { padding: 0 var(--s4) var(--s3); font-size: var(--fs-sm); }
.outbox-box summary { cursor: pointer; color: var(--ink-3); padding: var(--s1) 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   КАРТОЧКА, ТЕХРАЗДЕЛ, ФОРМЫ
   ═════════════════════════════════════════════════════════════════════════ */
.card-head { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
             margin-bottom: var(--s3); }
.card-head h1 { margin: 0; }
.card-actions { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }
.status-pill { background: var(--surface-3); border-radius: 10px; padding: 2px var(--s3);
               font-size: var(--fs-md); font-weight: 600; color: var(--ink-2);
               margin-left: var(--s2); vertical-align: middle; }
.card-chat { background: var(--surface); border: 1px solid var(--line);
             border-radius: var(--r2); overflow: hidden; margin-bottom: var(--s4); }
details.box { background: var(--surface); border: 1px solid var(--line);
              border-radius: var(--r2); margin-bottom: var(--s2); }
details.box > summary { cursor: pointer; padding: var(--s2) var(--s3);
                        font-size: var(--fs-md); font-weight: 600; color: var(--ink-2);
                        list-style: none; }
details.box > summary::before { content: "▸ "; color: var(--ink-3); }
details.box[open] > summary { border-bottom: 1px solid var(--line); }
details.box[open] > summary::before { content: "▾ "; }
details.box > .box-body { padding: var(--s3); }
details.box > .box-body > table { margin-bottom: 0; }

.new-form { max-width: 900px; }
.send-row { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s3); }

/* ── вход и ошибка ───────────────────────────────────────────────────────── */
.login-page { display: flex; align-items: center; justify-content: center;
              height: 100vh; background: var(--bg); }
.login-box { background: var(--surface); border: 1px solid var(--line);
             padding: var(--s5); border-radius: var(--r3); width: 340px;
             box-shadow: var(--sh2); }
.login-box h1 { margin-top: 0; }
.login-box label { display: block; margin-bottom: var(--s3); font-size: var(--fs-sm);
                   font-weight: 600; color: var(--ink-2); }
.login-box input { display: block; width: 100%; margin-top: 3px; }
.login-box button { width: 100%; padding: var(--s2); }
.errbox { background: var(--surface); border: 1px solid var(--line);
          border-radius: var(--r2); padding: var(--s4) var(--s5); max-width: 760px; }

/* ── узкий экран: два «экрана» вместо двух колонок ───────────────────────── */
/* На телефоне колонки рядом не помещаются. Раньше правую панель просто прятали
   (`display:none`) — и тап по заявке визуально не делал НИЧЕГО: переписка
   грузилась в невидимый блок. Теперь это две страницы одного экрана: список →
   тап → переписка на весь экран → «← список» обратно. Класс на <body> ставит
   app.js; без JS ссылки ведут на отдельные страницы и всё работает так же. */
@media (max-width: 900px) {
  .one-window { grid-template-columns: 1fr; }
  body.screen-list { overflow: auto; }
  .lp { border-right: 0; }
  .rp { display: none; }
  body.chat-open .lp { display: none; }
  body.chat-open .rp { display: block; }
  /* Кнопка возврата нужна только здесь: на широком экране список и так виден. */
  .chat-back { display: inline-block; }
  /* Палец — не мышь: цели меньше 40px мажут. */
  .chat-head button, .chat-head .btn-link, .chat-back { min-height: 36px; }
  .reply textarea { font-size: 16px; }   /* меньше 16px — iOS зумит страницу */
}
/* На широком экране возврат не нужен: список никуда не девался. */
.chat-back { display: none; font-weight: 600; text-decoration: none;
             color: var(--accent); padding: 2px var(--s2); }

/* Переключатель архива: заметный, но не кричащий — это редкое действие. */
.f-arch { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px;
          font-size: 13px; color: var(--muted, #667); cursor: pointer;
          border: 1px solid var(--line, #d7dce3); border-radius: 4px; }
.f-arch.on { background: #eef3ff; color: #24406b; border-color: #b6cdf0; }
.f-arch input { margin: 0; }

/* Переключатель «искать в закрытых» — тот же стиль, что и общий архивный,
   но стоит у самой строки поиска: решение принимается в момент поиска. */
.f-qarch { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px;
           font-size: 13px; color: var(--ink-3); cursor: pointer;
           border: 1px solid var(--line-2); border-radius: var(--r1); white-space: nowrap; }
.f-qarch.on { background: #eef3ff; color: #24406b; border-color: #b6cdf0; }
.f-qarch input { margin: 0; }

.archive-hint { padding: var(--s2) var(--s4); font-size: var(--fs-sm);
                color: var(--ink-2); background: var(--surface-2);
                border-bottom: 1px solid var(--line); }
.archive-hint a { margin-left: var(--s2); font-weight: 600; }

/* Окно отмены: сообщение ещё не ушло в БТИ, несколько секунд можно передумать. */
.sending { margin: 8px 0; }
.sending-row { display: flex; align-items: center; gap: 10px; padding: 6px 10px;
               background: #fff8e1; border-left: 3px solid #e0a800; font-size: 13px; }
.sending-row.cancelled { background: #f1f3f5; border-left-color: #adb5bd; color: #667; }
.sending-row.gone { opacity: .65; }
.sending-txt { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.undo { padding: 2px 10px; font-size: 13px; cursor: pointer; }
.undo[disabled] { cursor: default; opacity: .6; }

/* ═══════════════════════════════════════════════════════════════════════════
   Топ-10 UX-улучшений (18.08.2026) — тема, плотность, тосты, массовые
   действия, скелетон-загрузка, залипающая панель фильтров, онбординг.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── тёмная тема: та же переменная база, другие значения ─────────────────── */
:root[data-theme="dark"] {
  --bg:        #14171c;
  --surface:   #1c2028;
  --surface-2: #20242c;
  --surface-3: #2a2f38;
  --line:      #333944;
  --line-2:    #454c58;
  --ink:       #e8ebf0;
  --ink-2:     #b4bcc8;
  --ink-3:     #8790a0;
  --dark:      #0e1116;
  --dark-ink:  #e9edf3;
  --dark-dim:  #8b93a1;

  --accent:      #4a9eff;  --accent-bg: #1c2d42;  --accent-line: #2c4a6e;
  --hot:         #ff6b64;  --hot-bg:    #3a1f1e;  --hot-line:    #5c2e2b;
  --soon:        #e0af4b;  --soon-bg:   #3a2f14;  --soon-line:   #5c4b1f;
  --wait:        #8fb0c7;  --wait-bg:   #232c34;  --wait-line:   #37424e;
  --done:        #5cc98a;  --done-bg:   #17301f;  --done-line:   #25502f;
  --new:         #b98cf0;  --new-bg:    #2a2038;  --new-line:    #43305c;
  --client:      #e0a468;  --client-bg: #332212;  --client-line: #52381c;
}

/* ── переключатели темы/плотности в шапке ─────────────────────────────────── */
.icon-btn { background: none; border: none; color: var(--dark-dim); cursor: pointer;
            padding: 4px; border-radius: var(--r1); display: flex; align-items: center; }
.icon-btn:hover { background: rgba(255,255,255,.12); color: #fff; }
.icon-btn[aria-pressed="true"] { color: #fff; background: rgba(255,255,255,.14); }
#theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] #theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] #theme-toggle .icon-moon { display: block; }

/* ── плотность списка: компакт против обычной (по умолчанию) ─────────────── */
[data-density="compact"] .req-link { min-height: 40px; padding: 5px var(--s4); }
[data-density="compact"] .r-addr { font-size: var(--fs-base); }
[data-density="compact"] .r-sub { display: none; }
[data-density="compact"] .kb-card { padding: 6px 8px; }

/* ── выбрать все (счётчики над списком) ───────────────────────────────────── */
.select-all { display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
              color: var(--ink-3); margin-left: var(--s2); }
.select-all input { cursor: pointer; accent-color: var(--accent); }

/* ── плавающая панель массовых действий ───────────────────────────────────── */
.bulk-bar { position: fixed; left: 50%; bottom: var(--s5); transform: translate(-50%, 12px);
            background: var(--dark); color: var(--dark-ink); padding: var(--s2) var(--s3);
            border-radius: var(--r3); box-shadow: var(--sh2); display: flex; align-items: center;
            gap: var(--s3); z-index: 40; opacity: 0; pointer-events: none;
            transition: opacity .15s, transform .15s; }
.bulk-bar.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.bulk-bar .bulk-count { font-weight: 600; white-space: nowrap; }
.bulk-bar button { border-color: rgba(255,255,255,.3); background: none; color: var(--dark-ink); }
.bulk-bar button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.bulk-bar button:disabled { opacity: .6; cursor: wait; }

/* ── тосты: те же серверные msg=/err=, плюс действия из JS (тост из app.js) ── */
#toast-root { position: fixed; right: var(--s4); bottom: var(--s4); z-index: 50;
              display: flex; flex-direction: column; gap: var(--s2); pointer-events: none;
              max-width: 360px; }
.toast { pointer-events: auto; background: var(--dark); color: var(--dark-ink);
         padding: var(--s2) var(--s3); border-radius: var(--r2); box-shadow: var(--sh2);
         font-size: var(--fs-md); opacity: 0; transform: translateY(8px);
         transition: opacity .2s, transform .2s; }
.toast.in { opacity: 1; transform: translateY(0); }
.toast-err { background: var(--hot); color: #fff; }

/* ── скелетон-загрузка вместо резкого мигания списка/переписки ───────────── */
@keyframes bti-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
.lp-loading .req-list, .lp-loading .kanban, .lp-loading .needs-podat {
  animation: bti-pulse 1s ease-in-out infinite; pointer-events: none; }
#chat-panel.loading .chat-wrap { animation: bti-pulse 1s ease-in-out infinite; pointer-events: none; }

/* ── залипающая строка сортировки/фильтров при скролле длинного списка ───── */
.sortbar { position: sticky; top: 0; z-index: 2; background: var(--bg); }

/* ── онбординг для новых сотрудников: точечные подсказки поверх интерфейса ── */
.onb-spot { position: fixed; z-index: 60; background: var(--surface); color: var(--ink);
            border-radius: var(--r3); box-shadow: var(--sh2); padding: var(--s3) var(--s4);
            max-width: 280px; font-size: var(--fs-md); }
.onb-spot .onb-title { font-weight: 700; margin-bottom: 4px; }
.onb-spot .onb-actions { display: flex; justify-content: space-between; align-items: center;
                          margin-top: var(--s3); }
.onb-spot .onb-step { color: var(--ink-3); font-size: var(--fs-sm); }
.onb-backdrop { position: fixed; inset: 0; z-index: 55; background: rgba(0,0,0,.15); }
.onb-highlight { position: relative; z-index: 56; box-shadow: 0 0 0 3px var(--accent),
                 0 0 0 9999px rgba(0,0,0,.35); border-radius: var(--r2); }

@media (max-width: 900px) {
  .icon-btn { display: none; }   /* плотность/тема на телефоне не критичны — экономим место в шапке */
}
