/* Оформление страницы целиком: палитра, шапка, разделы, карточки, таблица,
   панели-окна и подсказки. Один файл без сборки — подключается <link> из
   index.html; порядок правил имеет значение там, где специфичность равна
   (например, .gate h2 обязан стоять после .card h2). */
:root {
  --bg:#f6f7f9; --card:#fff; --ink:#1c1c1e; --muted:#6b6b70; --line:#e3e4e8;
  /* приглушённая палитра: один уровень насыщенности, чтобы шесть групп читались
     как шкала, а не как набор сигнальных ламп */
  --fresh:#8d7ac4; --new:#41729f; --returned:#5aa9a2; --active:#46824f; --at_risk:#cc9144; --lost:#bf5f52;
  /* Ширина колонки — одна на все разделы: шапка, содержимое и панели держатся
     одного числа, и при переходе между разделами страница не «дышит».
     1280 — столько нужно таблице «Клиентов» с её четырнадцатью колонками;
     разделы уже таблицы просто не растягиваются шире. */
  --col:1280px;
}
* { box-sizing:border-box }
body { margin:0; font:15px/1.5 system-ui,-apple-system,"SF Pro Text","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; color:var(--ink); background:var(--bg); -webkit-font-smoothing:antialiased; font-variant-numeric:tabular-nums }
p, .hint, .todo-card, .sub, .kpi .d { text-wrap:pretty }  /* без висячих слов в конце абзаца */
/* z-index выше затемнения: переключатели разделов и дата остаются рабочими,
   даже когда поверх дашборда открыто окно */
header { position:sticky; top:0; z-index:14; padding:10px 0;
         background:rgba(255,255,255,.82); backdrop-filter:saturate(180%) blur(14px);
         border-bottom:1px solid var(--line) }
/* та же колонка, что и у main, — шапка выровнена с содержимым */
.hrow { display:flex; gap:20px; align-items:center; flex-wrap:wrap; max-width:var(--col); margin:0 auto; padding:0 20px }
.brand { display:flex; gap:10px; align-items:center; margin-right:4px }
/* донат из четырёх цветов групп — тот же код цвета, что и на карточках */
.mark { width:22px; height:22px; border-radius:50%; flex:none; position:relative;
        background:conic-gradient(var(--new) 0 25%, var(--active) 0 50%, var(--at_risk) 0 75%, var(--lost) 0) }
.mark::after { content:""; position:absolute; inset:6px; border-radius:50%; background:var(--card) }
.brand h1 { font-size:15px; margin:0; font-weight:600; letter-spacing:-0.01em; line-height:1.2 }
.brand h1 span { color:var(--muted); font-weight:500 }
.brand .tag { font-size:11.5px; color:var(--muted); line-height:1.2 }
.tabs { display:flex; gap:2px; background:#eef0f3; padding:3px; border-radius:9px }
/* один бизнес — та же серая плашка, но одна выбранная вкладка и без курсора-руки: выбора нет */
#tabs { margin-left:28px }
.onlyb { font-size:13.5px; font-weight:500; padding:6px 13px; border-radius:7px; background:var(--card);
         box-shadow:0 1px 2px rgba(0,0,0,.1) }
.tabs button { border:0; background:none; padding:6px 13px; border-radius:7px; cursor:pointer; font:inherit; font-size:13.5px; color:var(--muted) }
.tabs button:hover { color:var(--ink) }
.tabs button.on { background:var(--card); color:var(--ink); font-weight:500; box-shadow:0 1px 2px rgba(0,0,0,.1) }
/* выключенный бизнес виден только администратору и только пока открыт — бледным */
.tabs button.off, .onlyb.off { color:#a9aab0 }
.asof { margin-left:auto; color:var(--muted); display:flex; gap:8px; align-items:center; font-size:13px }
input[type=date] { font:inherit; font-size:12.5px; padding:5px 8px; border:1px solid var(--line); border-radius:7px; background:var(--card) }
.today { font:inherit; font-size:12.5px; color:var(--muted); background:none; border:0; padding:5px 2px; cursor:pointer; text-decoration:underline dotted var(--line) 1px; text-underline-offset:3px }
.today:hover { color:var(--ink) }
.hrow .auth { padding-left:20px; border-left:1px solid var(--line); line-height:1.6 }
/* minmax(0,1fr), а не auto: иначе колонка сетки вырастает до min-content самой
   широкой таблицы, и на телефоне вся страница становится шире экрана */
main { padding:18px 20px; display:grid; grid-template-columns:minmax(0, 1fr); gap:16px; max-width:var(--col); margin:0 auto }
#app { display:grid; grid-template-columns:minmax(0, 1fr); gap:16px }
/* До входа на экране только эта карточка: показывать нечего, данные одного
   живого бизнеса мимо входа не отдаются. */
.card { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:14px 18px; min-width:0 }
.card h2 { font-size:13px; margin:0 0 4px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:0.04em }
.card h2 + .sub { color:var(--muted); font-size:12.5px; margin:0 0 12px }
/* экран входа: карточка по центру, заголовок обычным текстом, а не рубрикой */
.gate { max-width:380px; width:100%; margin:6vh auto 0 }
.gate h2 { font-size:17px; font-weight:600; color:var(--ink); text-transform:none; letter-spacing:-0.01em; margin-bottom:6px }
/* Подчёркивание у ссылок-вкладок — это нижняя рамка, а она идёт по радиусу
   кнопки: с общими 8px концы линии загибались вверх крючками. Почти прямой
   угол оставляет линию линией. */
.seg-btn { font:inherit; font-size:12.5px; color:var(--muted); background:none; border:0; border-bottom:1px solid transparent; border-radius:1px; padding:0 0 2px; margin-right:14px; cursor:pointer }
.seg-btn.on { color:var(--ink); border-bottom-color:var(--ink) }
/* Любой раздел — колонка блоков с одним общим зазором. Иначе карточки,
   стоящие просто друг под другом, слипаются, а внутренние сетки разделов
   расходятся каждая на свой отступ. */
.sec { display:grid; grid-template-columns:minmax(0,1fr); gap:14px; align-content:start }
.topstrip { display:flex; gap:12px 24px; align-items:baseline; flex-wrap:wrap; padding:0 4px }
.lead { font-size:15px; flex:1 1 460px; min-width:0; text-wrap:pretty }
.lead b { font-weight:600 }
.lead .second { color:var(--muted); font-size:13.5px; margin-top:3px }
.meta { color:var(--muted); font-size:12.5px; margin:7px 0 0; padding:0 4px }
/* сводка над разделом — две равные невысокие карточки */
.sumrow { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:10px }
.sumrow:has(#meta:empty) { grid-template-columns:minmax(0, 1fr) }
.sumrow:has(#meta:empty) > .sumbox:has(#meta) { display:none }
@media (max-width:760px){ .sumrow { grid-template-columns:minmax(0, 1fr) } }
.sumrow > .sumbox { padding:10px 14px; margin:0; display:flex; align-items:center }
.sumbox .lead, .sumbox .meta { margin:0; padding:0; flex:1 }
.sumbox .nw { white-space:nowrap }
@media (max-width:760px){ .sumbox .nw { white-space:normal } }
.sumbox .meta .m1 { font-size:15px; color:var(--ink) }
.sumbox .meta .m1 b { font-weight:600 }
.sumbox .meta .second { font-size:13.5px; margin-top:3px }
.sumbox .anrow { margin:0 !important }
.links { display:flex; gap:14px; margin-left:auto }
.linkbtn { font:inherit; font-size:13px; color:var(--muted); background:none; border:0; padding:0; cursor:pointer;
           text-decoration:underline dotted var(--line) 1px; text-underline-offset:3px }
.linkbtn:hover, .linkbtn.on { color:var(--ink) }
/* ---------- кнопки ---------- */
/* Одна база на всё приложение: обычная — светлая с рамкой, `.primary` —
   чернильная (главное действие на экране ровно одно), `.ghost` — без заливки,
   `.danger` — то, что нельзя отменить. Кнопки, которые по смыслу не кнопки
   (вкладки, чипы, строки списков), переопределяют базу своим классом. */
button { font:inherit; font-size:13px; line-height:1.35; cursor:pointer; padding:6px 13px; border-radius:8px;
         border:1px solid var(--line); background:var(--card); color:var(--ink) }
button:hover:not(:disabled) { border-color:#c6c8ce; background:#fafbfc }
/* выключенная кнопка должна читаться: подпись светлее обычной, но не исчезает */
button:disabled { color:#9b9da4; background:#f4f5f7; border-color:var(--line); cursor:default }
button.primary { background:var(--ink); border-color:var(--ink); color:#fff }
button.primary:hover:not(:disabled) { background:#000; border-color:#000 }
button.primary:disabled { background:#f4f5f7; border-color:var(--line); color:#9b9da4 }
button.ghost { background:none }
button.ghost:hover:not(:disabled) { background:#f4f5f7 }
button.danger { color:var(--lost); border-color:#e4c9c4 }
button.danger:hover:not(:disabled) { background:#fdf4f2; border-color:var(--lost) }
/* мелкая — в строках фильтров и в плотных панелях, где 13px уже спорят с полями */
button.small { font-size:12.5px; padding:5px 11px; border-radius:7px }
/* Выпадающие списки одинаковые везде: системный вид у них свой в каждой ОС и
   рядом с нашими кнопками смотрится чужим — рисуем рамку как у полей ввода,
   а галочку кладём фоном. */
select { font:inherit; font-size:13px; line-height:1.35; color:var(--ink); cursor:pointer; max-width:100%;
  padding:6px 28px 6px 10px; border:1px solid var(--line); border-radius:8px;
  background:var(--card) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b6b70' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 9px center / 10px 6px;
  appearance:none; -webkit-appearance:none }
select:hover { border-color:#c6c8ce }
select:disabled { color:#9b9da4; background-color:#f4f5f7; cursor:default }
/* Кольцо фокуса рисуем сами: браузерное — толстая скоба с большим радиусом,
   из-за неё подчёркнутая вкладка выглядит обведённой пузырём. Мышью кольца
   нет вовсе, с клавиатуры — тонкая рамка с еле заметным скруглением. */
button:focus, summary:focus { outline:none }
button:focus-visible, a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline:1.5px solid var(--ink); outline-offset:2px }
/* Кольцо повторяет скругление самой кнопки. У вкладок и ссылок-кнопок рамки
   нет вовсе, и восьмёрка радиуса превращала кольцо в пузырь, — им почти прямой
   угол. Кнопкам с рамкой радиус оставляем: там кольцо идёт по их же краю. */
.sect button:focus-visible, .linkbtn:focus-visible, .sub button:focus-visible {
  outline-offset:3px; border-radius:1px }
/* Панели — окна поверх дашборда: открытие не должно сдвигать вниз цифры,
   на которые человек в этот момент смотрит. Настройки встают слева, вход
   справа, на одном уровне; одновременно открыта только одна. */
/* затемнение намеренно слабое: настройки меняют отчёт на лету, и цифры под
   окном должны оставаться читаемыми — ради них настройки и открывают */
.veil { position:fixed; inset:0; z-index:11; background:rgba(28,28,30,.08) }
/* отступ сверху — высота шапки, её меряет fitPanels: на узком экране кнопки
   переносятся на вторую строку, шапка становится выше, и зашитые 62px увели бы
   первую строку окна под неё */
.panels { position:fixed; top:var(--panel-top,62px); left:0; right:0; z-index:12; display:flex; gap:16px;
          align-items:flex-start; max-width:var(--col); margin:0 auto; padding:0 20px; pointer-events:none }
.panel { display:none; position:relative; pointer-events:auto; max-height:calc(100vh - var(--panel-top,62px) - 20px); overflow:auto;
         box-shadow:0 16px 40px rgba(28,28,30,.18) }
.panel.on { display:block }
.panel .x { position:absolute; top:8px; right:10px; font:inherit; font-size:17px; line-height:1; color:var(--muted);
            background:none; border:0; padding:4px 7px; border-radius:6px; cursor:pointer }
.panel .x:hover { color:var(--ink); background:#f1f2f5 }
#p-help .help-body > p:first-child { padding-right:26px }
/* ширина задана, а не выведена из содержимого: внутри аккаунта короткие строки,
   и панель съёживалась до полоски в треть окна */
#p-auth { width:340px; flex:none; margin-left:auto }
#p-load { max-width:720px; margin-left:auto }
#p-help { max-width:820px; margin:0 auto }
/* Блочная форма, не grid: Safari и менеджеры паролей в сетке вписывают логин
   и пропускают пароль — поле для них «не то». Ширина 100%, иначе кнопка съёжится. */
.authform { margin-top:14px }
.authform label { display:block; margin:0 0 12px; font-size:12.5px; color:var(--muted) }
.authform label span { display:block; margin-bottom:4px }
.authform input { display:block; width:100%; font:inherit; font-size:13.5px; padding:7px 10px; border:1px solid var(--line); border-radius:7px; background:var(--card) }
.authform button { width:100%; font-size:13.5px; padding:8px 13px }
/* зазор как у .two: иначе промежутки между плитками и между графиками под ними не на одной линии */
.kpis { display:grid; grid-template-columns:repeat(6,1fr); gap:14px }
.kpi { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:12px 12px; cursor:pointer; border-top:4px solid var(--c); min-width:0 }
.kpi:hover { border-color:#c6c8ce; border-top-color:var(--c) }
/* выбранная группа подсвечивается своим цветом: чёрная рамка спорила с цветной
   полосой сверху и не говорила, какая именно группа выбрана */
.kpi.on { outline:2px solid var(--c); outline-offset:-1px; background:color-mix(in srgb, var(--c) 7%, var(--card)) }
.kpi.on .d { border-top-color:color-mix(in srgb, var(--c) 22%, var(--line)) }
.kpi .n { font-size:24px; font-weight:600; line-height:1.2; letter-spacing:-0.02em }
.kpi .l { color:var(--muted); font-size:13px; font-weight:500; white-space:nowrap }
.kpi .s { font-size:12.5px; color:var(--muted); margin-top:2px; white-space:nowrap }  /* одна строка: доля · деньги */
.kpi .d { font-size:12.5px; margin-top:8px; padding-top:8px; border-top:1px solid var(--line); color:var(--ink) }
/* графики внутри карточек не упираются в её край: справа остаётся поле */
.bars { display:grid; gap:10px; padding-right:8px }
.bar { display:grid; grid-template-columns:130px 1fr 80px; align-items:center; gap:10px; font-size:13px }
.bar .track { height:18px; background:#eef0f3; border-radius:4px; overflow:hidden }
.bar .fill { height:100%; background:var(--c); border-radius:4px; transition:width .3s }
.bar .v { text-align:right; color:var(--muted) }
.bar.dim { opacity:.35 }   /* выбрана одна группа: остальные видны, но не спорят с ней */
.two { display:grid; grid-template-columns:1fr 1fr; gap:14px }
[hidden] { display:none !important }   /* иначе display из класса перебивает атрибут */
/* карточки в ряду равной высоты: пояснения прижаты к низу и стоят на одной линии, гистограмма растягивается */
.two > .card { display:flex; flex-direction:column }
.two > .card .hint { margin-top:auto; padding-top:10px }
.hist { display:flex; align-items:flex-end; gap:2px; flex:1; min-height:120px; border-bottom:1px solid var(--line); padding:0 8px 2px }
.hist div { flex:1; background:var(--c); min-height:1px; border-radius:2px 2px 0 0 }
.hist-x { display:flex; justify-content:space-between; color:var(--muted); font-size:11px; margin-top:4px; padding:0 8px }
/* min-width: на узком экране лучше горизонтальный скролл обёртки, чем обрезанные заголовки */
table { width:100%; min-width:880px; border-collapse:collapse; font-size:12.5px; table-layout:fixed }
th, td { text-align:left; padding:5px 6px; border-bottom:1px solid var(--line); white-space:nowrap }
/* Длинное название услуги иначе наползает на соседний столбец: при
   table-layout:fixed ячейка не расширяется, а текст из неё просто вылезает. */
td { overflow:hidden; text-overflow:ellipsis }
th { color:var(--muted); font-weight:500; font-size:11.5px; cursor:pointer; user-select:none; position:sticky; top:0; z-index:1;
     background:var(--card); vertical-align:bottom; white-space:pre-line; line-height:1.25 }
/* collapse режет фон липкой шапки, и строка под ней просвечивает.
   separate с нулевым зазором рисует те же линии, но фон шапки сплошной. */
.tbl-wrap table { border-collapse:separate; border-spacing:0 }
.tbl-wrap th { background:var(--card); box-shadow:0 1px 0 var(--card) }
/* Шапка таблицы непрозрачная: строка под ней не просвечивает. Где крутится не
   сама таблица, а карточка вокруг, шапку не приклеиваем — иначе она встаёт
   посреди строк. */
.client .visits th, .preview th, .ptbl.prev .pdetail th { position:static; z-index:auto }
/* Колонка со значками: подпись словом («сценарий», «звонить») занимала места
   втрое больше самих значков. Буква в кружке, полное имя — в подсказке. */
.hbadge { display:inline-block; width:17px; height:17px; border-radius:50%; border:1px solid var(--line);
  font-size:10.5px; line-height:15px; text-align:center; font-weight:600; letter-spacing:0 }
/* Где есть подсказка, это видно: точечное подчёркивание у слов и цифр, маленький
   знак у заголовков. Иначе о том, что приложение умеет объяснить себя, никто не узнает. */
th[data-tip], .kpi .s[data-tip], .meta span[data-tip], .lead b[data-tip], .lname[data-tip], .bizcard .f > span[data-tip],
.sub span[data-tip], .hint span[data-tip], .planbar span[data-tip], .rhead span[data-tip], .client .nums .n[data-tip] span,
.client .code[data-tip], .client .tplmeta .len[data-tip], .tplrow .n[data-tip], .pinline[data-tip], .f > span[data-tip],
.genbar .gencard .len[data-tip], .cnt[data-tip], .fine span[data-tip], .an-head .hint[data-tip], .tplmeta .len[data-tip] {
  text-decoration:underline dotted #c4c6cc 1px; text-underline-offset:3px }
h2[data-tip]::after, h3[data-tip]::after, h4[data-tip]::after, summary[data-tip]::after {
  content:"i"; display:inline-block; margin-left:7px; width:14px; height:14px; border-radius:50%; border:1px solid #c4c6cc;
  color:var(--muted); font:italic 600 10px/13px Georgia,serif; text-align:center; vertical-align:2px }
td.hash { font-family:ui-monospace,"SF Mono",Menlo,monospace; font-size:12px; color:var(--muted) }
th.sorted::after { content:" ▾" }
th.sorted.asc::after { content:" ▴" }
td.num, th.num { text-align:right }
td.late { color:var(--lost) }
td.ontime { color:var(--muted) }
.pill { display:inline-block; padding:1px 7px; border-radius:10px; font-size:11px; color:#fff; background:var(--c) }
/* мягкая плашка вместо заливки: фон и текст выводятся из того же цвета группы.
   Где color-mix не поддерживается, остаётся строка выше — белым по цвету */
.pill { background:color-mix(in oklab, var(--c) 15%, #fff); color:color-mix(in oklab, var(--c) 78%, #000) }
.tbl-wrap { max-height:min(62vh, 760px); overflow:auto }
/* «Клиенты»: высота таблицы — остаток окна (её пишет fill.js в --tbl-room).
   Иначе предел 62vh плюс шапка выше экрана, и крутятся и страница, и таблица. */
#sec-clients .tbl-wrap { max-height:var(--tbl-room, min(62vh, 760px)) }
/* Уже 1180 лучше горизонтальная прокрутка обёртки: это сумма пиксельных
   столбцов (услуга целиком, дата и деньги целиком) плюс хотя бы 90 на пометку. */
#tbl { min-width:1180px }
/* у трёх узких столбцов шапка шире содержимого — поля ей тоньше, чтобы
   столбцы не раздувались ради подписи */
/* сумма прижата вправо, услуга — влево: без зазора они читаются одной строкой */
#tbl th[data-k=last_service], #tbl td.svc { padding-left:18px }
#tbl th[data-k=streak], #tbl th[data-k=scen], #tbl th[data-k=past], #tbl th[data-k=no_call], #tbl td.scen, #tbl td.past { padding-left:3px; padding-right:3px }

/* ---------- раздел «Клиенты»: вкладки групп, фильтры, массовые действия ---------- */
/* Вкладки групп — они же сводка: людей и деньги за год всегда перед глазами,
   за этим не нужно уходить в «Обзор». Цветная полоска сверху — цвет группы. */
.segtabs { display:flex; gap:14px; flex-wrap:wrap }
/* Семь вкладок в ряд: доли равные (flex-basis 0), текст в одну строку с
   многоточием — иначе у длинных названий ряд становится разной высоты. */
.segtabs button { text-align:left; flex:1 1 0; min-width:116px; padding:6px 10px 7px;
  border-top:4px solid var(--c); border-radius:8px }
.segtabs button b, .segtabs button span { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.segtabs button b { font-size:13px; font-weight:600 }
.segtabs button span { font-size:11.5px; color:var(--muted) }
.segtabs button span i { font-style:normal }
.segtabs button span i + i::before { content:" · " }
.segtabs button.on { border-color:var(--c); box-shadow:0 0 0 1px var(--c) inset;
  background:color-mix(in srgb, var(--c) 7%, var(--card)) }
.segtabs button:hover { background:#fafbfc }
.filters { display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-bottom:8px }
.filters .q { flex:1 1 220px; min-width:160px; font:inherit; font-size:12.5px; padding:5px 10px;
  border:1px solid var(--line); border-radius:7px; background:var(--card) }
.filters .q:focus { outline:2px solid var(--ink); outline-offset:-1px }
.flt { position:relative }
.flt > summary { cursor:pointer; user-select:none; list-style:none; font-size:12.5px; padding:5px 10px;
  border:1px solid var(--line); border-radius:7px; background:var(--card); white-space:nowrap }
.flt > summary::-webkit-details-marker { display:none }
.flt > summary::after { content:" ▾"; color:var(--muted) }
.flt > summary b { display:inline-block; margin-left:5px; padding:0 5px; border-radius:8px; font-size:11px;
  background:var(--ink); color:#fff }
.flt[open] > summary { border-color:var(--ink) }
/* Меню поверх таблицы: список может быть длинным (услуг у зала два десятка) */
.flt .menu { position:absolute; z-index:40; top:calc(100% + 4px); left:0; min-width:230px; max-height:320px; overflow:auto;
  background:var(--card); border:1px solid var(--line); border-radius:9px; padding:4px; box-shadow:0 10px 26px rgba(0,0,0,.14) }
.flt .menu label { display:flex; align-items:center; gap:7px; padding:4px 7px; border-radius:6px; font-size:12.5px; cursor:pointer }
.flt .menu label:hover { background:#f3f4f6 }
.flt .menu label span { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.flt .menu label i { font-style:normal; color:var(--muted); font-size:11.5px }
.flt .menu .empty, .mass .empty { color:var(--muted); font-size:12.5px; padding:6px 8px }

.chips { display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-bottom:8px }
.chips:empty { display:none }
.chip { font:inherit; font-size:12px; cursor:pointer; padding:3px 8px; border-radius:12px;
  border:1px solid var(--line); background:#f3f4f6; color:var(--ink) }
.chip span { color:var(--muted); margin-left:5px }
.chip:hover span { color:var(--lost) }

/* Полоса плана над таблицей: слева то, что уже в работе у бизнеса, справа
   черновик, который мы собираем. Два состояния рядом — потому что они и
   живут рядом: прошлый план ещё исполняется, следующий уже набирается. */
.planbar { display:flex; gap:10px 16px; align-items:center; flex-wrap:wrap;
  padding:8px 12px; background:var(--card); border:1px solid var(--line); border-radius:9px;
  font-size:12.5px }
.planbar .pstate { display:flex; gap:8px; align-items:center; flex-wrap:wrap }
.planbar .pstate.on:not(:last-child) { padding-right:16px; border-right:1px solid var(--line) }
.planbar .pstate + .pstate { margin-left:auto }
.planbar .warn, .planbar .muted { font-style:normal; font-size:12px }
.planbar .muted { color:var(--muted) }
.planbar a { color:var(--ink); text-decoration:underline dotted; text-underline-offset:3px }

/* Панель массовых действий: появляется, когда отмечен хоть кто-то */
.bulk { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:8px; padding:7px 10px;
  background:#f1f3f6; border:1px solid var(--line); border-radius:8px; font-size:12.5px }
.bulk .linkbtn { margin-left:auto }

th.pick, td.pick { text-align:center; padding:0 }
td.pick input, th.pick input { cursor:pointer }
tr.picked td { background:#eef2fb }
tr.off td { opacity:.55 }           /* «не звонить»: строка видна, но тушится */
/* Значки каналов — рисованные (см. ICON в app.js): конверт и трубка из шрифта
   разного размера и в каждой системе свои. */
.ico { width:15px; height:15px; vertical-align:-3px; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round }
.ico .slash { stroke-width:2 }
td.scen .ico { margin:0 4px; color:var(--muted) }
td.scen .ico.gap { display:inline-block }  /* пустое место канала: столбец не пляшет */
td.scen .ico.on { color:var(--active) }    /* зелёный — уже сделано */
td.scen .ico.soon { opacity:.6; stroke-dasharray:2.4 2 }   /* пунктир — наш черновик, а не задача бизнеса */
/* «П» — прошлые планы: значки мельче и плотнее, последние справа */
td.past { text-align:center; white-space:nowrap; overflow:hidden }
td.past .ico { width:13px; height:13px; margin:0 1.5px; color:#9a9da4 }
td.past .ico.good { color:var(--active) }
td.past .ico.bad { color:var(--lost) }
td.past .more { font-size:10.5px; color:var(--muted); margin-right:2px; vertical-align:1px }
td.call { cursor:pointer; user-select:none }
/* Перечёркнутая трубка — «не звонить»; жёлтая — владелец передал просьбу
   не беспокоить, а решение ещё за нами. */
td.call .ico { color:var(--ink) }
td.call .ico.off { color:var(--lost) }
td.call .ico.asked { color:var(--at_risk) }
/* столбцы со значками и галочками: содержимое и шапка по центру столбца */
th.mid, td.mid, td.scen, td.call { text-align:center }
td.note { overflow:hidden; text-overflow:ellipsis }
.pill.warn { background:color-mix(in oklab, var(--at_risk) 18%, #fff); color:color-mix(in oklab, var(--at_risk) 80%, #000); margin-left:5px }
/* Окно массового назначения */
dialog.mass { width:min(94vw, 900px); max-height:88vh; overflow:auto; padding:0; border:1px solid var(--line);
  border-radius:12px; box-shadow:0 20px 60px rgba(0,0,0,.26); color:var(--ink) }
dialog.mass::backdrop { background:rgba(28,28,30,.42) }
.mass .head { display:flex; align-items:center; padding:12px 16px; border-bottom:1px solid var(--line) }
.mass .head h2 { margin:0; font-size:15px }
.mass .head .x { margin-left:auto; font:inherit; font-size:19px; line-height:1; cursor:pointer; border:0; background:none; color:var(--muted) }
.mass > p { margin:10px 16px 0; font-size:12.5px }
.mass p.warn { color:color-mix(in oklab, var(--at_risk) 85%, #000) }
.mass .two { display:grid; grid-template-columns:1fr 1fr; gap:14px; padding:12px 16px }
.mass h3 { margin:0 0 6px; font-size:12.5px; color:var(--muted); font-weight:600 }
.mass .tpl { display:flex; gap:8px; align-items:flex-start; padding:6px 8px; border-radius:7px; cursor:pointer }
.mass .tpl:hover { background:#f5f6f8 }
.mass .tpl b { font-size:12.5px; font-weight:600 }
.mass .tpl p { margin:2px 0 0; font-size:12px; color:var(--muted); line-height:1.35 }
.mass .tpl.none { border-bottom:1px solid var(--line); border-radius:0; padding-bottom:8px; margin-bottom:4px }
.mass .note { display:block; padding:0 16px; font-size:12.5px; color:var(--muted) }
.mass .note input { display:block; width:100%; box-sizing:border-box; margin-top:4px; font:inherit; font-size:13px;
  padding:6px 9px; border:1px solid var(--line); border-radius:7px }
.mass .row { display:flex; gap:8px; align-items:center; justify-content:flex-end; padding:14px 16px }
.mass .row .err { margin-right:auto; color:var(--lost); font-size:12.5px }

/* ---------- раздел «Шаблоны» ---------- */
/* Редактор шире пула: в нём три поля в строку и шесть групп в строку, а
   списку хватает названия и куска текста. Высота у колонок общая: stretch,
   а список внутри пула прокручивается. */
.tpl-two { display:grid; grid-template-columns:minmax(280px, 2fr) minmax(420px, 3fr); gap:16px; align-items:stretch }
#tpl-list { display:flex; flex-direction:column }
#tpl-list .tplfilters { flex:none }
/* возражения и заметки — друг под другом: у возражений четыре колонки
   текста, у заметок шесть полей, и в половину ширины оба блока мнутся */
.obj-two { display:grid; grid-template-columns:minmax(0, 1fr); gap:14px }
@media (max-width: 900px) { .tpl-two { grid-template-columns:minmax(0, 1fr) } }
.obj-two .card { display:flex; flex-direction:column }
.obj-two .card .row { margin-top:auto; padding-top:10px }
.vals-grid { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:10px 8px; margin:10px 0 }
@media (max-width:1000px){ .vals-grid { grid-auto-flow:row; grid-template-columns:repeat(auto-fill, minmax(160px, 1fr)) } }
/* имя скобки — строкой над полем: в колонке 62px «[проба_цена]» не помещалось */
.vals-grid label { display:block; font-size:12.5px; min-width:0 }
.vals-grid label > span { display:block; margin-bottom:3px; color:var(--muted);
  font-family:ui-monospace,Menlo,monospace; font-size:11.5px }
.vals-grid input { width:100%; box-sizing:border-box; font:inherit; font-size:12.5px; padding:5px 8px;
  border:1px solid var(--line); border-radius:7px; min-width:0 }
.vals-grid label.need input { border-color:var(--at_risk); background:#fffaf1 }
.vals-grid label.done > span { color:var(--ink) }
.objedit { table-layout:auto; min-width:0; margin-top:6px }
.objedit th { position:static; font-size:11.5px; cursor:default }
.objedit td { white-space:normal; vertical-align:top; padding:4px 4px }
.objedit textarea, .segnote textarea { width:100%; box-sizing:border-box; font:inherit; font-size:12.5px;
  padding:5px 7px; border:1px solid var(--line); border-radius:7px; resize:vertical; line-height:1.35 }
/* шесть групп в два столбца: по одной на строку блок вытягивался на пол-экрана */
.notes-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px 16px; margin-top:4px }
.segnote { display:grid; gap:4px; align-content:start;
  border-left:3px solid var(--c); padding-left:8px }
.segnote > span { font-size:12.5px }
@media (max-width:760px){ .notes-grid { grid-template-columns:1fr } }
/* блок генерации: строка управления и карточки вариантов */
.genbar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:10px 0 }
.genbar input { flex:1 1 220px; min-width:160px; font:inherit; font-size:12.5px; padding:6px 10px;
  border:1px solid var(--line); border-radius:7px; background:var(--card); color:var(--ink) }
.genbar .pick-btn[data-gs].on { box-shadow:inset 0 -2px 0 var(--c), 0 1px 2px rgba(0,0,0,.1) }
/* auto-fit, а не auto-fill: двум вариантам незачем жаться слева, оставляя
   полкарточки пустого места — пустые колонки сетка схлопывает */
/* пустое состояние генерации — поле с запасом снизу, а не строка у самого края */
.genempty { display:grid; place-items:center; min-height:56px; margin:8px 0 0; padding:10px 14px;
  border:1px dashed var(--line); border-radius:10px; color:var(--muted); font-size:12.5px; text-align:center }
.gengrid { display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:12px; margin:10px 0 }
.gencard { display:flex; flex-direction:column; gap:6px; border:1px solid var(--line);
  border-radius:10px; padding:10px 12px; background:var(--card) }
.gencard b { font-size:12.5px }
.gencard .gentext { font-size:13px; line-height:1.4; white-space:pre-wrap }
.gencard .len { font-size:12px; color:var(--muted) }
.gencard .len.over { color:var(--lost) }
/* «почему это сработает» — словами модели, оттого и серым: это не наш текст */
.gencard .why { font-size:12px; color:var(--muted); font-style:italic }
.gencard .pinline { font-size:12px; color:var(--muted); display:flex; gap:6px; align-items:center }
.gencard .row { margin-top:auto; padding-top:4px }
.gencard .genopts { display:flex; gap:8px; align-items:center; justify-content:space-between }
.gencard .genopts .pick-btn { padding:2px 9px; font-size:12px }
.gencard .segpick.short .seg { padding-left:4px; padding-right:4px }
.segpick.small .seg { font-size:11.5px; padding:2px 6px }
/* что нашла шлифовка — под кнопками редактора, правку подставляет человек */
.polished { margin-top:10px; padding:10px 12px; border:1px solid var(--line); border-radius:9px;
  background:#f8f9fb; font-size:12.5px }
.polished.ok { color:var(--active) }
.polished > b { display:block; margin-top:12px } .polished > b:first-child { margin-top:0 }
.polished ul { margin:4px 0 0; padding-left:18px; line-height:1.45 }
.polished .gentext { margin:3px 0 0; font-size:13px; line-height:1.45; white-space:pre-wrap }
.polished .row { margin-top:14px }
.genbad { margin-top:6px; font-size:12.5px; color:var(--muted) }
.genbad > summary { cursor:pointer }
.genbad .badrow { display:grid; gap:2px; margin:8px 0; padding-left:10px; border-left:2px solid var(--line) }
.genbad .badrow small { color:var(--muted); font-size:12px }
.tplrow .ai { font-style:normal; font-size:10px; font-weight:600; color:var(--muted);
  border:1px solid var(--line); border-radius:5px; padding:0 3px; vertical-align:1px }
.tplrow .pr { display:inline-grid; place-items:center; width:16px; height:16px; margin-right:6px; border-radius:4px;
  font-style:normal; font-size:10px; font-weight:700; vertical-align:1px; border:1px solid var(--line); color:var(--muted) }
.tplrow .pr-A { background:var(--ink); border-color:var(--ink); color:#fff }
.tplrow .pr-C { border-style:dashed }
#tpl-edit .state { font-size:12.5px; color:var(--muted); margin-left:auto }
/* Отбор в пуле в две строки: канал, приоритет и «добавить» сверху, группа,
   состояние и поиск под ними. Освободившаяся строка ушла списку шаблонов. */
.tplfilters { display:grid; gap:10px; margin:8px 0 14px }
.tplfilters .line { display:flex; gap:8px; align-items:center; flex-wrap:wrap }
/* канал нового шаблона — в строке заголовка: у нового и у открытого шаблона редактор одной высоты */
.tplhead { display:flex; align-items:center; justify-content:space-between; gap:8px; height:30px }
.tplhead h2 { margin:0 }
.tplfilters .prio-pick .pick-btn { min-width:30px; padding:4px 8px; text-align:center }
.tplfilters .pair { display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,2fr); gap:6px }
.starchk { display:grid; place-items:center; width:32px; border:1px solid var(--line); border-radius:8px;
  color:#c4c8cf; font-size:15px; cursor:pointer; background:var(--card) }
.starchk:hover { color:var(--muted) }
.starchk.on { color:#e0a100; border-color:#e8c766; background:#fdf6e0 }
.starchk input { position:absolute; width:0; height:0; opacity:0 }
.starchk:has(input:focus-visible) { outline:1.5px solid var(--ink); outline-offset:2px }
.tplfilters select, .tplfilters input { font:inherit; font-size:12.5px; padding:5px 10px;
  border:1px solid var(--line); border-radius:7px; background-color:var(--card); color:var(--ink); min-width:0 }
.tplfilters select { padding-right:26px; background-size:9px 5px }
.tplfilters input { width:100% }
/* канал — одна переключалка на три положения, а не три отдельные кнопки */
.pickgroup { display:inline-flex; flex-wrap:wrap; max-width:100%; background:#eef0f3; padding:2px; border-radius:8px; gap:2px }
.pickgroup .pick-btn { font-size:12.5px; padding:4px 10px; border:0; border-radius:6px; background:none; color:var(--muted) }
.pickgroup .pick-btn:hover:not(.on) { color:var(--ink); background:none }
.pickgroup .pick-btn.on { background:var(--card); color:var(--ink); font-weight:500; box-shadow:0 1px 2px rgba(0,0,0,.1) }
.tplfilters #tpl-new { margin-left:auto; flex:none }
/* Высоту ряду задаёт редактор, список дотягивается до неё и прокручивается внутри */
.tpllist { display:grid; gap:4px; align-content:start; flex:1 1 0; min-height:140px; overflow:auto }
.tplrow { display:grid; grid-template-columns:1fr auto; gap:4px 8px; text-align:left; font:inherit; cursor:pointer;
  padding:7px 9px; border:1px solid var(--line); border-radius:8px; background:var(--card) }
.tplrow:hover { background:#fafbfc }
.tplrow.on { border-color:var(--ink); box-shadow:0 0 0 1px var(--ink) inset }
.tplrow b { font-size:12.5px; font-weight:600 }
.tplrow small { grid-column:1 / -1; font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.tplrow .segs { display:flex; gap:3px; align-items:center }
.tplrow .dot { width:8px; height:8px; border-radius:50%; background:var(--c); display:inline-block }
.tplrow .n { font-size:11px; color:var(--muted); margin-left:3px }
#tpl-edit .f { display:block; margin-top:8px; font-size:12.5px; min-width:0 }
/* мелкие поля в две-три колонки: в один столбец редактор был наполовину пустым */
/* «как отвечать», «когда уместно», «приоритет» — одной строкой: по
   отдельной строке на поле редактор выходил вдвое длиннее, чем нужно */
#tpl-edit .fgrid { display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:0 12px }
/* у SMS «как отвечать» и «когда уместно» делят ширину, приоритету — сколько нужно трём кнопкам */
#tpl-edit .fgrid.sms { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr) auto }
#tpl-edit .f > span { display:block; color:var(--muted); margin-bottom:3px }
#tpl-edit .f input:not([type=checkbox]), #tpl-edit .f textarea { width:100%; box-sizing:border-box; font:inherit; font-size:13px;
  padding:6px 9px; border:1px solid var(--line); border-radius:7px; resize:vertical; line-height:1.4 }
#tpl-edit .f > span.withlen { display:flex; justify-content:space-between; align-items:baseline; gap:8px }
#tpl-edit .tplmeta { display:flex; gap:8px 16px; align-items:flex-start; justify-content:space-between; margin-top:6px }
#tpl-edit .tplnote .hint { display:block; margin-top:0; line-height:1.25 }
/* подстановки — кнопками: клик ставит скобку в текст, а не заставляет её набирать.
   Подпись слева, чипы справа ровно в две строки. Счётчик SMS — в строке «текст SMS». */
.slots { display:flex; flex-wrap:wrap; gap:4px }
#tpl-edit .slots { display:grid; grid-template-columns:repeat(var(--cols, 7), max-content); gap:4px; justify-content:end; margin-left:auto }
#tpl-edit .tplnote { flex:none; line-height:1 }
#tpl-gen.filled { display:flex; flex-direction:column }
#tpl-gen.filled > * { flex:none }
#tpl-gen.filled > .genempty { flex:1 1 auto }
.slots .slot { font:inherit; font-size:11.5px; font-family:ui-monospace,Menlo,monospace; color:var(--muted);
  padding:2px 6px; border:1px solid var(--line); border-radius:6px; background:var(--card); cursor:pointer }
.slots .slot:hover { color:var(--ink); border-color:#c6c8ce; background:#fafbfc }
/* приоритет — переключатель из трёх положений, выбрать можно только одно */
.prio { display:flex; gap:6px }
.prio label { display:inline-flex; gap:5px; align-items:center; cursor:pointer; font-size:12.5px;
  padding:4px 9px; border:1px solid var(--line); border-radius:7px; background:var(--card) }
.prio label.on { background:#f1f2f5 }
.prio input { margin:0 }
#tpl-edit .len { font-size:12px; color:var(--muted) }
#tpl-edit .len.over { color:var(--lost) }
#tpl-edit .tag { font-size:11px; color:var(--muted); font-weight:400 }
/* Шесть групп — шесть чипов по ширине текста, а не сетка из равных клеток:
   в клетках названия переносились и звёздочка липла к краю. */
.segpick { display:flex; flex-wrap:wrap; gap:6px; margin-top:2px }
.segpick .seg { display:inline-flex; flex:none; gap:6px; align-items:center; font-size:12.5px; cursor:pointer;
  white-space:nowrap; border:1px solid var(--line); border-left:3px solid var(--c); border-radius:8px; padding:4px 8px }
.segpick .seg:hover { border-color:#c6c8ce; border-left-color:var(--c) }
.segpick .seg.on { background:color-mix(in oklab, var(--c) 8%, #fff) }
.segpick .seg input { margin:0; flex:none }
/* Галочку в редакторе убираем совсем — выбранная группа видна заливкой,
   зато шесть чипов укладываются в одну строку. */
/* Чипы групп занимают всю строку поровну — и в редакторе, и у придуманных
   нейросетью вариантов они одного размера. В узком окне ужимаются с
   многоточием, а не растягивают карточку. */
#tpl-edit .segpick, .gencard .segpick { display:flex; flex-wrap:nowrap; gap:5px; min-width:0 }
#tpl-edit .segpick .seg, .gencard .segpick .seg { font-size:12px; padding:5px 8px; gap:5px;
  justify-content:center; flex:1 1 auto; min-width:0 }
#tpl-edit .segpick .seg > span, .gencard .segpick .seg > span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
/* звезда только у выбранных групп: у остальных она всё равно не нажимается,
   а места занимает столько, что названия уходят под многоточие */
#tpl-edit .segpick .seg:not(.on) .pin { display:none }
.gencard .segpick .seg input, #tpl-edit .segpick .seg input { position:absolute; width:0; height:0; opacity:0 }
.gencard .segpick .seg.on { border-color:var(--c); font-weight:500 }
#tpl-edit .segpick .seg input { position:absolute; width:0; height:0; opacity:0 }
#tpl-edit .segpick .seg.on { border-color:var(--c); font-weight:500 }
#tpl-edit .segpick .seg:has(input:focus-visible) { outline:1.5px solid var(--ink); outline-offset:2px }
.segpick .pin { font:inherit; font-size:13px; line-height:1; cursor:pointer; border:0; background:none; color:#d2d4d9; padding:0 }
.segpick .pin:hover:not(:disabled) { background:none; color:var(--at_risk) }
.segpick .pin.on { color:var(--at_risk) }
.segpick .pin:disabled { opacity:.3; cursor:default }
#tpl-values .row, #tpl-edit .row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:12px }

/* ---------- окно клиента ---------- */
/* Две колонки: слева профиль (кто это и как ходит), справа сценарий (что с
   ним делать). На телефоне колонки встают друг под друга, и первым идёт
   сценарий: владелец открывает окно, чтобы позвонить, а не изучать графики. */
dialog.client { width:min(96vw, 980px); max-height:92vh; padding:0; border:1px solid var(--line);
  border-radius:14px; box-shadow:0 24px 70px rgba(0,0,0,.3); color:var(--ink); overflow:hidden }
dialog.client::backdrop { background:rgba(28,28,30,.45) }
.client .head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:11px 16px;
  border-bottom:1px solid var(--line); background:#fafbfc }
.client .head .who { font-size:14px }
.client .head .tel { font-size:14px; color:var(--ink); text-decoration:none; border-bottom:1px dashed var(--line) }
.client .head .code { font-family:ui-monospace,"SF Mono",Menlo,monospace; font-size:12px; color:var(--muted) }
.client .head .nav { margin-left:auto; display:flex; gap:6px; align-items:center }
.client .head .x { font-size:19px; line-height:1; border:0; background:none; color:var(--muted); cursor:pointer; padding:0 4px }
.client button.ghost { font-size:12.5px; padding:4px 10px; border-radius:7px }
.client .body { display:grid; grid-template-columns:1fr 1fr; grid-template-rows:minmax(0,1fr); gap:0;
  overflow:hidden; max-height:calc(92vh - 56px) }
.client .col { padding:14px 16px; overflow:auto; min-height:0 }
.client .col.scen { border-left:1px solid var(--line); background:#fcfcfd }
.client h3 { margin:0 0 10px; font-size:13px; color:var(--muted); font-weight:600 }
.client h4 { margin:14px 0 6px; font-size:12.5px; font-weight:600 }
.client .nums { display:grid; grid-template-columns:1fr 1fr; gap:8px 14px }
.client .nums .n { display:flex; justify-content:space-between; gap:8px; font-size:12.5px;
  border-bottom:1px solid var(--line); padding-bottom:4px }
.client .nums .n span { color:var(--muted) }
.client .bars.mini { gap:5px; margin-bottom:6px }
.client .col .sub { font-size:11.5px; color:var(--muted); margin:6px 0 3px }
.client .bars.mini .bar { grid-template-columns:96px 1fr 34px; font-size:12px }
.client .bars.mini .track { height:12px }
.client .visits { margin-top:14px }
.client .visits > summary { cursor:pointer; font-size:12.5px; color:var(--muted) }
.client .visits table { min-width:0; margin-top:8px }
.client .visits th, .client .visits td { padding:3px 6px; font-size:12px }
/* дата, время, тренер и сумма — по содержимому, услуге — всё остальное */
.client .visits table { table-layout:auto }
.client .visits th, .client .visits td { width:1%; white-space:nowrap }
.client .visits th:nth-child(3), .client .visits td:nth-child(3) { width:auto; max-width:0; overflow:hidden; text-overflow:ellipsis }
/* выбор шаблона: тот же вид, что в массовом назначении — рука помнит одно место */
.client .two { display:grid; grid-template-columns:1fr; gap:4px }
.client .tpl { display:flex; gap:8px; align-items:flex-start; padding:5px 7px; border-radius:7px; cursor:pointer }
.client .tpl:hover { background:#f2f3f5 }
.client .tpl b { font-size:12.5px }
.client .tpl p { margin:2px 0 0; font-size:12px; color:var(--muted); line-height:1.35 }
.client .tpl i { font-size:11px; color:var(--muted) }
.client .tpl > div { flex:1; min-width:0 }
.client .tpl .tpl-top { display:flex; gap:8px; align-items:baseline; justify-content:space-between }
.client .tpl .tpl-top i { flex:none; font-style:normal; font-variant-numeric:tabular-nums }
.client .tpl em { font-style:normal; background:#fdf2dc; border-radius:3px; padding:0 2px }
/* шаблон у человека уже был: не запрет, а напоминание — в архив он от этого не уходит */
.had { display:inline-block; font-size:11px; font-weight:500; line-height:1.4; color:#8a5a12; background:#fdf2dc;
  border-radius:5px; padding:0 6px; margin-left:4px; vertical-align:1px; white-space:nowrap; cursor:default }
.had.sms { color:#b3261e; background:#fde4e1 }
.client .tpl.none { border-bottom:1px solid var(--line); border-radius:0; margin-bottom:4px; padding-bottom:7px }
.client .note { display:block; margin-top:10px; font-size:12.5px; color:var(--muted) }
.client .note input, .client .outcome input[type=text], .client .outcome input:not([type]) {
  display:block; width:100%; box-sizing:border-box; margin-top:4px; font:inherit; font-size:13px;
  padding:6px 9px; border:1px solid var(--line); border-radius:7px }
.client .row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:10px }
.client .row button.ghost { padding:5px 11px }
.client .row .done { font-size:12.5px; color:var(--active) }
/* ссылка sms:/tel: выглядит той же кнопкой, что и соседние */
a.btn { display:inline-flex; align-items:center; justify-content:center; font-size:13px; line-height:1.35; padding:6px 13px;
  border-radius:8px; border:1px solid var(--line); background:var(--card); color:var(--ink); text-decoration:none }
a.btn.primary { background:var(--ink); border-color:var(--ink); color:#fff }
.client .row button.on { border-color:var(--ink); box-shadow:0 0 0 1px var(--ink) inset }
.client .qrbox { display:flex; gap:14px; align-items:center; margin-top:10px; padding:10px; border:1px solid var(--line); border-radius:9px; background:#fff }
.client .qrbox .qr { flex:none; width:180px; height:180px; display:grid; place-items:center; font-size:12px; color:var(--muted) }
.client .qrbox .qr svg { width:100%; height:100%; display:block }
.client .qrbox .hint { margin:0; font-size:12.5px }
.client .row .hint { margin:0 }
/* карточка дела у владельца: текст виден целиком, кнопки крупные */
.client .todo-card { border:1px solid var(--line); border-radius:9px; background:var(--card); padding:10px 12px; margin-bottom:10px }
.client .todo-card h4 { margin:0 0 6px }
.client .todo-card .todo-h { display:flex; align-items:center; gap:6px }
.client .todo-card .todo-h #c-copy { margin-left:auto; flex:none }
.client .todo-card .text { margin:0; font-size:13px; line-height:1.45; white-space:pre-wrap }
.client .obj { margin-top:8px }
.client .obj > summary { cursor:pointer; font-size:12.5px; color:var(--muted) }
.client .outcome { margin-top:10px; display:grid; gap:4px; border-top:1px solid var(--line); padding-top:8px }
.client .outcome label { display:flex; gap:7px; align-items:center; font-size:12.5px; cursor:pointer }
.client .outcome .out-act { display:flex; gap:8px; margin-top:6px }
/* второй вариант и отказ — мелко, в той же строке справа от кнопок: это не
   основное действие, но и прятать его в меню нельзя */
.client .altrow { display:flex; gap:10px; align-items:center; flex:1; min-width:0; justify-content:flex-end;
  font-size:12px; color:var(--muted) }
.client .altrow > span { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.client .altrow button { flex:none }
.client .altrow .alt-no { color:var(--lost) }
.client .altrow .alt-take { font-size:15px; line-height:1; text-decoration:none; color:var(--ink) }
.client .declineform { display:grid; gap:4px; margin:10px 0; padding:10px 12px;
  border:1px solid var(--at_risk); border-radius:9px; background:#fffaf1; font-size:12.5px }
.client .declineform h4 { margin:0 0 2px }
.client .declineform label { display:flex; gap:7px; align-items:center; cursor:pointer }
.client .declineform input[type=text], .client .declineform input:not([type]) { width:100%;
  box-sizing:border-box; font:inherit; font-size:12.5px; padding:5px 8px;
  border:1px solid var(--line); border-radius:7px; margin-top:4px }
/* что бизнес уже делает по прошлому плану — строкой над выбором */
.client .inplan { font-size:12.5px; margin-bottom:12px; padding:10px 12px; border-radius:10px; background:#f6f7f9 }
.client .inplan h5 { margin:0 0 6px; font-size:11.5px; font-weight:500; color:var(--muted) }
.client .inplan ul { list-style:none; margin:0; padding:0; display:grid; gap:4px }
.client .inplan li { display:flex; align-items:center; gap:8px; padding:6px 10px; border-radius:8px; background:#fff }
.client .inplan li .ch { width:52px; flex:none; color:var(--muted); font-size:12px }
.client .inplan li b { font-weight:600; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.client .inplan li .tag { margin-left:auto }
.client .inplan .hint { display:block; margin-top:8px }
.client .asked { display:flex; gap:7px; align-items:center; font-size:12.5px; margin-top:4px; cursor:pointer }
.client .feed { margin-top:16px; border-top:1px solid var(--line); padding-top:10px }
.client .feed div { font-size:12.5px; color:var(--muted); padding:2px 0 }
.client .feed i { font-style:normal; opacity:.7 }
.client .empty { font-size:12.5px; color:var(--muted) }
td.who { overflow:hidden; text-overflow:ellipsis }
#tbl tbody tr { cursor:pointer }

/* Телефон: окно на весь экран, сначала сценарий, профиль — ниже и свёрнутым */
@media (max-width:430px){
  dialog.client { width:100vw; max-width:100vw; height:100dvh; max-height:100dvh; border-radius:0; border:0 }
  .client .body { grid-template-columns:1fr; max-height:calc(100dvh - 96px) }
  .client .col.scen { order:-1; border-left:0; border-bottom:1px solid var(--line) }
  .client .row button, .client .row a.btn, .client .outcome button { width:100%; padding:11px 14px; font-size:15px }
  .client .row { gap:6px }
  /* «отменить» рядом с «отправлено» — мелкая, в строку: главное действие уже сделано */
  .client .row .done + button { width:auto; padding:5px 12px; font-size:13px }
  .client .row .altrow { flex-basis:100%; justify-content:center }
  .client .row .altrow button { width:auto; padding:6px 8px; font-size:13px }
  .client .head .tel { font-size:16px; font-weight:600 }
  .client .nums { grid-template-columns:1fr }
  /* «Групповая тренировка» — одной строкой, полоса короче */
  .client .bars.mini .bar { grid-template-columns:132px 1fr 30px }
  .client .bars.mini .bar > span:first-child { white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
}

/* Список людей на телефоне: таблица уезжает, остаются карточки — имя, группа,
   когда был и что назначено. Всё, чтобы решить «открывать или листать дальше». */
.cards { display:none; gap:8px }
.cards .ccard { display:grid; grid-template-columns:1fr auto; gap:2px 8px; width:100%; text-align:left;
  font:inherit; cursor:pointer; padding:10px 12px; background:var(--card);
  border:1px solid var(--line); border-radius:9px }
/* клетки расставлены поимённо: у строки с одним только номером строки браузер
   по правилам грида отдаёт первую колонку ей, и код уезжал бы вправо */
.cards .ccard b { grid-area:1 / 1; font-size:15px; font-weight:600 }
.cards .ccard .pill { grid-area:1 / 2; justify-self:end }
.cards .ccard .when { grid-area:2 / 1; font-size:12.5px; color:var(--muted) }
.cards .ccard .ic { grid-area:2 / 2; justify-self:end; color:var(--muted) }
.cards .ccard .ic .ico { margin-left:6px }
.cards .ccard .ic .ico.on { color:var(--active) }
.cards .ccard.off { opacity:.55 }
@media (max-width:430px){
  /* отметки живут в таблице, значит и массовые действия вместе с ней */
  #sec-clients .tbl-wrap, #bulk { display:none }
  .cards { display:grid }
  /* возражениям — горизонтальная прокрутка, а не сжатие в столбик */
  .objwrap { overflow:auto }
  .objedit { min-width:640px }
  .filters .q { font-size:16px; padding:9px 12px }
  #flt-xlsx { flex:1 1 100% }
}

/* ---------- раздел «Аналитика» ---------- */
.an-head .anrow { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:10px }
.an-head .anrow label { display:flex; gap:5px; align-items:center; font-size:12.5px; color:var(--muted) }
.an-head .anrow input { font:inherit; font-size:12.5px; padding:4px 8px; border:1px solid var(--line);
  border-radius:7px; background:var(--card) }
/* таблицы аналитики уже телефона: прокрутка внутри карточки, а не всей страницы */
.andecl { margin-top:8px; font-size:12.5px; color:color-mix(in oklab, var(--at_risk) 85%, #000) }
.anscroll { overflow-x:auto; margin-top:10px }
/* таблицы аналитики: колонки по содержимому (а не поровну, как в «Клиентах»),
   название шаблона не режется */
table.an { width:100%; min-width:640px; border-collapse:collapse; font-size:13px; table-layout:auto }
table.an th { text-align:left; font-weight:600; color:var(--muted); font-size:11.5px; text-transform:uppercase;
  letter-spacing:.03em; padding:0 8px 6px; border-bottom:1px solid var(--line); position:static; cursor:default; white-space:normal; vertical-align:bottom }
table.an td { padding:6px 8px; border-bottom:1px solid #f2f4f6; vertical-align:top; white-space:normal }
table.an td:first-child { white-space:nowrap }
/* «По группам»: восемь столбцов чисел одинаковой ширины — при колонках по
   содержимому числа расползались и шапка теряла связь со своим столбцом */
table.an.even { table-layout:fixed }
table.an.even th:first-child { width:160px }
/* «Шаблоны»: название и итоги звонков тянутся, числа — по своей мерке.
   Таблица влезает в карточку целиком, длинное прячется под многоточие. */
table.an.tpl { table-layout:fixed; min-width:0 }
/* шапка мельче: «назначено» и «отказались» одним словом не переносятся, а в
   восьми столбцах чисел им иначе не хватает места */
table.an.tpl th { font-size:10px; letter-spacing:.02em }
table.an.tpl th.num { white-space:normal }  /* шапки чисел переносятся в две строки */
/* Столбцы чисел — ровно по шапке, поля тоньше обычных: всё, что осталось,
   уходит итогам звонков, им ширина нужнее всего. */
table.an.tpl th, table.an.tpl td { padding-left:5px; padding-right:5px }
table.an.tpl th:nth-child(1) { width:184px }
table.an.tpl th:nth-child(2) { width:94px }
table.an.tpl th:nth-child(3) { width:78px }
table.an.tpl th:nth-child(4) { width:64px }
table.an.tpl th:nth-child(5) { width:76px }
table.an.tpl th:nth-child(6) { width:56px }  /* «100%» целиком */
table.an.tpl th:nth-child(7) { width:70px }
table.an.tpl th:nth-child(8) { width:64px }
table.an.tpl th:nth-child(9) { width:76px }
table.an.tpl th:nth-child(10) { width:84px }
table.an.tpl td:first-child, table.an.tpl td:last-child div { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
/* итоги звонков — одной строкой: перенос ломал ритм таблицы, полный текст в подсказке */
table.an td.outs div { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
table.an td.num, table.an th.num { text-align:right; white-space:nowrap }
table.an tr.thin td { color:var(--muted) }
table.an td.up { color:var(--active) }
table.an td.down { color:var(--lost) }
.an-two { display:grid; grid-template-columns:1fr 1fr; gap:14px }
/* Соседние карточки одной высоты и выровнены по верху графика: пояснение в
   обеих занимает две строки, дальше график начинается на одной высоте. */
.an-two { align-items:stretch }
.an-two > .card { display:flex; flex-direction:column }
.an-two > .card > .hint { min-height:34px }
/* легенды обеих карточек — по низу */
.an-two .anlegend { margin-top:auto; padding-top:12px }
.anlegend .seg { background:linear-gradient(135deg, var(--active) 0 33%, var(--at_risk) 33% 66%, var(--lost) 66%) }
.anpeople { display:grid; gap:4px; margin-top:8px; max-height:320px; overflow:auto }
.anpeople button { display:grid; grid-template-columns:92px 70px 1fr; gap:8px; align-items:center; width:100%; text-align:left; font:inherit;
  font-size:12.5px; cursor:pointer; padding:5px 8px; background:var(--card);
  border:1px solid var(--line); border-radius:7px }
.anpeople button:hover { background:#fafbfc }
.anpeople code { font-size:11.5px; color:var(--muted) }
.anpeople .pill { justify-self:start }
/* по столбику на загрузку: высота — люди в базе, цвета — доли групп */
/* «Как менялись группы»: линии в svg (растягивается без пропорций, толщина
   постоянная), точки с числами и даты — html поверх в тех же процентах */
.snaplegend { display:flex; flex-wrap:wrap; gap:4px 6px; margin:8px 0 4px }
.snaplegend button { font:inherit; font-size:12px; display:inline-flex; align-items:center; gap:6px; padding:3px 9px;
  border:1px solid var(--line); border-radius:999px; background:var(--card); color:var(--ink); cursor:pointer }
.snaplegend button i { width:10px; height:3px; border-radius:2px; background:var(--c) }
.snaplegend button.off { color:var(--muted); background:#f4f5f7 }
.snaplegend button.off i { background:#c4c6cc }
.snapchart { position:relative; height:210px; margin:6px 0 0; padding:22px 28px 36px }
.snapchart .plot { position:relative; height:100%; border-bottom:1px solid var(--line) }
.snapchart svg { position:absolute; inset:0; width:100%; height:100%; overflow:visible }
.snapchart polyline { fill:none; stroke:var(--c); stroke-width:2; vector-effect:non-scaling-stroke; stroke-linejoin:round; stroke-linecap:round }
.snapchart .dot { position:absolute; width:8px; height:8px; margin:-4px 0 0 -4px; border-radius:50%; background:var(--card);
  border:2px solid var(--c); box-sizing:border-box; font-style:normal }
.snapchart .dot b { position:absolute; left:50%; transform:translateX(-50%); font-size:11px; font-weight:600; line-height:1;
  color:var(--ink); white-space:nowrap; text-shadow:0 0 3px var(--card), 0 0 3px var(--card) }
.snapchart .dot b.up { bottom:7px } .snapchart .dot b.dn { top:7px }
.snapchart .xs { position:absolute; left:28px; right:28px; bottom:0; height:18px }
.snapchart .xs span { position:absolute; transform:translateX(-50%); font-size:11px; color:var(--muted); white-space:nowrap }
.snapnow { display:flex; flex-wrap:wrap; gap:4px 14px; margin-top:12px; font-size:12.5px; color:var(--muted) }
.snapnow span { color:var(--ink); white-space:nowrap }
.snapnow .sw { display:inline-block; width:9px; height:9px; border-radius:3px; background:var(--c); margin-right:5px }
.snapnow i.up { color:var(--active); font-style:normal; font-weight:600 }
.snapnow i.down { color:var(--lost); font-style:normal; font-weight:600 }
.snapnow i:not(.sw):not(.up):not(.down) { font-style:normal; color:var(--muted) }
@media (max-width:860px){
  .an-two { grid-template-columns:1fr }
  .anlift .row { grid-template-columns:1fr 72px }
  .anlift .l { grid-column:1 / -1 }
}
/* графики аналитики: полоски и столбики из div, без библиотек */
.anlegend { display:flex; gap:14px; align-items:center; margin-top:10px; font-size:12px; color:var(--muted) }
.anlegend i { display:inline-block; width:10px; height:10px; border-radius:2px; background:var(--c); margin-right:5px; vertical-align:-1px }
.anlegend .ctl { background:#c9ccd3 }
.anlegend .sms { background:#7d8aa5 }
.anlegend .call { background:#4a5468 }
.anlegend .ret { background:var(--active) }
/* «Когда приходят после связи»: линии в svg, точки и подписи — html поверх */
.ancurve .cv-say { font-size:13.5px; line-height:1.45; margin:6px 0 4px }
.cv-chart { position:relative; height:190px; padding:12px 8px 26px 38px }
.cv-chart .plot { position:relative; height:100%; border-bottom:1px solid var(--line); border-left:1px solid var(--line) }
.cv-chart svg { position:absolute; inset:0; width:100%; height:100%; overflow:visible }
.cv-chart polyline { fill:none; stroke-width:2.5; vector-effect:non-scaling-stroke; stroke-linejoin:round; stroke-linecap:round }
.cv-chart polyline.ours { stroke:var(--c) }
.cv-chart polyline.ctl { stroke:#b9bcc3; stroke-dasharray:5 4 }
.cv-chart .dot { position:absolute; width:9px; height:9px; margin:-4.5px 0 0 -4.5px; border-radius:50%; background:var(--card);
  border:2px solid var(--c); box-sizing:border-box }
.cv-chart .unseen { position:absolute; top:0; bottom:0; right:0; border-left:1px dashed var(--line);
  background:repeating-linear-gradient(135deg, transparent 0 6px, #f3f4f6 6px 8px) }
.cv-chart .unseen span { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); font-size:11.5px; color:var(--muted);
  background:var(--card); padding:2px 6px; border-radius:4px; text-align:center; max-width:90%; }
.cv-chart .ys { position:absolute; left:0; top:12px; bottom:26px; width:32px; display:flex; flex-direction:column;
  justify-content:space-between; align-items:flex-end; font-size:11px; color:var(--muted) }
.cv-chart .ys span { transform:translateY(-50%) } .cv-chart .ys span:last-child { transform:translateY(50%) }
.cv-chart .xs { position:absolute; left:38px; right:8px; bottom:0; height:18px }
.cv-chart .xs span { position:absolute; transform:translateX(-50%); font-size:11px; color:var(--muted) }
.ancurve .anlegend .ctl { background:none; border-top:2px dashed #b9bcc3; height:0; border-radius:0 }
/* «По планам»: полоса — назначено целиком, на ней сделано и пришли */
.anplans .pl { padding:10px 0; border-top:1px solid var(--line) }
.anplans .pl:first-of-type { border-top:0; padding-top:6px }
.anplans .pl-h { display:flex; justify-content:space-between; gap:10px; font-size:13.5px; margin-bottom:6px }
.anplans .pl-bar { position:relative; height:12px; background:#eef0f3; border-radius:6px; overflow:hidden }
.anplans .pl-bar i { position:absolute; left:0; top:0; bottom:0; border-radius:6px }
.anplans .pl-bar .done { background:#9aa6bd } .anplans .pl-bar .came { background:var(--active) }
.anplans .pl-n { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:8px; margin-top:12px }
.anplans .pl-n div { padding:8px 10px; border-radius:8px; background:#f6f7f9; display:grid; gap:2px }
.anplans .pl-n b { font-size:22px; font-weight:650; letter-spacing:-0.02em; line-height:1.1 }
.anplans .pl-n span { font-size:12px; color:var(--muted) }
.anplans .pl-n .came b { color:var(--active) }
.anplans .pl-n .ctl b { color:var(--muted) }
.anplans .pl .hint { margin:4px 0 0 }
.anlegend .pdone { background:#9aa6bd }
/* «Есть ли эффект»: крупный ответ, статус и по строке на группу */
.eff .eff-head { display:flex; align-items:center; gap:16px; margin:6px 0 10px }
.eff .eff-n { font-size:40px; font-weight:650; letter-spacing:-0.03em; line-height:1; color:var(--muted); min-width:64px }
.eff .eff-n.plus { color:var(--active) }
.eff .eff-line { font-size:15px; line-height:1.4; max-width:640px }
.eff .eff-status { font-size:13px; padding:8px 12px; border-radius:8px; margin-bottom:12px; line-height:1.45 }
.eff .eff-status.wait { background:color-mix(in srgb, var(--at_risk) 10%, var(--card)) }
.eff .eff-status.done { background:color-mix(in srgb, var(--active) 10%, var(--card)) }
.eff .eff-later { margin:-4px 0 12px }
.eff .eff-rows { display:grid; gap:10px }
.eff .eff-row { display:grid; grid-template-columns:120px minmax(0,1fr) 190px; gap:14px; align-items:center;
  padding-top:10px; border-top:1px solid var(--line) }
.eff .eff-row .pill { justify-self:start }
.eff .eff-bars { display:grid; gap:4px }
.eff .eff-b { display:grid; grid-template-columns:84px minmax(0,1fr) 40px 110px; gap:8px; align-items:center; font-size:12.5px }
.eff .eff-b span { color:var(--muted) } .eff .eff-b b { text-align:right; font-weight:600 } .eff .eff-b i { font-style:normal; color:var(--muted); font-size:12px }
.eff .track { height:10px; background:#eef0f3; border-radius:5px; overflow:hidden }
.eff .fill { height:100%; border-radius:5px }
.eff .verdict { justify-self:start; font-size:12.5px; font-weight:600; padding:3px 10px; border-radius:10px; background:#eef0f3; color:var(--muted) }
.eff .verdict.plus { background:color-mix(in srgb, var(--active) 14%, var(--card)); color:var(--active) }
@media (max-width:760px){ .eff .eff-row { grid-template-columns:1fr } .eff .eff-b { grid-template-columns:70px minmax(0,1fr) 36px } .eff .eff-b i { display:none } }
/* окно возврата ещё идёт: доли предварительные — приглушены, но читаются */
table.an tr.open td.num { color:var(--muted) }
/* шаблоны: разница с контролем от нулевой оси — вправо лучше, влево хуже */
.anlift { display:grid; gap:6px; margin:12px 0 18px }
/* шкала узкая, число сразу за ней: у правого края карточки оно отрывалось
   от своей полоски, а глазом их надо читать вместе */
/* график кончается там же, где первая строка пояснения над ним («…чем у
   контроля»): так он читается продолжением текста, а не висит посередине */
.anlift { max-width:706px }
/* полоски шаблонов слева, справа — канал и итоги звонков; узко — друг под другом */
.antpl-top { display:grid; grid-template-columns:minmax(0, 1.5fr) minmax(260px, 1fr); gap:28px; align-items:stretch; margin-bottom:24px }
/* слева строки раздвигаются по высоте правой колонки: там между блоками есть зазор */
.antpl-top .anlift { max-width:none; margin:12px 0 0; padding-left:5px; align-content:space-between }
.antpl-side h4 ~ h4 { margin-top:14px }
/* одна сетка на всю колонку, заголовки — такие же строки: шаг 19+6 px тот же,
   что у полосок слева, поэтому строки справа стоят вровень с ними */
.antpl-side { margin-top:12px; padding:0 6px 0 24px; border-left:1px solid var(--line); display:grid;
  grid-template-columns:max-content minmax(80px, 1fr) max-content; grid-auto-rows:minmax(19px, auto); gap:6px 10px; align-items:center; align-content:start }
.antpl-side h4 { grid-column:1 / -1; margin:0; line-height:19px; font-size:11px; font-weight:600; letter-spacing:.04em;
  text-transform:uppercase; color:var(--muted); white-space:nowrap }
.antpl-side h4 small { font-size:11px; font-weight:400; letter-spacing:0; text-transform:none; margin-left:6px }
.anside, .anside .o { display:contents }
.anside .l { white-space:nowrap; font-size:12.5px; line-height:19px; display:flex; gap:5px; align-items:center }
.anside .l svg { width:13px; height:13px; flex:none }
.anside .track { position:relative; height:12px; background:#f3f4f6; border-radius:3px }
.anside .fill { height:100%; background:#9aa1b0; border-radius:3px; min-width:2px }
.anside .fill.sms { background:#7d8aa5 } .anside .fill.call { background:#4a5468 } .anside .fill.good { background:var(--active) }
.anside .mark { position:absolute; top:-2px; bottom:-2px; width:2px; margin-left:-1px; background:var(--ink); border-radius:1px }
.anside .v { text-align:right; font-size:12px; color:var(--muted); white-space:nowrap; font-variant-numeric:tabular-nums }
.anside .v small { color:#a3a6ad; font-size:12px; margin-left:2px }
@media (max-width:1000px){ .antpl-top { grid-template-columns:1fr } .antpl-side { padding-left:0; border-left:0 } }
.anlift .row { display:grid; grid-template-columns:minmax(160px, 340px) minmax(150px, 1fr) 34px;
  gap:10px; align-items:center; font-size:12.5px; height:19px }
@media (max-width:860px){ .anlift { max-width:none } .anlift .row { grid-template-columns:1fr 72px } }
.anlift .row.thin { color:var(--muted) }
.anlift .row.thin .pos, .anlift .row.thin .neg { opacity:.45 }
.anlift .l { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.anlift .l small { color:var(--muted); font-size:11px; margin-left:4px }
.anlift .axis { position:relative; height:12px; background:#f3f4f6; border-radius:3px }
.anlift .axis::before { content:""; position:absolute; left:50%; top:-3px; bottom:-3px; border-left:1px solid #c9ccd3 }
.anlift .pos { position:absolute; left:50%; top:0; height:100%; background:var(--active); border-radius:0 3px 3px 0; min-width:2px }
.anlift .neg { position:absolute; right:50%; top:0; height:100%; background:var(--lost); border-radius:3px 0 0 3px; min-width:2px }
.anlift .v { text-align:right; font-size:12px; color:var(--muted); white-space:nowrap }
.anlift .v.up { color:var(--active) } .anlift .v.down { color:var(--lost) }

/* Плашка-уведомление внизу экрана */
#flash { position:fixed; left:50%; bottom:18px; transform:translate(-50%, 12px); z-index:90; max-width:min(92vw, 620px);
  padding:9px 16px; border-radius:9px; background:var(--ink); color:#fff; font-size:13px; line-height:1.4;
  opacity:0; pointer-events:none; transition:opacity .15s, transform .15s }
#flash.on { opacity:1; transform:translate(-50%, 0) }
#flash.bad { background:var(--lost) }
.obj { margin-top:10px }
.obj summary { cursor:pointer; font-size:12.5px; color:var(--muted); user-select:none }
.obj table { width:100%; min-width:0; border-collapse:collapse; font-size:12px; line-height:1.35; margin-top:4px; table-layout:fixed }
.obj td { text-align:left; vertical-align:top; padding:4px 6px 4px 0; border-bottom:1px solid var(--line); white-space:normal }
.obj tr:last-child td { border-bottom:0 }
.obj td:first-child { font-weight:600; width:9.5em; padding-right:10px }
.obj td .to { display:block; margin-top:1px; font-size:11px; color:var(--muted) }
.pill.ctl { background:#eef0f3; color:var(--muted) }
tr.ctl td { color:var(--muted) }
.foot { color:var(--muted); font-size:12px; margin-top:8px }
.err { color:var(--lost) }
.help { margin-top:14px; border-top:1px solid var(--line); padding-top:10px }
.help summary { cursor:pointer; color:var(--muted); font-size:13px; user-select:none }
/* ---------- раздел «Настройки»: группы ---------- */
/* Три карточки одна под другой: карточка бизнеса, группы, опасная зона.
   Внутри «групп» — распределение полосой, гистограмма давности с двумя
   границами, которые можно тянуть, и лестница условий с числом людей в
   каждой строке. Поля стоят прямо в тексте условия: «прошло > [20] дн.» —
   так число читается как часть фразы, а не как ячейка формы. */
.settings .card { padding:16px 20px }
/* Настройки администратора — два столбца: слева карточка бизнеса и опасная
   зона, справа группы. У владельца карточки нет — группы во всю ширину. */
/* первая строка забирает лишнюю высоту длинных «Групп»: карточка тянется
   вниз, и низ опасной зоны совпадает с низом «Групп» */
.settings:has(#st-card:not([hidden])) { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows:1fr auto; align-items:stretch }
.settings:has(#st-card:not([hidden])) #st-card { grid-column:1; grid-row:1 }
.settings:has(#st-card:not([hidden])) #st-danger { grid-column:1; grid-row:2 }
.settings:has(#st-card:not([hidden])) #st-groups { grid-column:2; grid-row:1 / span 2 }
/* в половине ширины три колонки лестницы не помещаются: имя и счётчик — сверху,
   условие с полями — строкой под ними во всю ширину */
.settings:has(#st-card:not([hidden])) .lrow { grid-template-columns:minmax(0, 1fr) auto;
  grid-template-areas:"name cnt" "cond cond"; gap:2px 14px }
.settings:has(#st-card:not([hidden])) .lname { grid-area:name }
.settings:has(#st-card:not([hidden])) .lcond { grid-area:cond; line-height:1.9 }
.settings:has(#st-card:not([hidden])) .lcnt { grid-area:cnt; min-width:110px }
@media (max-width:900px){
  .settings:has(#st-card:not([hidden])) { grid-template-columns:minmax(0, 1fr) }
  .settings:has(#st-card:not([hidden])) > .card { grid-column:1; grid-row:auto }
}
.settings .bizcard { margin-top:0; padding-top:16px; border-top:1px solid var(--line) }
.settings .bizcard h3 { font-size:13px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted) }
/* поля карточки парами: название с категорией, описание с указаниями */
.two-f { display:grid; grid-template-columns:minmax(0,3fr) minmax(0,2fr); gap:0 14px; align-items:start }
.two-f .f { display:flex; flex-direction:column }
.two-f textarea { flex:1 1 auto }
.bizcard select { width:100% }   /* вид общий, здесь только ширина */
/* список категорий и поле новой категории одной высоты — подмена не дёргает форму */
.bizcard .two-f input, .bizcard .two-f select { height:33px; box-sizing:border-box }
.groups .muted { color:var(--muted); font-size:12px }
/* распределение: одна полоса на всех и подпись по группам */
.dist { margin:6px 0 18px }
.dbar { display:flex; height:14px; border-radius:7px; overflow:hidden; background:#eef0f3; gap:1px }
.dbar i { display:block; background:var(--c); min-width:2px; transition:flex .25s ease }
.dleg { display:flex; justify-content:space-between; gap:6px; margin-top:8px; font-size:11.5px; white-space:nowrap }
.dleg span { display:inline-flex; align-items:baseline; gap:4px; color:color-mix(in srgb, var(--c) 80%, var(--ink)) }
.dleg i { display:none }
.dleg b { color:var(--ink); font-weight:600 }
/* гистограмма давности с ползунками границ */
.recency { position:relative; margin:0 0 18px; padding:0 2px }
.rhead { display:flex; justify-content:space-between; font-size:12px; color:var(--muted); margin-bottom:30px }  /* место под метки границ */
.rhist { display:flex; align-items:flex-end; gap:2px; height:120px; border-bottom:1px solid var(--line); padding-bottom:2px }
.rhist div { flex:1; background:var(--c); min-height:1px; border-radius:2px 2px 0 0; opacity:.85 }
.rplot { position:relative }
.rhandles { position:absolute; left:0; right:0; top:0; height:122px; pointer-events:none }
.handle { position:absolute; top:0; bottom:0; width:0; pointer-events:auto; cursor:ew-resize; touch-action:none }
.handle i { position:absolute; top:0; bottom:-2px; left:-1px; width:2px; background:var(--c); border-radius:1px }
.handle::before { content:""; position:absolute; top:-6px; bottom:-6px; left:-10px; width:20px }  /* за что хвататься */
.handle .tag { position:absolute; top:-22px; left:-1px; transform:translateX(-50%); white-space:nowrap; font-size:11.5px;
  color:#fff; background:var(--c); padding:2px 7px; border-radius:6px; line-height:1.3; cursor:ew-resize; user-select:none }
.handle .tag::after { content:""; position:absolute; left:50%; bottom:-4px; margin-left:-4px; border:4px solid transparent; border-top-color:var(--c); border-bottom:0 }
.handle.drag .tag, .handle:hover .tag { box-shadow:0 2px 8px rgba(0,0,0,.18) }
.handle[data-h="active_max_ratio"] .tag { transform:translateX(-100%) translateX(-6px) }   /* соседние метки не накладываются */
.handle[data-h="active_max_ratio"] .tag::after { left:auto; right:4px; margin:0 }
.raxis { display:flex; justify-content:space-between; font-size:11px; color:var(--muted); margin-top:4px }
.rtags { display:none; gap:14px; flex-wrap:wrap; font-size:12px; margin-top:8px }
.rtags i { display:inline-block; width:9px; height:9px; border-radius:2px; margin-right:6px; vertical-align:-1px }
/* лестница условий */
.ladder { border-top:1px solid var(--line) }
.lrow { display:grid; grid-template-columns:168px minmax(0,1fr) 150px; align-items:center; gap:0 14px;
        padding:9px 0; border-bottom:1px solid var(--line); font-size:13.5px }
.lrow.base { color:var(--ink) }
.lrow.base .sw { background:#cfd2d8 } .lrow.base .sw.ctl { background:#9a9ca3 }
.lname { display:flex; align-items:center; gap:8px; font-weight:500; white-space:nowrap }
.lname .sw { width:10px; height:10px; border-radius:3px; background:var(--c); flex:none }
.lcond { line-height:2.1 }
.lcond .cmp { font-weight:600; padding:0 2px; color:var(--ink) }
.lcond input { font:inherit; font-size:13px; width:50px; padding:2px 5px; margin:0 2px; border:1px solid var(--line);
               border-radius:7px; background:var(--card); text-align:center; appearance:textfield; vertical-align:baseline }
.lcond input::-webkit-inner-spin-button, .lcond input::-webkit-outer-spin-button { -webkit-appearance:none; margin:0 }
.lcond input:disabled { border-color:transparent; background:none; color:var(--ink); font-weight:600; field-sizing:content; width:auto; min-width:1ch; max-width:56px; padding:0; text-align:center }
.rhandles.ro .handle { cursor:default }
.lcond input:focus { outline:2px solid var(--ink); outline-offset:-1px; border-color:var(--ink) }
.lcond .linkbtn { font-size:12px; text-decoration:underline dotted; text-underline-offset:3px }
.lcnt { display:grid; grid-template-columns:auto auto; gap:0 8px; align-items:baseline; justify-content:end; font-variant-numeric:tabular-nums }
.lcnt b { font-size:15px } .lcnt span { font-size:12px; color:var(--muted) }
.lcnt .mini { grid-column:1 / -1; height:4px; border-radius:2px; background:#eef0f3; overflow:hidden; margin-top:3px }
.lcnt .mini i { display:block; height:100%; background:var(--c); transition:width .25s ease }
.facts { margin-top:14px; font-size:13px }
.facts summary { cursor:pointer; color:var(--muted); user-select:none }
.facts ul { margin:8px 0 0; padding-left:18px } .facts li { margin:3px 0 }
.gact { margin-top:16px; padding-top:12px; border-top:1px solid var(--line); flex-wrap:wrap }
.gact .state { margin-left:4px; font-size:12.5px; color:var(--muted) }
.gact .state.wait { white-space:nowrap }
.gact .state.warn { color:var(--at_risk) } .gact .state.err { color:var(--lost) }
/* предложение нейросети */
.proposal { margin-top:16px; padding:14px 16px; border:1px solid var(--line); border-radius:10px; background:#fafbfc }
.proposal.applied { border-color:var(--active) }
.proposal h3 { margin:0 0 6px; font-size:14px } .proposal p { margin:0 0 10px; font-size:13.5px }
.pwrap { overflow:auto }
.ptable { width:100%; min-width:0; border-collapse:collapse; font-size:13px; table-layout:auto }
.ptable th, .ptable td { text-align:left; padding:6px 8px; border-bottom:1px solid var(--line); vertical-align:top; white-space:normal; cursor:default; position:static }
.ptable th { color:var(--muted); font-weight:500; font-size:12px }
.ptable td:first-child { white-space:nowrap }
.ptable .num { text-align:right; white-space:nowrap; width:1% }
.ptable tr:has(+ .whyrow) td { border-bottom:0; padding-bottom:2px }
.ptable td.why { white-space:normal; color:var(--muted); font-size:12.5px; line-height:1.45; padding-top:0; padding-bottom:10px }
.ptable tr.same td { color:var(--muted) }
.pbar { display:grid; grid-template-columns:56px 1fr; gap:10px; align-items:center; margin-top:8px; font-size:12px; color:var(--muted) }
.proposal .row { margin-top:12px; align-items:center; flex-wrap:wrap }
.danger-zone .row { margin-top:4px }
@media (max-width:760px){
  /* таблица предложения на телефоне — списком: имя, «было → станет», ниже объяснение */
  .ptable, .ptable tbody { display:block }
  .ptable thead { display:none }
  .ptable tr { display:grid; grid-template-columns:auto 1fr; gap:2px 12px; padding:8px 0; border-bottom:1px solid var(--line) }
  .ptable td { border:0; padding:0 }
  .ptable td:first-child { grid-column:1 / -1; white-space:normal; font-weight:500 }
  .ptable td.num { text-align:left; white-space:normal }
  .ptable td.why { grid-column:1 / -1; width:auto }
  .ptable td.num:nth-child(2)::before { content:"было "; color:var(--muted); font-size:12px }
  .ptable td.num:nth-child(3)::before { content:"→ "; color:var(--muted) }
  /* на узком экране план и черновик встают друг под другом — разделитель не нужен */
  .planbar .pstate.on:not(:last-child) { padding-right:0; border-right:0 }
  .planbar .pstate + .pstate { margin-left:0 }
  .lrow { grid-template-columns:1fr; gap:4px 0 }
  .lcnt { justify-content:start }
  .two-f { grid-template-columns:1fr }
  /* плавающие метки границ на узком экране не помещаются — вместо них строка под осью */
  .handle .tag { display:none }
  .rtags { display:flex }
  .rhead { margin-bottom:8px } .rhead #g-span { display:none }
}
/* ---------- карточка бизнеса ---------- */
/* Текстовые поля во всю ширину, счётчик под полем справа: описание читает
   нейросеть, и важно видеть, сколько места осталось. Стоит и в «Настройках»,
   и в админке — отсюда отдельный блок, а не правка .settings. */
.bizcard { margin-top:16px; padding-top:14px; border-top:1px solid var(--line) }
.bizcard h3 { font-size:13px; margin:0 0 4px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); font-weight:600 }
.bizcard .hint { margin:0 0 10px }
.bizcard .f { display:block; margin-bottom:10px; font-size:12.5px }
.bizcard .f > span { display:block; color:var(--muted); margin-bottom:3px }
.bizcard .f > span.newcat { display:flex; margin-bottom:0; color:inherit }
.bizcard input:not([type=checkbox]), .bizcard textarea { width:100%; box-sizing:border-box; font:inherit; font-size:13px;
  padding:6px 9px; border:1px solid var(--line); border-radius:7px; background:var(--card);
  color:var(--ink); resize:vertical; line-height:1.45 }
.bizcard .flags input { width:auto; margin:0; flex:none }
/* карточку тянут до высоты соседней колонки — лишнее забирают описание и указания */
.bizcard { display:flex; flex-direction:column }
.bizcard .f.grow { display:flex; flex-direction:column; flex:var(--g, 1) 1 auto }
.bizcard .f.grow textarea { flex:1 1 auto }
.bizcard input:focus, .bizcard textarea:focus { outline:2px solid var(--ink); outline-offset:-1px; border-color:var(--ink) }
.bizcard .cnt { display:block; text-align:right; font-style:normal; font-size:11.5px; color:var(--muted); margin-top:2px }
.bizcard .flags { display:grid; gap:6px; margin:4px 0 2px }
.bizcard .flags label { display:flex; gap:8px; align-items:center; font-size:13px; cursor:pointer }
.bizcard .row { display:flex; gap:8px; align-items:center; margin-top:12px }
.bizcard .state { font-size:12.5px; color:var(--muted) }
.bizcard .state.err { color:var(--lost) }
.help-body { margin-top:10px; font-size:13.5px; max-width:820px }
.help-body p { margin:0 0 10px }
.seg-help { display:grid; gap:6px; margin:10px 0 12px }
.seg-help div { border-left:4px solid var(--c); padding:4px 10px; background:#fafafa; border-radius:0 6px 6px 0 }
/* подробности — свёрнутыми: на виду остаётся то, ради чего панель открывают,
   а длинные объяснения разворачивает тот, кому они сейчас нужны */
.help-more { border-top:1px solid var(--line); padding:9px 0 }
/* заголовок раздела — как «шапки» шагов в приёме выгрузки: внутри разделов
   пункты начинаются с жирного слова, и обычный жирный заголовок сливался с ними */
.help-more > summary { cursor:pointer; user-select:none; list-style:none; font-size:12px; font-weight:600;
                       text-transform:uppercase; letter-spacing:.04em; color:var(--muted) }
.help-more > summary::-webkit-details-marker { display:none }
.help-more > summary::before { content:"▸"; display:inline-block; width:14px; font-weight:400; letter-spacing:0 }
.help-more[open] > summary::before { content:"▾" }
.help-more > p { margin:9px 0 0 }
.help-more ul { margin:9px 0 0; padding-left:17px }
.help-more li { margin-bottom:6px }
.help-body li, .seg-help > div { text-wrap:pretty }
/* справка одна на обе роли: .adm — для нас, .own — для владельца */
body:not([data-role=admin]) #p-help .adm, body[data-role=admin] #p-help .own { display:none }
/* ссылки внутри текста — тем же пунктиром, что и подсказки: синее подчёркнутое
   поперёк абзаца выглядит как чужое и тянет взгляд сильнее самого текста */
.help-body a { color:var(--ink); text-decoration:underline solid #bfc1c7 1px; text-underline-offset:3px }
.help-body a:hover { text-decoration-color:var(--ink) }
.hint { color:var(--muted); font-size:12px; margin-top:10px }
.row { display:flex; gap:8px; align-items:center; flex-wrap:wrap }
.xdel, .xadd { width:24px; height:24px; padding:0; border:0; border-radius:50%; background:none; color:var(--lost); font-size:18px; line-height:1; cursor:pointer }
.xadd { color:var(--active); font-size:20px }
/* своя категория: поле с названием на месте списка */
/* ✓ и × висят под полем поверх отступа и не раздвигают соседние блоки */
.newcat { position:relative; display:flex; min-width:0 }
.newcat input { flex:1 1 0; min-width:0 }
.newcat .nc-tools { position:absolute; top:100%; left:0; right:0; z-index:2; display:flex; gap:2px; align-items:center; margin-top:1px }
.newcat .state { font-style:normal; font-size:12px; color:var(--muted); margin:0 0 0 4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; background:var(--card) }
.newcat .state:empty { display:none }
.newcat .state.err { color:var(--lost) }
.xdel:hover { background:color-mix(in srgb, var(--lost) 12%, transparent) }
.xadd:hover { background:color-mix(in srgb, var(--active) 12%, transparent) }
.objedit .xcol { width:28px }
#tpl-obj .state { font-size:12.5px; color:var(--muted); margin-left:auto } #tpl-obj .state.err { color:var(--lost) }
.objedit tr.fresh td { background:#f4fbf6 }
.objedit tr.fresh td:first-child { box-shadow:inset 3px 0 0 var(--active) }
.row > .hint { margin-top:0 }  /* в ряду с кнопками отступ сверху сбивал её с их середины */
/* приём выгрузки: шаги идут сверху вниз, каждый следующий появляется после предыдущего */
.drop { border:2px dashed var(--line); border-radius:10px; padding:22px; text-align:center; color:var(--muted); font-size:13.5px; cursor:pointer }
.drop.over { border-color:var(--active); background:#f4fbf6; color:var(--ink) }
.drop b { color:var(--ink) }
.step { margin-top:16px; padding-top:14px; border-top:1px solid var(--line) }
.step > h3 { font-size:13px; margin:0 0 8px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); font-weight:600 }
.cols { display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:10px 18px }
.cols label { display:grid; gap:4px; font-size:12.5px; color:var(--muted) }
.intake input[type=text] { font:inherit; font-size:13px; padding:6px 8px; border:1px solid var(--line); border-radius:7px; background:var(--card); color:var(--ink); max-width:100% }
.cols label.req span::after { content:" — обязательно"; color:var(--at_risk) }
.stlist { display:grid; gap:5px; font-size:13px }
.stlist label { display:flex; gap:8px; align-items:baseline; cursor:pointer }
.stlist .n { color:var(--muted); font-size:12px }
.preview { overflow:auto; margin-top:4px }
/* Образец строк — не отчёт: столбцы по содержимому. Иначе четыре колонки делят
   ширину поровну и сумма уезжает от услуги на полпанели. */
.preview table { width:auto; min-width:0; font-size:12px; table-layout:auto }
.preview td, .preview th { white-space:nowrap }
.preview .num { text-align:right }
/* образец целиком в ширину панели: текстовые колонки делят остаток (max-width:0
   не даёт им раздвигать таблицу по содержимому) и режутся многоточием */
.preview table.fit { width:100% }
.preview td.ell { max-width:0; width:22% }
.preview td.ell.svc { width:56% }
.preview td.ell > div { overflow:hidden; text-overflow:ellipsis }
.flags { display:flex; flex-wrap:wrap; gap:14px; font-size:13px; align-items:center }
.flags label { display:flex; gap:7px; align-items:center; cursor:pointer }
.result { background:#fafafa; border-left:4px solid var(--active); border-radius:0 6px 6px 0; padding:10px 14px; font-size:13.5px }
.result.bad { border-left-color:var(--lost) }
.result ul { margin:6px 0 0; padding-left:18px }
.files { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px }
.files a { font:inherit; font-size:13px; padding:7px 12px; border-radius:7px; border:1px solid var(--line);
           background:var(--card); color:var(--ink); text-decoration:none }
.files a:hover { border-color:var(--ink) }
.warn { color:var(--at_risk); font-size:12.5px; margin-top:8px }
/* переходы групп после загрузки: строчка «опаздывает → вовремя, 12 человек» */
.moved { display:grid; gap:4px; margin-top:8px }
.moved div { display:flex; align-items:center; gap:7px; font-size:13px }
.moved .after { color:var(--active); font-size:12.5px; font-weight:500 }
.intake .actions { display:flex; align-items:center; gap:8px; margin-top:16px; padding-top:12px; border-top:1px solid var(--line); flex-wrap:wrap }
/* приём выгрузки: список файлов, ключ, «что уйдёт», плашка изолированного окна */
.drop .dropsub { display:block; font-size:12.5px; margin-top:4px }
.filelist { display:grid; gap:4px; margin-top:10px; font-size:13px }
.filelist span { color:var(--muted); font-size:12px; margin-left:6px }
.filelist .prev { color:var(--ink) }
.intake .howto { margin-top:14px; font-size:12.5px; color:var(--muted); line-height:1.5 }
.intake .howto b { color:var(--ink); font-weight:500 }
.keyline { margin-top:8px; color:var(--ink) }
.keyrow { margin-top:12px; padding:9px 12px; border-radius:7px; background:#fbf7ee; border:1px solid #efe3c8; font-size:12.5px; line-height:1.5 }
.keyrow.ok { background:#f2f7f3; border-color:#d6e6da }
.keyrow.bad { background:#fbf1ef; border-color:#ecd3cf }
.keyrow .linkbtn { margin-left:6px; cursor:pointer }
.fine { margin-top:10px } .fine summary { cursor:pointer; color:var(--muted); font-size:12.5px; user-select:none }
.sandbox { display:flex; flex-wrap:wrap; gap:4px 8px; align-items:center; margin-top:14px; font-size:12px; color:var(--muted) }
.sandbox .dot { width:8px; height:8px; border-radius:50%; background:var(--active); flex:none }
.sandbox code, .ship code, .result code { font-family:ui-monospace,"SF Mono",Menlo,monospace; font-size:11.5px; color:var(--muted) }
.sandbox a { color:var(--muted); text-decoration:underline dotted var(--line) 1px; text-underline-offset:3px }
.sandbox a:hover { color:var(--ink) }
.ship { display:grid; gap:8px }
.ship .item { border:1px solid var(--line); border-radius:8px; padding:9px 12px; font-size:12.5px }
.ship .t { font-weight:500 } .ship .t .muted { color:var(--muted); font-weight:400; margin-left:6px }
.ship .d { color:var(--muted); margin-top:3px; line-height:1.5 }
.ship .sum { margin-top:6px; display:flex; gap:10px; align-items:center; flex-wrap:wrap }
.ship .preview { margin-top:6px } .ship td.hash { font-family:ui-monospace,Menlo,monospace; color:var(--muted) }
/* кодовое слово — отдельное окно: его вводит владелец, и вокруг не должно быть ничего лишнего */
dialog#ask { width:min(92vw, 440px); padding:0; border:1px solid var(--line); border-radius:12px;
             box-shadow:0 24px 70px rgba(28,28,30,.28); color:var(--ink) }
dialog#ask::backdrop { background:rgba(28,28,30,.42) }
.askform { padding:18px 20px; display:grid; gap:12px }
.askform h3 { margin:0; font-size:15px; font-weight:600 }
.askform p { margin:0; font-size:13px; color:var(--muted); line-height:1.5 }
.askform label { display:grid; gap:4px; font-size:12.5px; color:var(--muted) }
.askform label.show { display:flex; gap:7px; align-items:center; cursor:pointer }
@font-face { font-family:"rc-dots"; src:url(data:font/woff2;base64,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) format("woff2"); }
.askform input[type=text], .askform input:not([type]) { font:inherit; font-size:15px; letter-spacing:.02em; padding:8px 10px; border:1px solid var(--line); border-radius:7px }
/* Точки рисует шрифт (text-security, MIT), а поле остаётся обычным текстовым.
   В type=password macOS включает защищённый ввод и сам переводит раскладку на
   латиницу — кодовое слово по-русски в таком поле не набрать. */
.askform input.mask { font-family:"rc-dots", sans-serif }
.askform input:focus { outline:2px solid var(--ink); outline-offset:-1px; border-color:var(--ink) }
.askform p.fine { font-size:12px; margin-top:-7px }      /* пояснение под галкой — к ней же и прижато */
.askform .btns { display:flex; gap:8px; justify-content:flex-end; margin-top:4px }
.askform button { font:inherit; font-size:13px; padding:7px 14px; border-radius:7px; border:1px solid var(--line); background:var(--card); cursor:pointer }
.askform button.primary { background:var(--ink); color:#fff; border-color:var(--ink) }
/* Аккаунт: кто вошёл и три дела — пароль, кодовое слово, ключи. Пункты списком
   во всю ширину, раскрытый показывает форму прямо под собой; «Админки» здесь
   нет — она и так стоит в строке разделов. */
.account { display:grid; gap:12px; margin-top:4px; font-size:13.5px }
/* кружок прижат к верху: у владельца под именем ещё строка со списком бизнесов,
   и по центру он уезжал бы вниз относительно имени */
.account .me { display:flex; gap:11px; align-items:flex-start }
.account .ava { width:34px; height:34px; flex:none; border-radius:50%; background:var(--ink); color:#fff;
  display:flex; align-items:center; justify-content:center; font-size:15px; font-weight:600 }
.account .mw { min-width:0 }
.account .mw b { font-size:15px; font-weight:600; letter-spacing:-0.01em }
.account .sub2 { color:var(--muted); font-size:12.5px; line-height:1.35 }
.account .menu { display:grid; border-top:1px solid var(--line) }
.account .menu-item { display:flex; align-items:center; gap:8px; width:100%; text-align:left;
  padding:9px 2px; border:0; border-bottom:1px solid var(--line); border-radius:0; background:none; font-size:13.5px }
.account .menu-item:hover:not(:disabled) { background:var(--bg); border-color:var(--line) }
.account .menu-item > span { flex:1; min-width:0 }
.account .menu-item .aside { font-style:normal; color:var(--muted); font-size:12.5px }
.account .menu-item .ch { font-style:normal; color:#b9bbc1; font-size:13px; width:10px; text-align:center }
.account .menu-item.on { font-weight:500 }
.account .menu-body { padding:4px 2px 12px; border-bottom:1px solid var(--line) }
.account .menu-body .authform { margin-top:6px }
.account .row { display:flex; gap:8px; align-items:center }
.account .row #au-out { margin-left:auto; color:var(--lost) }
/* своя подсказка вместо title: у нативной задержка ~1 с и её нельзя поменять */
/* pre-line: перечисления (услуги, тренеры, часы) приходят с переносами —
   списком они читаются, а одной строкой через запятую нет */
#tip { position:fixed; z-index:20; max-width:min(320px, calc(100vw - 16px)); padding:7px 10px; border-radius:7px;
       background:var(--ink); color:#fff; font-size:12.5px; line-height:1.4; text-wrap:pretty;
       white-space:pre-line; pointer-events:none; opacity:0; transition:opacity .08s; }
#tip.on { opacity:1 }
#tip.list { max-width:min(600px, calc(100vw - 16px)); line-height:1.6 }
/* пальцем попадают грубее, поэтому на тач-экранах подсказка крупнее */
@media (pointer:coarse){ #tip { font-size:13.5px; padding:9px 12px } }
@media (max-width:1000px){ .kpis{grid-template-columns:repeat(3,1fr)} }
@media (max-width:860px){
  .kpis{grid-template-columns:1fr 1fr} .two{grid-template-columns:1fr}
  /* на узком экране делить окна на «слева» и «справа» нечем */
  .panels { flex-direction:column }
  #p-auth, #p-load, #p-help { max-width:none; width:auto; margin:0 }
}

/* Разделы — вторая строка шапки. Слева то, куда смотрим, справа окна, которые
   нужны из любого раздела: загрузка, настройки, справка. Подчёркивание цветом
   текста, а не плашка: вкладки бизнесов выше и так плашки, две сразу рябят. */
.sections { position:sticky; top:var(--head-h,54px); z-index:13; padding:0;
            background:rgba(255,255,255,.82); backdrop-filter:saturate(180%) blur(14px);
            border-bottom:1px solid var(--line) }
.srow { display:flex; gap:10px 24px; align-items:center; flex-wrap:wrap; max-width:var(--col); margin:0 auto; padding:6px 20px }
.sect { display:flex; gap:18px }
.sect button { font:inherit; font-size:13.5px; color:var(--muted); background:none; border:0; padding:3px 0;
               border-bottom:2px solid transparent; border-radius:1px; cursor:pointer }
.sect button:hover { color:var(--ink) }
.sect button.on { color:var(--ink); border-bottom-color:var(--ink); font-weight:500 }
.srow .links { margin-left:auto }

/* ---------- разделы «Черновик» и «В работе» ---------- */
.sec#sec-draft, .sec#sec-work { display:grid; gap:12px; align-content:start }
.sec#sec-draft[hidden], .sec#sec-work[hidden] { display:none }
.plan-head .ph-top { display:flex; gap:12px 18px; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; margin-bottom:12px }
.plan-head h2 { display:flex; gap:8px; align-items:center; font-size:15px; text-transform:none; letter-spacing:0; color:var(--ink) }
.plan-head .sub { color:var(--muted); font-size:12.5px }
.plan-head .actions { display:flex; gap:8px; flex-wrap:wrap }
.plan-head .ptitle { font:inherit; font-size:15px; font-weight:600; color:var(--ink); border:1px solid transparent; border-bottom:1px dashed #b9bcc4; border-radius:6px 6px 0 0; padding:2px 6px; margin-left:-7px; background:none; field-sizing:content; min-width:6ch; max-width:40ch; cursor:text }
.plan-head .ptitle:hover { border-color:var(--line); border-radius:6px }
.plan-head .ptitle:focus { outline:none; border-color:var(--ink); background:var(--card) }
/* черновик: шаблоны и люди рядом; столбцы фиксированной ширины, текстовые делят остаток поровну */
.pd-two { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:12px; align-items:start }
/* черновик: «По шаблонам» и «Люди» одной высоты (ряд дотягивает fill.js),
   длинная таблица прокручивается внутри карточки, а не тянет её */
#sec-draft .pd-two { align-items:stretch }
#sec-draft .pd-two .tbl-wrap { max-height:none }
@media (max-width:1000px){ .pd-two { grid-template-columns:1fr } }
.ptbl.fixed { table-layout:fixed; min-width:0 }
.ptbl.fixed th, .ptbl.fixed td { padding:5px 6px; overflow:hidden; text-overflow:ellipsis }
.ptbl.fixed .c-ch { width:28px } .ptbl.fixed .c-seg { width:112px } .ptbl.fixed .c-n { width:52px }
.ptbl.fixed .c-code { width:68px } .ptbl.fixed .c-x { width:30px }
.plan-people.ai .ptbl.fixed .c-code { width:100px }
.ptbl.fixed .ico { width:15px; height:15px; vertical-align:-3px }
.ptbl.fixed th .ico { width:13px; height:13px; color:var(--muted) }
.ptbl.fixed .xdel { width:22px; height:22px; font-size:17px }
.plan-people .tbl-wrap { max-height:520px; overflow:auto }
.aitag { display:inline-block; font-size:10px; font-weight:600; line-height:1; padding:2px 5px; border-radius:5px;
  background:#efeaf9; color:#6a55a8; vertical-align:1px; cursor:help }
.aiwhy { font-size:12.5px; line-height:1.45; padding:7px 10px; margin-bottom:8px; border-radius:8px; background:#f6f3fc }
dialog#ask:has(.askform.auto) { width:min(94vw, 500px) }
.askform.auto p.lead { text-wrap:pretty }
.askform.auto p.fine { margin-top:0; text-wrap:pretty }
.askform .aopt { display:grid; gap:6px; font-size:12.5px; color:var(--muted) }
.askform .aopt.two { grid-template-columns:1fr 1fr; gap:12px }
.askform .chks { display:flex; flex-wrap:wrap; gap:5px }
.askform .chks.segs { display:grid; grid-template-columns:repeat(3, 1fr) }
.askform label.chk { display:flex; align-items:center; gap:5px; padding:5px 8px; white-space:nowrap; border:1px solid var(--line);
  border-left:3px solid var(--c, var(--line)); border-radius:7px; color:var(--ink); cursor:pointer }
.askform input[type=number] { font:inherit; font-size:14px; padding:7px 10px; border:1px solid var(--line); border-radius:7px; width:100% }
.askform .aprog { display:grid; gap:6px; font-size:12.5px; color:var(--muted) }
.askform .aprog .ppbar { height:6px }
.sec .tag { font-size:11px; font-weight:500; padding:2px 7px; border-radius:10px; background:#eef0f3; color:var(--muted); text-transform:none; letter-spacing:0 }
.sec .tag.on { background:color-mix(in srgb, var(--active) 15%, transparent); color:var(--active) }
.plan-head .tiles { display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); gap:8px; margin:0 0 12px }
.plan-head .tile { border:1px solid var(--line); border-radius:8px; padding:8px 12px; display:grid; gap:2px }
.plan-head .tile b { font-size:20px; font-weight:600; font-variant-numeric:tabular-nums }
.plan-head .tile span { font-size:12px; color:var(--muted) }
.plan-head .tile.link { cursor:pointer } .plan-head .tile.link:hover { border-color:var(--ink) }
.plan-head .tile.warn b { color:var(--at_risk) } .plan-head .tile.bad b { color:var(--lost) }
.plan-head .tile.warn { margin-top:0; font-size:inherit }
/* «В работе»: осталось, полоса и плитки — одной строкой */
.wstats { display:grid; grid-template-columns:repeat(5, minmax(0, 1fr)); gap:8px }
.wstats .pbig { grid-column:span 2 } .wstats .wbar { grid-column:span 3 }
.wstats .tile span { white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.wstats .wbar span { white-space:normal }
.wstats .tile { padding:7px 10px }
.wstats .pbig { justify-items:center; align-content:center; padding:6px 16px }
.wstats .pbig b { font-size:24px; line-height:1.1 }
.wstats .wbar { align-content:center; gap:7px }
.wstats .wbar .ppbar { height:10px }
.wstats .wbar { gap:6px; align-content:start }
.wstats .wbar > * { min-width:0 }
.wstats .wtot { display:flex; justify-content:space-between; align-items:baseline; gap:10px; font-size:12px; color:var(--muted) }
.wstats .wtot span { white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.wstats .wtot span b { color:var(--ink); font-weight:600; font-size:inherit }
.wstats .wtot .pct { font-size:16px; font-weight:600; color:var(--active); font-variant-numeric:tabular-nums }
.wstats .wch { display:grid; grid-template-columns:52px minmax(0, 1fr) minmax(76px, max-content); gap:10px; align-items:center; font-size:12px }
.wstats .wch .l { color:var(--muted) }
.wstats .wch .n { font-variant-numeric:tabular-nums; text-align:right; white-space:nowrap; overflow:visible }
.wstats .wch .n i { font-style:normal; color:var(--muted) }
.wstats .wch .ppbar { height:8px }
.wstats .wpace { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:8px; margin-top:4px; padding-top:7px; border-top:1px solid var(--line) }
.wstats .wpace .wp { display:grid; gap:1px; min-width:0 }
.wstats .wpace b { font-size:14px; font-weight:600; font-variant-numeric:tabular-nums; line-height:1.2 }
.wstats .wpace span { font-size:11px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.wstats .pbig .sub { font-size:11.5px; color:var(--muted) }
.wstats .wurg { gap:4px }
.wstats .wurg .wq-tabs { margin-bottom:4px }
.wstats .wurg .wq-tabs button { font-size:12px; padding:3px 9px }
.wstats .wurg .wq-tabs b { font-size:inherit; line-height:inherit; margin-left:2px }
.wdue { display:inline-block; font-size:11.5px; padding:1px 8px; border-radius:9px; white-space:nowrap;
  background:color-mix(in srgb, var(--at_risk) 14%, var(--card)); color:color-mix(in srgb, var(--at_risk) 70%, #000) }
.wdue.ok { background:color-mix(in srgb, var(--active) 12%, var(--card)); color:var(--active) }
.wdue.late { background:color-mix(in srgb, var(--lost) 14%, var(--card)); color:var(--lost) }
.wstats .wurg .wsplit { display:grid; grid-template-columns:1fr 1fr; width:100%; margin:2px 0 }
.wstats .wurg .wsplit > div { display:grid; justify-items:center; gap:1px; min-width:0 }
.wstats .wurg .wsplit > div + div { position:relative }
.wstats .wurg .wsplit > div + div::before { content:''; position:absolute; left:0; top:3px; height:16px; border-left:1px solid var(--line) }
.wstats .wurg .wsplit b { font-size:18px; line-height:1.2; font-weight:600; font-variant-numeric:tabular-nums; white-space:nowrap }
.wstats .wurg .wsplit span { font-size:11.5px; color:var(--muted) }
.wstats .wurg .wdate b { color:color-mix(in srgb, var(--at_risk) 75%, #000) }
.wstats .wurg .wdate.ok b, .wstats .wurg .wdate.ok span { color:var(--active) }
.wstats .wurg .wdate.late b, .wstats .wurg .wdate.late span { color:var(--lost) }
/* очередь слева, человек справа */
/* высоту ряда задаёт правый блок с текстами; очередь в неё вписывается
   и прокручивается внутри, а не тянет страницу вниз */
.filled { align-items:stretch }   /* ряд дотянут до низа окна (fill.js) — карточки вместе с ним */
.work-top, .work-two { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); align-items:stretch }
.work-top { margin-bottom:12px }
.work-top .ph-top h2 { font-size:16px }
/* «По шаблонам» вписывается в высоту шапки. Крутится таблица: заголовок
   карточки стоит, шапка столбцов лежит сверху сплошной полосой. */
.work-top > .card { min-height:250px }
.work-top .wtpl { contain:size; overflow:hidden; display:flex; flex-direction:column; min-height:0 }
.work-top .wtpl > h3 { flex:none }
.work-top .wtpl .tbl-wrap { flex:1; min-height:0; max-height:none; overflow:auto }
.work-top .plan-head { display:flex; flex-direction:column; justify-content:space-between }
.work-top .wstats .tile { padding:10px 12px }
/* в одном ряду с высокой полосой прогресса: число и подпись — вместе, по центру */
.wstats .tile:not(.pbig):not(.wbar) { align-content:center; justify-items:center; text-align:center; gap:4px }
/* у владельца шаблонов рядом нет — шапка во всю ширину, плитки одной строкой */
.work-top.solo { grid-template-columns:minmax(0, 1fr) }
.work-top.solo > .card { min-height:0; gap:0; padding:12px 16px }
/* шапка плана в одну строку: название, дата и кто зафиксировал — рядом */
.work-top .ph-top { margin-bottom:10px; align-items:center; flex-wrap:nowrap }
.work-top .ph-top > div:first-child { display:flex; align-items:baseline; gap:12px; min-width:0; flex:1 }
.work-top .ph-top h2 { flex:none; white-space:nowrap }
.work-top .ph-top .sub { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.work-top .ph-top .actions { flex:none; flex-wrap:nowrap }
.work-top.solo .wstats { grid-template-columns:repeat(10, minmax(0, 1fr)) }
@media (max-width:1000px){ .work-top.solo .wstats { grid-template-columns:repeat(5, minmax(0, 1fr)) } }
.ptbl.fixed .c-n2 { width:60px } .ptbl.fixed .c-done { width:92px }
.work-two .wqueue { contain:size; min-height:440px; display:flex; flex-direction:column; overflow:hidden }
.wq-bar { display:flex; flex-wrap:wrap; gap:8px; justify-content:space-between; margin-bottom:10px }
.wq-tabs { display:inline-flex; gap:2px; background:#eef0f3; padding:3px; border-radius:9px }
.wq-tabs button { white-space:nowrap; padding:5px 8px }
.wq th.sortable { cursor:pointer; user-select:none }
.wq th.sortable:hover, .wq th.sortable.on { color:var(--ink) }
.wq-bar { gap:6px }
.wq-tabs button svg { vertical-align:-2px }
.wq-tabs button { border:0; background:none; padding:5px 11px; border-radius:7px; cursor:pointer; font:inherit; font-size:12.5px; color:var(--muted) }
.wq-tabs button b { font-weight:600; margin-left:3px }
.wq-tabs button.on { background:var(--card); color:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,.1) }
.wqueue .tbl-wrap { flex:1; min-height:0; max-height:none; overflow:auto }
.ptbl.fixed .c-st { width:26px }
.wq .wrow { cursor:pointer } .wq .wrow:hover td { background:#f8f9fb }
.wq .wrow.sel td { background:color-mix(in srgb, var(--active) 9%, transparent) }
.wq .wrow.over td { color:var(--muted) }
.wst { font-size:12px } .wst.todo { color:var(--at_risk) } .wst.done { color:var(--active); font-weight:600 } .wst.declined { color:var(--lost) }
.wq-empty { margin:6px 0 }
.wpanel .wp-head { display:flex; align-items:center; gap:10px; flex-wrap:nowrap; margin-bottom:14px }
.wpanel .wp-head .pill { flex:none }
.wpanel .wp-head .who { font-size:14px; font-weight:600; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.wpanel .wp-head .tel { flex:none; border:0; border-bottom:1px dashed var(--line); background:none; padding:0;
  font:inherit; font-size:14px; color:var(--ink); cursor:pointer; white-space:nowrap }
.wpanel .wp-head .tel:hover { border-bottom-color:var(--ink) }
.wpanel .wp-head .code { flex:none; font-family:ui-monospace,"SF Mono",Menlo,monospace; font-size:12px; color:var(--muted) }
.wpanel .wp-head .nav { margin-left:auto; flex:none; display:flex; gap:6px }
.wpanel .wp-head .ghost { flex:none }
.wpanel .wp-facts { margin-bottom:14px }
.wpanel .wp-facts .nums { grid-template-columns:repeat(3, minmax(0, 1fr)) }
/* цифры человека плитками — одинаково в панели «В работе» и в полном окне */
.wpanel .wp-facts .nums, .client .profile .nums { gap:8px }
.wpanel .wp-facts .nums .n, .client .profile .nums .n { flex-direction:column; justify-content:flex-start; gap:3px;
  padding:9px 12px; border:0; border-radius:10px; background:#f6f7f9 }
.wpanel .wp-facts .nums .n span, .client .profile .nums .n span { font-size:11.5px }
.wpanel .wp-facts .nums .n b, .client .profile .nums .n b { font-size:15px; font-weight:600;
  font-variant-numeric:tabular-nums; letter-spacing:-.01em }
.wpanel .wp-facts .nums .n.late, .client .profile .nums .n.late { background:color-mix(in oklab, var(--c) 12%, #fff) }
.wpanel .wp-facts .nums .n.late b, .client .profile .nums .n.late b { color:color-mix(in oklab, var(--c) 75%, #000) }
.client .profile .nums { margin-bottom:14px }
@media (max-width:1000px){ .work-two .wqueue, .work-top .wtpl { contain:none; min-height:0 } .work-top .wtpl { max-height:320px } .wqueue .tbl-wrap { max-height:420px } }
.plegend { display:flex; gap:4px 14px; flex-wrap:wrap; margin-top:7px; font-size:12px; color:var(--muted) }
.plegend span { display:inline-flex; gap:5px; align-items:center }
.plegend span::before { content:""; width:8px; height:8px; border-radius:2px; background:var(--c) }
.plegend b { color:var(--ink); font-weight:600 } .plegend i { font-style:normal }
.ppbar { height:12px; border-radius:6px; background:#eef0f3; overflow:hidden }
.ppbar i { display:block; height:100%; background:var(--active); border-radius:6px }
.sec h3 { font-size:13px; margin:0 0 8px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:0.04em; display:flex; gap:8px; align-items:center }
.sec h3.gap { margin-top:16px }
.ptbl { width:100%; border-collapse:collapse; font-size:13px; table-layout:auto }
.ptbl th { text-align:left; font-weight:500; font-size:11.5px; color:var(--muted); padding:5px 8px; border-bottom:1px solid var(--line); white-space:nowrap }
.ptbl td { padding:6px 8px; border-bottom:1px solid #f0f1f4; vertical-align:middle; white-space:nowrap }
.ptbl .n { text-align:right; font-variant-numeric:tabular-nums }
.ptbl td.t { max-width:320px; overflow:hidden; text-overflow:ellipsis }
.ptbl .muted, .ptbl i.muted { color:var(--muted); font-style:normal } .ptbl .warn { color:var(--at_risk) } .ptbl .bad { color:var(--lost) }
.ptbl .linkbtn { color:var(--ink); text-decoration:underline dotted; text-underline-offset:3px }
.ptbl .mono { font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12px }
.segchip { display:inline-flex; gap:4px; align-items:center; font-size:12px; margin-right:8px }
.segchip::before { content:""; width:8px; height:8px; border-radius:50%; background:var(--c) }
.segchip b { font-weight:500; color:var(--muted) }
.ptbl.prev .prow { cursor:pointer } .ptbl.prev .prow:hover td { background:#f8f9fb }
.ptbl.prev .caret { display:inline-block; font-size:10px; color:var(--muted); transition:transform .15s }
.ptbl.prev .prow.open .caret { transform:rotate(90deg) }
.ptbl.prev .pdetail > td { background:#fafbfc; padding:6px 10px 12px }
/* разбивка раскрытого плана лежит внутри уже прокручиваемой таблицы */
.ptbl.prev .pdetail .tbl-wrap { max-height:none; overflow:visible }
.declines { margin:0; padding-left:18px; font-size:13px; display:grid; gap:4px }
.declines i { color:var(--muted) }
.plan-empty .row { margin-top:12px }
@media (max-width:760px){ .plan-head .tiles { grid-template-columns:repeat(2, minmax(0,1fr)) } }

/* ---------- раздел «Журнал» ---------- */
.jrfilters { display:flex; gap:8px 12px; flex-wrap:wrap; align-items:flex-end; margin:10px 0 12px }
.jrfilters label { display:grid; gap:4px; font-size:12px; color:var(--muted) }
.jrfilters select, .jrfilters input { font:inherit; font-size:12.5px; padding:5px 8px; border:1px solid var(--line);
  border-radius:7px; background:var(--card); color:var(--ink) }
.jrfilters select { appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:28px;
  background:var(--card) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b6b70' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 9px center / 10px 6px }
.jrfilters .chk { display:flex; gap:6px; align-items:center; font-size:12.5px; color:var(--ink); padding-bottom:7px; cursor:pointer }
.jrfilters .chk input { margin:0; padding:0 }
.jrfilters .search { flex:1 1 200px } .jrfilters .search input { width:100% }
/* клиент — колонкой кода: по нему ищут человека в «Клиентах» */
.jrlog { display:grid; grid-template-columns:max-content max-content fit-content(160px) max-content minmax(0,1fr); column-gap:12px;
  font-size:12.5px; align-content:start }
.jrlog .e { grid-column:1/-1; display:grid; grid-template-columns:subgrid; padding:4px 0; border-bottom:1px solid var(--line); align-items:baseline }
.jrlog .e:last-child { border-bottom:0 }
.jrlog .ts { color:var(--muted); white-space:nowrap; font-size:12px }
.jrlog .who { font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.jrlog .biz { color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.jrlog .code { font-family:ui-monospace,"SF Mono",Menlo,monospace; font-size:12px; color:var(--muted) }
.jrlog .txt { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0 }
.jrlog .d { color:var(--muted) } .jrlog .a { color:var(--ink) }
.jrlog .k-switch .a { color:#a86b1c; font-weight:500 } .jrlog .k-decline .a { color:var(--lost); font-weight:500 }
.jrlog .k-done .a { color:var(--active) }
.jrlog .tpl[data-tip] { color:var(--ink); border-bottom:1px dashed #c6c8ce; cursor:help }
.jrlog .pl, .jrlog .rs { font-size:11px; padding:1px 6px; border-radius:8px; background:#eef0f3; color:var(--muted); margin-left:4px }
.jrlog .rs { background:#fdf3e3; color:#a86b1c }
.jrmore { display:flex; justify-content:center; margin-top:12px }
@media (max-width:760px){ .jrlog { grid-template-columns:1fr } .jrlog .txt { white-space:normal } }

/* ---------- телефон (iPhone 17 — 402px) ----------
   Шапка уезжает вместе со страницей, а приклеенной остаётся строка разделов:
   иначе две липкие полосы съедают треть экрана. Вкладки не переносятся,
   а листаются вбок — так строка всегда одной высоты. */
@media (max-width:430px){
  header { position:static; padding:8px 0 }
  .hrow { gap:8px 12px; padding:0 12px }
  .hrow .auth { order:1; margin-left:auto; padding-left:12px }
  #tabs { order:2; margin-left:0; width:100%; overflow-x:auto; scrollbar-width:none }
  .tabs button, .onlyb { flex:none; white-space:nowrap; padding:6px 11px }
  .asof { order:3; margin-left:0; gap:6px }
  .sections { top:0 }
  .srow { gap:2px 14px; padding:4px 12px }
  .sect { width:100%; gap:16px; overflow-x:auto; scrollbar-width:none }
  .sect button { flex:none; white-space:nowrap; padding:7px 0 5px }
  .srow .links { margin-left:0; gap:12px; padding-bottom:2px }
  #tabs::-webkit-scrollbar, .sect::-webkit-scrollbar { display:none }
  main { padding:12px 10px; gap:12px }
  .card { padding:12px 12px }
  /* меню фильтров — во всю ширину строки фильтров, а не от своей кнопки:
     у правых кнопок оно уезжало за край экрана */
  .filters { position:relative }
  .flt { position:static }
  .flt .menu { top:auto; left:0; right:0; min-width:0; margin-top:4px }
  .dleg { flex-wrap:wrap; justify-content:flex-start; gap:2px 12px }
  .tpllist { flex:none; max-height:300px }
  #tpl-edit .fgrid.sms { grid-template-columns:minmax(0, 1fr) minmax(0, 1fr) }
  /* шесть групп в строку на телефоне — одни многоточия; по три в ряд читаются */
  #tpl-edit .segpick, .gencard .segpick { flex-wrap:wrap }
  #tpl-edit .segpick .seg, .gencard .segpick .seg { flex:1 1 30% }
  #tpl-edit .tplmeta { flex-wrap:wrap }
  #tpl-edit .slots { display:flex; flex-wrap:wrap; justify-content:flex-start; margin-left:0 }
  /* «В работе» в одну колонку: выбранный человек сверху, очередь под ним —
     «Следующий →» и так ведёт по очереди, листать к панели не нужно */
  .work-top, .work-two { grid-template-columns:minmax(0, 1fr) }
  .work-two .wpanel { order:-1; scroll-margin-top:64px }
  .work-top > .card { min-height:0 }
  .plan-head .tiles { grid-template-columns:repeat(3, minmax(0, 1fr)); gap:6px }
  .plan-head .tile { padding:7px 9px }
  .wstats { gap:5px }
  .work-top .wstats .tile { padding:7px 3px 7px 6px }
  .work-top .wstats .tile span { font-size:10px; text-overflow:clip }
  /* окно клиента — одна прокрутка на всё тело: в сетке с рядом 1fr сценарий
     сплющивался в ноль и наезжал на профиль */
  .client .body { display:flex; flex-direction:column; overflow:auto }
  .client .col { flex:none; overflow:visible }
  .client .profile .nums { grid-template-columns:repeat(3, minmax(0, 1fr)) }
  .wpanel .wp-facts .nums .n, .client .profile .nums .n { padding:8px 9px }
  .wpanel .wp-facts .nums .n b, .client .profile .nums .n b { font-size:14px; white-space:nowrap }
  .wpanel .wp-facts .nums .n span, .client .profile .nums .n span { font-size:11px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
  .wpanel .wp-head { flex-wrap:wrap; row-gap:8px }
  .wpanel .wp-head .nav { width:100%; margin-left:0 }
  .wpanel .wp-head .nav > * { flex:1 1 0 }
  /* окна аккаунта, загрузки и справки — во всю ширину экрана, а не по содержимому */
  .panels { align-items:stretch; padding:0 10px }
  /* бизнес один — имя строкой рядом с датой, без серой плашки на всю ширину */
  #tabs:has(> .onlyb) { order:3; width:auto; background:none; padding:0 }
  .onlyb { background:none; box-shadow:none; padding:0; font-size:15px; font-weight:600 }
  .hrow:has(.onlyb) .asof { order:4; margin-left:auto }
  /* перенос строки после логотипа и аккаунта: иначе короткое имя встаёт к ним */
  .hrow:has(.onlyb)::after { content:""; order:2; flex-basis:100%; height:0; margin-bottom:-8px }
  .hrow .auth { border-left:0; padding-left:0 }
  /* название плана и «с какого числа» — в две строки, а не многоточием */
  .work-top .ph-top > div:first-child { flex-direction:column; align-items:flex-start; gap:2px }
  .work-top .ph-top .sub { white-space:normal }
  /* сроки и выполнение — на всю ширину, пять счётчиков строкой под ними */
  .wstats .pbig, .wstats .wbar { grid-column:1 / -1 }
  .work-top .wstats .pbig { padding:8px 12px }
  .work-top .wstats .wbar { padding:10px 12px }
  /* группы: «весь список» строкой, шесть групп по три, люди и деньги — в две строки */
  .segtabs { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:6px }
  .segtabs button { min-width:0; padding:6px 9px 7px }
  .segtabs button[data-seg=""] { grid-column:1 / -1; display:flex; align-items:baseline; gap:10px }
  .segtabs button:not([data-seg=""]) span i { display:block }
  .segtabs button:not([data-seg=""]) span i + i::before { content:none }
  /* карточки людей — прямо на фоне, без второй рамки вокруг */
  #clients { background:none; border:0; padding:0 }
  .cards .ccard { align-items:center; padding:11px 13px }
}
