/* Vale поверх дизайн-системы Sollo. app.css — её копия без правок (обновлять целиком),
   здесь только своё: палитра «бутылочное стекло» и вёрстка под телефон. */

:root{
  --primary:#1aa394; --primary-strong:#128578; --primary-soft:#e2f4f1;
  --primary-2:#2a8fc4;   /* хвост фирменного градиента: бирюза → голубой */
  --accent:#3cc6b4;
  --bg:#f3f7f7; --bg-2:#ecf3f2; --surface-2:#f4f8f8;
  --text:#22393d; --muted:#7a9096;
}

/* тени, которые в app.css заданы числом (синие), — в тон палитре */
.avatar{box-shadow:0 6px 14px rgba(26,163,148,.25);}
.tb-user .avatar:hover{box-shadow:0 8px 18px rgba(26,163,148,.38);}
.pill.role{box-shadow:0 8px 18px rgba(26,163,148,.28);}
.status-ok{box-shadow:0 14px 32px rgba(26,163,148,.24);}
.btn{box-shadow:0 8px 18px rgba(26,163,148,.25);}
.toast{box-shadow:0 14px 32px rgba(26,163,148,.28);}

/* Появление страницы — сдвигом через margin-top, а не transform, как в app.css: transform делает .panel
   «коробкой» для position:fixed, и модалка, открытая уже при загрузке (ошибка в форме), первые 0,4 с
   стояла вверху без затемнения, а потом прыгала на место. */
.panel{animation:vale-panel-in .4s var(--ease);}
@keyframes vale-panel-in{from{opacity:0;margin-top:10px;}to{opacity:1;margin-top:0;}}

/* Кнопкам браузер даёт свой шрифт (Arial) и не передаёт им межбуквенный интервал страницы: «Новая сделка»
   кнопкой на доске выглядела иначе, чем такая же ссылкой в списке (20.10). Календарь Sollo прописывал это каждой
   своей кнопке — здесь всем сразу; класс со своим шрифтом (.tb-info) по-прежнему главнее. */
button{font-family:inherit;letter-spacing:inherit;}

.side-foot a.me-link{display:block;min-width:0;color:inherit;}
/* телефоны контрагента под названием в справочнике: номер не рвётся по дефисам, переносятся только целые номера */
.cp-phone{display:block;margin-top:2px;font-weight:400;}
.cp-phone span{white-space:nowrap;}
.side-foot a.me-link:hover b{color:var(--primary-strong);}

/* ── учёт ── */
/* фильтры-«чипы» ссылками (в app.css стили только для кнопок) */
.chips{flex-wrap:wrap;}
.chips a{padding:8px 16px;border-radius:9px;font-size:13px;font-weight:600;color:var(--muted);transition:all .2s var(--ease);}
.chips a:hover{color:var(--text);}
.chips a.on{background:var(--primary-soft);color:var(--primary-strong);}
.card.sel{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft);}
.field[hidden]{display:none;}
.amt-pos{color:var(--green-ink);font-weight:600;}
.amt-neg{color:var(--rose-ink);font-weight:600;}
.linkbtn{border:0;background:none;padding:0;color:var(--primary-strong);font:inherit;font-weight:600;cursor:pointer;}
.linkbtn:hover{text-decoration:underline;}
/* расчёт сделки: строки «продажа → … → чистая» */
.calc{width:100%;font-size:13.5px;}
.calc td{padding:9px 2px;border-bottom:1px solid var(--border);}
.calc tr:last-child td{border-bottom:0;}
.calc tr.sum td{font-weight:700;}
.calc tbody tr:hover{background:none;}
/* пары «подпись — значение» в карточках */
.kv{display:grid;grid-template-columns:max-content 1fr;gap:9px 18px;margin:0;font-size:13.5px;}
.kv dt{color:var(--muted);}
.kv dd{margin:0;min-width:0;}
/* многострочное поле — как однострочные (.field input) */
.field textarea{min-height:88px;border:1px solid var(--border-2);border-radius:13px;padding:11px 14px;font-size:14px;line-height:1.45;color:var(--text);background:var(--surface);outline:none;resize:vertical;font-family:inherit;transition:border .18s,box-shadow .18s;}
.field textarea:focus{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);}
/* ── контрагенты: поиск с фильтрами одной строкой, карточка с контактными лицами ── */
.cp-bar{display:flex;gap:12px;align-items:stretch;margin-bottom:14px;}
.cp-bar .searchbar{flex:1;margin-bottom:0;}
.cp-bar .field{margin-bottom:0;}
.cp-scope{min-width:190px;}
@media (max-width:760px){.cp-bar{flex-wrap:wrap;}.cp-bar .searchbar{flex:1 1 100%;}.cp-bar>.cp-scope{flex:1 1 100%;}}
.cp-wrap{overflow-wrap:anywhere;}
.cp-tags{display:flex;flex-wrap:wrap;gap:5px;}
/* заметки из amoCRM — с переносами строк и бывают длинными: окно с прокруткой, а не карточка в полэкрана */
.cp-note{margin-top:10px;max-height:260px;overflow:auto;white-space:pre-line;overflow-wrap:anywhere;font-size:13.5px;}
.person{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--border);}
.person:first-of-type{margin-top:12px;}
.person-main{flex:1;min-width:0;font-size:13.5px;}
.person-links{margin-top:3px;overflow-wrap:anywhere;}
.person-note{margin-top:4px;white-space:pre-line;overflow-wrap:anywhere;max-height:120px;overflow:auto;}
.person-act{display:flex;gap:6px;flex:none;}
.person-act form{margin:0;}
/* окно с длинной формой (карточка контрагента, контактное лицо): поля по два-три в ряд, а не каждое во всю ширину;
   не влезло по высоте — окно прокручивается, а не уходит верхом за край экрана */
.modal-overlay.tall{overflow-y:auto;align-items:flex-start;}
.modal-overlay.tall>.modal{margin:auto 0;}
.modal-overlay .dds-form.pair .field{flex:1 1 150px;min-width:0;}
.modal-overlay .dds-form.pair .field.grow{flex:1 1 240px;}
.modal-overlay .dds-form.pair .field.wide{flex:1 1 100%;}
/* контакт сделки — выбором прямо в строке над сделкой */
.deal-person{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px 6px;}
.deal-person form{margin:0;}
.deal-person .sel-in{height:32px;max-width:260px;}
/* ── форма сделки (из Finuchet): «Карточка», «Блоки», «Таблица» — поля одни, раскладка своя ── */
.deal-form .num-in{text-align:right;font-variant-numeric:tabular-nums;width:100%;min-width:0;}
.deal-form .lined>div[hidden],.deal-form .badge[hidden]{display:none;}
.deal-form .ro-input{background:var(--surface-2);font-weight:700;font-variant-numeric:tabular-nums;cursor:default;}
.deal-form .ro-input:focus{border-color:var(--border-2);box-shadow:none;}
.deal-form .price-vat{display:flex;align-items:center;justify-content:flex-end;gap:6px;}
.deal-form .price-vat .num-in{width:104px;}
.deal-form .vat-sel{flex:none;width:78px;}
/* поля с поиском (static/js/combo.js) — в форме сделки и в новой сделке на доске; подсказки — над модалками (200) */
.combo{position:relative;min-width:0;}
.combo-in{width:100%;height:38px;border:1px solid var(--border-2);border-radius:11px;padding:0 12px;background:var(--surface);font-family:inherit;font-size:13.5px;color:var(--text);outline:none;transition:border .18s,box-shadow .18s;}
.combo-in:focus{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);}
.combo-in::placeholder{color:var(--muted);}
.field .combo-in{height:44px;border-radius:13px;}
.combo-pop{position:fixed;z-index:210;background:var(--surface);border:1px solid var(--border-2);border-radius:12px;box-shadow:0 14px 38px rgba(20,40,60,.16);max-height:262px;overflow:auto;padding:5px;max-width:420px;}
.combo-pop[hidden]{display:none;}
.combo-item{padding:8px 11px;border-radius:9px;cursor:pointer;font-size:13.5px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.combo-item.active,.combo-item:hover{background:var(--primary-soft);}
.combo-item b{color:var(--primary);}
.deal-form .add-row.wide{display:flex;width:100%;justify-content:center;height:40px;}
.deal-actions{display:flex;justify-content:flex-end;gap:12px;margin-top:18px;}
/* шапка «Блоков» и «Таблицы» — одной строкой */
.fhead{display:flex;gap:14px 16px;flex-wrap:wrap;align-items:flex-end;margin-bottom:16px;}
.fhead .field{margin:0;min-width:150px;}
.fhead .field.grow{flex:1 1 200px;}
/* источник и срочность — по самому длинному варианту («Холодное касание», «Месяцы»), не на всю строку */
.deal-form .f-source{flex:none;width:180px;min-width:0;}
.deal-form .f-urgency{flex:none;width:108px;min-width:0;}
/* номер: поле по своему вводу — без общих 150px, из-за которых справа от него была пустота */
.deal-form .f-number{flex:none;min-width:0;}
.deal-form .f-number input{min-width:48px;}
/* «Таблица»: закупка ‖ продажа одной строкой */
.tform-tbl{width:100%;border-collapse:collapse;}
.tform-tbl th{font-size:11px;color:var(--muted);font-weight:600;padding:6px 10px;white-space:nowrap;}
.tform-tbl th.grp{font-size:12.5px;color:var(--text);font-weight:700;text-align:center;padding-bottom:3px;}
.tform-tbl th.ch{vertical-align:bottom;border-bottom:1px solid var(--border);padding-bottom:9px;}
.tform-tbl th.l{text-align:left;} .tform-tbl th.r{text-align:right;}
.tform-tbl td{padding:8px 10px;border-bottom:1px solid var(--border);vertical-align:middle;}
.tform-tbl .lsep{border-left:1px solid var(--border);}
.tform-tbl tbody tr:last-child td{border-bottom:none;}
.tform-tbl tbody tr:hover{background:none;}
.tform-tbl .lmar-cell{font-weight:700;white-space:nowrap;}
.tcalc{padding:16px 18px;}
.tcalc-wf{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-top:16px;padding-top:14px;border-top:1px solid var(--border);font-size:14px;}
.tcalc-wf .wf-k{color:var(--muted);font-size:12.5px;}
.tcalc-wf .wf-op{color:var(--muted);font-weight:700;}
.tcalc-wf .wf-net b{color:var(--green-ink);font-size:17px;}
/* «Блоки»: покупка → продажа → расходы → чистая */
.blk-flow .blk h3{display:flex;align-items:center;gap:9px;font-size:14px;margin-bottom:12px;}
.blk-flow .blk,.blk-flow .blk-net{flex:1 1 0;min-width:290px;width:auto;}   /* делят ширину; узко — лента прокручивается */
.blk-net .net-wf{margin-top:14px;}
.blk-net .net-wf>div{border-top:none;padding:4px 0;}
.bk-field{margin-bottom:10px;}
.bk-field>label{display:block;font-size:12px;color:var(--muted);margin-bottom:5px;font-weight:600;}
.bk-lines{display:flex;flex-direction:column;}
.bk-pos{padding:13px 0;border-top:1px dashed var(--border-2);display:flex;flex-direction:column;gap:8px;}
.bk-pos:first-child{border-top:none;padding-top:4px;}
.bk-top{display:flex;gap:6px;align-items:center;}
.bk-top .combo{flex:1;}
.bk-mirror-in{width:100%;height:38px;border:1px solid var(--border-2);border-radius:11px;padding:0 12px;background:var(--surface-2);font-family:inherit;font-size:13.5px;font-weight:600;color:var(--text);cursor:default;outline:none;text-overflow:ellipsis;}
.bk-mirror-in::placeholder{font-weight:400;color:var(--muted);}
.bk-qpv{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.bk-qpv .num-in{flex:1 1 70px;}
.bk-qpv .p-qty{flex:0 0 84px;}
.bk-pos-sum{flex-basis:100%;text-align:right;font-size:12px;color:var(--muted);font-weight:700;white-space:nowrap;}   /* итог строки — под полями */
.bk-pos-sum span{color:var(--text);}
.blk .add-row{margin:12px 0 14px;}   /* снизу — отступ до черты «Суммы закупки», иначе в самом высоком блоке кнопка лежит на ней */
/* просмотр сделки (из Finuchet): значки в шапке блока, «Таблица» с итогом и строкой-водопадом */
.blk-badges{margin-left:auto;display:inline-flex;gap:6px;flex-wrap:wrap;justify-content:flex-end;}
.deal-view .flow-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px 22px;padding:2px 4px 14px;}
.deal-view .flow-meta + .flow-meta{border-top:1px solid var(--border);padding-top:13px;}
.deal-view .flow-meta-k{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.03em;margin-right:7px;}
.deal-view .flow-arrow{color:var(--muted);margin:0 6px;}
.deal-view .flow-pc{font-size:15px;}
.deal-view .flow-badges{display:inline-flex;flex-wrap:wrap;gap:6px;}
.deal-view .flow-tbl{width:100%;border-collapse:collapse;margin-top:4px;}
.deal-view .flow-tbl th{font-size:11px;color:var(--muted);font-weight:600;padding:5px 10px;text-align:center;}
.deal-view .flow-tbl thead tr:last-child th{border-bottom:1px solid var(--border);padding-bottom:8px;}
.deal-view .flow-tbl th.grp{font-size:12.5px;color:var(--text);font-weight:700;padding-bottom:2px;}
.deal-view .flow-tbl td{padding:11px 10px;border-bottom:1px solid var(--border);font-variant-numeric:tabular-nums;}
.deal-view .flow-tbl td.num,.deal-view .flow-tbl th.num{text-align:right;white-space:nowrap;}
.deal-view .flow-tbl .lsep{border-left:1px solid var(--border);}
.deal-view .flow-tbl tbody tr:last-child td{border-bottom:2px solid var(--border-2);}
.deal-view .flow-tbl tbody tr:hover{background:none;}
.deal-view .flow-tot td{font-weight:750;border-bottom:none;padding-top:13px;font-size:14.5px;}
.deal-view .flow-tot td.pos{color:var(--green-ink);}
.deal-view .flow-wf{display:flex;flex-wrap:wrap;align-items:center;gap:7px 13px;margin-top:18px;padding:15px 18px;border-radius:14px;background:var(--surface-2);}
.deal-view .wf-term{display:inline-flex;align-items:baseline;gap:6px;font-variant-numeric:tabular-nums;}
.deal-view .wf-k{color:var(--muted);font-size:13px;}
.deal-view .wf-op{color:var(--muted);font-weight:700;}
.deal-view .wf-net{font-size:16px;}
.deal-view .wf-net b{color:var(--green-ink);}
.deal-lead{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 22px;margin:0 4px 16px;font-size:13.5px;}

/* ── доска сделок (deals/board.html): колонки-стадии, лента листается вбок, у колонки своя прокрутка вниз.
   Высота — экран без топбара (66): горизонтальная прокрутка всегда под рукой. Колонка 336 px, карточки 320 —
   длинным названиям клиентов и «что хочет» хватает места (просьбы 20 и 21.10); на 1440 видно четыре ── */
/* топбар доски в тесноте (закреплённый блокнот в окне 1100–1250) не уводит «Новую сделку» под блокнот (21.10): сначала
   сжимается заголовок — подзаголовок одной строкой с многоточием, до «Сделки (i)», — потом поиск, до 140. Строку режет
   line-clamp, а не nowrap: с nowrap заголовок не сжимается уже всей строки подзаголовка */
/* поиск в топбаре — в высоту кнопок, в ширину своей подсказки и не шире (21.10): --ph — её длина в символах, ch — ширина
   символа этого шрифта, так подсказка влезает и в других шрифтах (Windows). Ширина, а не flex-basis: по ней топбар
   считает место под кнопки */
.tb-search{width:calc(var(--ph, 28) * 1ch + 26px);min-width:140px;height:44px;-webkit-appearance:none;appearance:none;}
/* фильтр страницы — выпадающим списком в топбаре, как в Sollo (21.10) */
.tb-filter{display:flex;gap:8px;flex:none;margin:0;}
.tb-filter .field{margin:0;min-width:0;}   /* по содержимому: выбранный пункт и стрелка */
.tb-filter .rp-trigger{min-width:0;width:auto;white-space:nowrap;}   /* период — по короткой подписи */
/* «Сделки → Список»: в топбаре ещё и период, поэтому тесно здесь раньше, чем на других страницах (замер 26.10).
   Ступень 1, как у всех страниц с фильтром: «Новая сделка» — «+», переключатель плотнее, без разделителя —
   и шире обычного: до 1100, с закреплённым блокнотом до 1520 */
@media (min-width:1061px) and (max-width:1100px){
  .topbar:has(#dealsFilter) .pill.role{padding:0 14px;} .topbar:has(#dealsFilter) .pill.role .tb-lbl{display:none;}
  .topbar:has(#dealsFilter) .chips a{padding-left:11px;padding-right:11px;} .topbar:has(#dealsFilter) .tb-div{display:none;}
}
@media (min-width:1367px) and (max-width:1520px){
  .nb-docked .topbar:has(#dealsFilter) .pill.role{padding:0 14px;} .nb-docked .topbar:has(#dealsFilter) .pill.role .tb-lbl{display:none;}
  .nb-docked .topbar:has(#dealsFilter) .chips a{padding-left:11px;padding-right:11px;} .nb-docked .topbar:has(#dealsFilter) .tb-div{display:none;}
}
/* ступень 2 — период одной иконкой (что выбрано — в подсказке и в итоге над таблицей), промежутки уже.
   Стрелка — только у периода: у выпадающего списка статуса тот же класс .rp-chev */
@media (min-width:761px) and (max-width:950px){
  .topbar:has(#dealsFilter) .tb-actions{gap:10px;}
  .topbar:has(#dealsFilter) .rp .rp-label, .topbar:has(#dealsFilter) .rp .rp-chev{display:none;}
  .topbar:has(#dealsFilter) .rp-trigger{width:44px;padding:0;gap:0;justify-content:center;}
  .topbar:has(#dealsFilter) .rp-has .rp-trigger{border-color:var(--primary);}   /* период выбран — видно и без подписи */
  .topbar:has(#dealsFilter) .rp-has .rp-trigger .ic{color:var(--primary);}
}
@media (min-width:1100px) and (max-width:1400px){
  .nb-docked .topbar:has(#dealsFilter) .tb-actions{gap:10px;}
  .nb-docked .topbar:has(#dealsFilter) .rp .rp-label, .nb-docked .topbar:has(#dealsFilter) .rp .rp-chev{display:none;}
  .nb-docked .topbar:has(#dealsFilter) .rp-trigger{width:44px;padding:0;gap:0;justify-content:center;}
  .nb-docked .topbar:has(#dealsFilter) .rp-has .rp-trigger{border-color:var(--primary);}
  .nb-docked .topbar:has(#dealsFilter) .rp-has .rp-trigger .ic{color:var(--primary);}
}
/* и этого мало (окно уже 830, с закреплённым блокнотом — уже 1220): кнопки — второй строкой, как на телефоне,
   а не за край */
@media (min-width:761px) and (max-width:830px){
  .topbar:has(#dealsFilter){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
}
@media (min-width:1100px) and (max-width:1220px){
  .nb-docked .topbar:has(#dealsFilter){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
}
/* топбар с фильтром в тесноте — узкое окно или закреплённый блокнот рядом: «Новая сделка» — одной иконкой,
   переключатель и фильтр плотнее, без разделителя; иначе кнопка уходит за край или под блокнот (21.10) */
@media (min-width:761px) and (max-width:1060px){
  .topbar:has(.tb-filter) .pill.role{padding:0 14px;} .topbar:has(.tb-filter) .pill.role .tb-lbl{display:none;}
  .topbar:has(.tb-filter) .chips a{padding-left:11px;padding-right:11px;} .topbar:has(.tb-filter) .tb-div{display:none;}
}
@media (min-width:1100px) and (max-width:1366px){
  .nb-docked .topbar:has(.tb-filter) .pill.role{padding:0 14px;} .nb-docked .topbar:has(.tb-filter) .pill.role .tb-lbl{display:none;}
  .nb-docked .topbar:has(.tb-filter) .chips a{padding-left:11px;padding-right:11px;} .nb-docked .topbar:has(.tb-filter) .tb-div{display:none;}
}
.topbar:has(.tb-search) .tb-title{flex-shrink:100;}
/* длинный заголовок (_topbar.html) — одной строкой с многоточием: сжимается он, а не кнопки справа (23.10) */
@media (min-width:761px){
  .tb-title.tb-long,.tb-long>div{min-width:0;}
  .tb-long h1,.tb-long .sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .topbar:has(.tb-long) .tb-actions{flex-shrink:0;}
}
/* «Почта» в тесноте (узкое окно или блокнот рядом): «Обновить» — иконкой, поиск уже, кнопки плотнее — иначе «Написать»
   уходит за край (23.10) */
@media (min-width:761px) and (max-width:1180px){
  .topbar .tb-sync{padding:0 14px;} .topbar .tb-sync .tb-lbl{display:none;}
  .topbar:has(.tb-sync) .tb-search{width:140px;} .topbar:has(.tb-sync) .tb-actions{gap:10px;}
}
/* ещё уже — кнопки второй строкой, как на телефоне */
@media (min-width:761px) and (max-width:880px){
  .topbar:has(.tb-sync){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
}
/* с блокнотом рядом топбару остаётся окно минус 30% (340–420px): то же, пока места меньше 1124px, и второй строкой —
   пока меньше 880px */
@media (min-width:1100px) and (max-width:1560px){
  .nb-docked .topbar .tb-sync{padding:0 14px;} .nb-docked .topbar .tb-sync .tb-lbl{display:none;}
  .nb-docked .topbar:has(.tb-sync) .tb-search{width:140px;} .nb-docked .topbar:has(.tb-sync) .tb-actions{gap:10px;}
  .nb-docked .topbar:has(.tb-sync) .pill.role{padding:0 14px;} .nb-docked .topbar:has(.tb-sync) .pill.role .tb-lbl{display:none;}
}
@media (min-width:1100px) and (max-width:1250px){
  .nb-docked .topbar:has(.tb-sync){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
}
.topbar:has(.tb-search) .sub{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;}
/* лента — на всю область страницы без отступов (margin −26 = отступ .scroll, 66 — высота топбара): шапки стадий идут
   сплошной полосой вплотную к топбару и к краям, между ними — тонкая линия зазора (21.10). Снизу колонки обрезает
   край окна (только полоса прокрутки вбок) */
.kb{display:flex;align-items:stretch;gap:2px;overflow-x:auto;height:calc(100vh - 66px);height:calc(100dvh - 66px);margin:-26px;}
.flash + #board .kb{margin-top:0;}   /* сообщение над доской — доска под ним, а не поверх */
/* у колонки своего фона нет: шапка во всю её ширину, под ней карточки 320 px по центру (21.10). min-width:0 — длинная
   шапка не раздувает колонку, название обрезается многоточием, целиком — в подсказке. Колонку, над которой держат
   карточку, обводит outline — рамка сдвигала бы шапки */
.kb-col{flex:0 0 336px;min-width:0;display:flex;flex-direction:column;min-height:0;transition:background .15s,flex-basis .2s var(--ease);}
.kb-col.drop{outline:2px solid var(--primary);outline-offset:-2px;background:var(--primary-soft);}
/* поиск: колонка, где ничего не нашлось, — полоска с названием сверху вниз (21.10): найденное в других подъезжает
   в окно, а сама она на виду — карточку в неё бросить можно, и тогда она раскрывается */
.kb-col.shrunk{flex-basis:44px;}
.kb-col.shrunk .kb-head{flex:1;margin:0;padding:14px 0;writing-mode:vertical-rl;justify-content:flex-start;}
.kb-col.shrunk .kb-list,.kb-col.shrunk .kb-sum,.kb-col.shrunk .kb-auto{display:none;}
/* шапка в одну строку, без скруглений: название слева, число сделок справа. Маржа колонки — в подсказке шапки,
   всей доски — в подзаголовке страницы */
.kb-head{flex:none;display:flex;align-items:center;gap:6px;margin-bottom:6px;padding:10px 12px;background:var(--tone);color:#fff;cursor:default;}
/* у каждой стадии свой цвет — по кругу вдоль воронки: синие заявки → сиреневая квалификация → розовое КП →
   оранжевая и жёлтая логистика → зелёная оплата; «Неразобранное» и «Не реализовано» — серые (21.10) */
.kb-col[data-stage="unsorted"]{--tone:#94a6b4;} .kb-col[data-stage="new"]{--tone:#69b6df;} .kb-col[data-stage="in_work"]{--tone:#5d8fdc;}
.kb-col[data-stage="qual_b"]{--tone:#8b84e0;} .kb-col[data-stage="qual_a"]{--tone:#ab7fd6;}
.kb-col[data-stage="kp_ready"]{--tone:#d67fb4;} .kb-col[data-stage="kp_defended"]{--tone:#e57f7f;}
.kb-col[data-stage="escort"]{--tone:#e99a5b;} .kb-col[data-stage="carrier"]{--tone:#dcae45;} .kb-col[data-stage="shipped"]{--tone:#a9b84a;}
.kb-col[data-stage="delivered"]{--tone:#6cb76a;} .kb-col[data-stage="paid"]{--tone:#3a9e6a;} .kb-col[data-stage="not_realized"]{--tone:#a5afb4;}
.kb-name{flex:1;min-width:0;font-size:13px;font-weight:700;line-height:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.kb-auto{display:inline-block;margin-left:2px;padding:0 7px;border-radius:20px;background:rgba(255,255,255,.22);color:#fff;font-size:10.5px;font-weight:650;line-height:17px;vertical-align:1px;cursor:help;}
.kb-sum{flex:none;font-size:12px;color:rgba(255,255,255,.92);font-variant-numeric:tabular-nums;white-space:nowrap;}
.kb-sum b{color:#fff;}
/* сверху 4 px — подсветка новой карточки и тень при наведении на первую не обрезаются краем прокрутки (21.10) */
.kb-list{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:9px;padding:4px 8px 12px;scrollbar-width:thin;}
/* тень карточки — короткая: длинная (--shadow, 28px) сливалась между карточками в серую дымку, а колонка обрезала её
   по своему краю — выходил «фон колонки» (20.10). Карточку отделяет рамка */
.kb-card{flex:none;background:var(--surface);border:1px solid var(--border-2);border-radius:13px;box-shadow:0 1px 2px rgba(22,52,56,.05);padding:11px 12px;cursor:pointer;transition:box-shadow .18s,opacity .18s,border-color .18s;}
.kb-card:hover{border-color:#d9e3e8;box-shadow:0 2px 6px rgba(22,52,56,.08);}
.kb-card:focus-visible{outline:2px solid var(--primary);outline-offset:-2px;}   /* внутрь: по бокам колонка обрезает всё, что за карточкой */
.kb-card[hidden]{display:none;}
.kb-card.dragging{opacity:.4;}
.kb-card.stuck{border-color:#f1d5d5;}
.kb-card.fresh{animation:kb-fresh 1.8s var(--ease);}   /* только что заведённая — подсвечена */
@keyframes kb-fresh{0%,45%{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft);}}
.kb-top{display:flex;align-items:flex-start;gap:8px;}
.kb-client{flex:1;min-width:0;font-size:13.5px;font-weight:700;line-height:1.3;overflow-wrap:anywhere;}
.kb-client:hover{color:var(--primary-strong);}
.kb-idle{flex:none;padding:1px 8px;border-radius:20px;background:var(--surface-2);color:var(--muted);font-size:11px;font-weight:700;line-height:17px;white-space:nowrap;}
.kb-idle.late{background:var(--rose-soft);color:var(--rose-ink);}
.kb-tel{display:inline-block;margin-top:3px;font-size:12px;font-weight:600;color:var(--primary-strong);}
.kb-wish{margin-top:5px;font-size:12.5px;line-height:1.4;color:var(--muted);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;}
.kb-money{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:2px 8px;margin-top:8px;font-size:13px;font-variant-numeric:tabular-nums;white-space:nowrap;}   /* большие суммы — маржа строкой ниже, а не за край карточки */
.kb-mar{color:var(--green-ink);font-size:12px;font-weight:650;}
.kb-pay{margin-top:7px;}
.kb-foot{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:11.5px;color:var(--muted);}
.kb-lose,.kb-snooze{border:0;background:none;padding:2px 0;font:inherit;font-weight:650;color:var(--muted);cursor:pointer;opacity:0;transition:opacity .15s,color .15s;}
.kb-snooze{margin-left:auto;}
.kb-snooze + .kb-lose{margin-left:0;}
.kb-lose{margin-left:auto;}
.kb-card:hover .kb-lose,.kb-lose:focus-visible,.kb-card:hover .kb-snooze,.kb-snooze:focus-visible{opacity:1;}
.kb-lose:hover{color:var(--rose-ink);}
.kb-snooze:hover{color:var(--amber-ink);}
/* «Отложить до даты»: отложенная — дата в углу вместо «когда трогали», в свой день — горит, сверху колонки */
.kb-remind{flex:none;display:inline-flex;align-items:center;gap:4px;padding:1px 8px;border-radius:20px;background:var(--surface-2);color:var(--muted);font-size:11px;font-weight:700;line-height:17px;white-space:nowrap;}
/* часы — маской, как трубка у телефона: доска приходит с сервера заново, и иконки из app.js в неё не вставлены */
.kb-remind::before{content:"";flex:none;width:11px;height:11px;background:currentColor;-webkit-mask:var(--ic-clock) center/contain no-repeat;mask:var(--ic-clock) center/contain no-repeat;}
:root{--ic-clock:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M12 7.5V12l3 1.8'/%3E%3C/svg%3E");}
.kb-remind.due{background:var(--amber-soft);color:var(--amber-ink);}
.kb-card.due{border-color:var(--amber);box-shadow:0 0 0 2px var(--amber-soft);}
/* две строки обрезает внутренний span: у самой плашки отступ, и в нём выглядывала бы третья строка */
.kb-due-note{margin-top:6px;padding:5px 9px;border-radius:9px;background:var(--amber-soft);color:var(--amber-ink);font-size:12px;line-height:1.4;}
.kb-due-note span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;}
/* Выбор стадии на компьютере не виден, но Tab до него доходит: мышью карточку тащат, клавиатурой — выбирают.
   Не display:none — спрятанный так список браузер пропускал при переходе по Tab. */
.kb-card{position:relative;}
.kb-stage{position:absolute;left:0;bottom:0;width:1px;height:1px;opacity:0;pointer-events:none;}
.kb-stage:focus-visible{position:static;width:100%;height:38px;opacity:1;pointer-events:auto;margin-top:9px;}
/* пока карточку тащат, внизу — «Отказ»: бросить туда, как в amoCRM */
.kb-drop-lose{position:fixed;left:50%;bottom:26px;z-index:60;transform:translateX(-50%);display:flex;align-items:center;gap:9px;padding:15px 40px;border:2px dashed var(--rose);border-radius:16px;background:var(--rose-soft);color:var(--rose-ink);font-size:14px;font-weight:700;box-shadow:0 14px 32px rgba(217,134,134,.22);transition:background .15s,transform .15s var(--ease);}
.kb-drop-lose[hidden]{display:none;}
.kb-drop-lose.drop{background:#f7dcdc;transform:translateX(-50%) scale(1.04);}
.kb-dragging .toasts{visibility:hidden;}   /* уведомления стоят там же, внизу по центру, и перехватывали бы бросок */

/* ── Sipuni (app/telephony, static/js/calls.js): телефоны звонят по клику, окно входящего, звонки в карточках ── */
:root{--ic-phone:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 16.4v3a2 2 0 0 1-2.2 2 18 18 0 0 1-7.8-2.8 17.7 17.7 0 0 1-5.4-5.4A18 18 0 0 1 2.8 5.3 2 2 0 0 1 4.8 3h3a2 2 0 0 1 2 1.7c.1.9.4 1.8.7 2.6a2 2 0 0 1-.5 2.1L8.7 10.7a14.5 14.5 0 0 0 5.4 5.4l1.3-1.3a2 2 0 0 1 2.1-.5c.8.3 1.7.6 2.6.7a2 2 0 0 1 1.7 2z'/%3E%3C/svg%3E");}
/* трубка у телефона — звонит через Sipuni, а не через tel: */
body[data-ext] a[data-dial]::before,.kb-missed::before{content:"";display:inline-block;flex:none;width:12px;height:12px;margin-right:4px;vertical-align:-1px;background:currentColor;-webkit-mask:var(--ic-phone) center/contain no-repeat;mask:var(--ic-phone) center/contain no-repeat;}
.kb-tel-row{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px;margin-top:3px;}
.kb-person{min-width:0;max-width:100%;overflow:hidden;font-size:12px;font-weight:600;color:var(--text);text-overflow:ellipsis;white-space:nowrap;}
.kb-tel-row .kb-tel{margin-top:0;}
.kb-missed{display:inline-flex;align-items:center;padding:1px 8px;border-radius:20px;background:var(--rose-soft);color:var(--rose-ink);font-size:11px;font-weight:700;line-height:17px;white-space:nowrap;}
/* ── лента сделки и клиента (_feed.html): комментарии, правки, оплаты, звонки — строкой с кружком-значком слева ── */
.feed{margin-top:18px;padding:18px 20px 6px;}
.feed-new{margin-top:12px;}
.feed-new textarea,.fi-edit textarea{display:block;width:100%;min-height:64px;border:1px solid var(--border-2);border-radius:13px;padding:11px 14px;font:inherit;font-size:14px;line-height:1.45;color:var(--text);background:var(--surface);outline:none;resize:vertical;transition:border .18s,box-shadow .18s;}
.feed-new textarea:focus,.fi-edit textarea:focus{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);}
.feed-new-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px;}
.feed-new-k{font-size:12.5px;font-weight:600;color:var(--muted);}
.feed-new-row .js-feed-send{margin-left:auto;}
.remind{display:flex;flex-wrap:wrap;align-items:center;gap:8px;}
.remind-chips{box-shadow:none;}
.remind .dp-trigger{min-width:150px;width:auto;}
.fi-list{margin-top:14px;}
.fi{display:flex;gap:12px;padding:12px 0;border-top:1px solid var(--border);}
.fi-ico{flex:none;display:grid;place-items:center;width:30px;height:30px;border-radius:50%;background:var(--surface-2);color:var(--muted);}
.fi-comment .fi-ico{background:var(--primary-soft);color:var(--primary-strong);}
.fi-ico.tone-green{background:var(--green-soft);color:var(--green-ink);}
.fi-ico.tone-blue{background:var(--blue-soft);color:var(--blue-ink);}
.fi-ico.tone-rose{background:var(--rose-soft);color:var(--rose-ink);}
.fi-ico.tone-amber{background:var(--amber-soft);color:var(--amber-ink);}
.fi-ico.tone-lav{background:var(--lav-soft);color:var(--lav);}
.fi-phone{width:14px;height:14px;background:currentColor;-webkit-mask:var(--ic-phone) center/contain no-repeat;mask:var(--ic-phone) center/contain no-repeat;}
.fi-body{flex:1;min-width:0;font-size:13.5px;line-height:1.45;}
.fi-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 8px;}
.fi-meta{font-size:12px;color:var(--muted);}
.fi-body>.fi-meta{display:block;}
.fi-deal{font-size:12px;font-weight:600;color:var(--primary-strong);}
.fi-deal:hover{text-decoration:underline;}
.fi-created .fi-deal{font-size:inherit;}
.fi-act{display:inline-flex;gap:10px;margin-left:auto;font-size:12px;}
.fi-act form{margin:0;}
.fi-act .linkbtn{color:var(--muted);font-weight:600;}
.fi-act .linkbtn:hover{color:var(--primary-strong);}
.fi-text{margin-top:2px;white-space:pre-line;overflow-wrap:anywhere;}
.fi-edit{margin-top:6px;}
.fi-edit[hidden]{display:none;}
.fi-edit-row{display:flex;justify-content:flex-end;gap:8px;margin-top:8px;}
.fi-change{color:var(--muted);overflow-wrap:anywhere;}
.fi .nowrap{white-space:nowrap;}
.fi audio{display:block;width:min(300px,100%);height:32px;margin-top:6px;}
.fi-empty{margin:4px 0 14px;}
/* поля заявки и напоминание — в строке над сделкой: формы не ломают её перенос */
.deal-field{display:inline-flex;align-items:center;gap:0;margin:0;}
.deal-field .sel-in{height:32px;width:auto;max-width:240px;}
.deal-remind{display:inline-flex;align-items:baseline;gap:8px;}
.deal-remind form{margin:0;}
.deal-remind.due{padding:2px 10px;border-radius:20px;background:var(--amber-soft);color:var(--amber-ink);font-weight:650;}
.deal-remind.due .flow-meta-k{color:inherit;}
.sip{padding:16px 18px 18px;}
.sip-check{display:flex;align-items:center;gap:9px;height:44px;font-size:13.5px;cursor:pointer;}
.sip-check input{width:18px;height:18px;margin:0;accent-color:var(--primary);}
.sip-url{margin-top:16px;}
.sip-url label{display:block;margin-bottom:7px;font-size:12.5px;color:var(--muted);}
.sip-url-row{display:flex;gap:10px;}
.sip-url-row input{flex:1;min-width:0;height:44px;padding:0 14px;border:1px solid var(--border-2);border-radius:12px;background:var(--surface-2);font:inherit;font-size:13px;color:var(--text);}
/* окно входящего — в углу, поверх страницы; закреплённый блокнот — правее него */
.call-pops{position:fixed;right:16px;bottom:16px;z-index:240;display:flex;flex-direction:column;gap:10px;width:min(340px,calc(100vw - 32px));pointer-events:none;transition:bottom .2s var(--ease);}
@media (min-width:1100px){.nb-docked .call-pops{right:calc(var(--nb-w) + 16px);}}
/* уведомление («Звоним…») стоит внизу по центру: окно над ним, а не под — на телефоне и рядом с блокнотом они встречаются */
body:has(.toasts .toast) .call-pops{bottom:100px;}
/* пока окно на экране, страницу можно докрутить, чтобы кнопки внизу справа («Сохранить» в сделке) вышли из-под него;
   высоту окон calls.js кладёт в --calls-h. Доска листается колонками — им запас снизу в самих колонках */
body:has(.call-pop) .scroll > .panel:not(:has(.kb)){padding-bottom:calc(var(--calls-h, 0px) + 24px);}
body:has(.call-pop) .kb-list{padding-bottom:calc(var(--calls-h, 0px) + 12px);}
.kb-dragging .call-pops{opacity:.35;pointer-events:none;}   /* карточку бросают и туда, где стоит окно */
.call-pop{pointer-events:auto;padding:12px 14px 14px;background:var(--surface);border:1px solid var(--border-2);border-radius:16px;box-shadow:0 18px 44px rgba(20,40,60,.22);animation:toast-in .28s var(--ease);transition:opacity .3s var(--ease),transform .3s var(--ease);}
.call-pop.out{opacity:0;transform:translateY(12px);}
.call-pop:nth-child(n+4){display:none;}   /* больше трёх разом на один номер не бывает — столбик на весь экран не нужен */
.cp-head{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--muted);}
.cp-head b{font-weight:700;}
.cp-dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--primary);animation:cp-pulse 1.1s ease-in-out infinite;}
.call-pop.talking .cp-dot{background:var(--green);animation:none;}
.call-pop.ended .cp-dot{background:var(--faint);animation:none;}
@keyframes cp-pulse{50%{opacity:.25;}}
.cp-x{margin-left:auto;padding:0 4px;border:0;background:none;color:var(--muted);font-size:20px;line-height:1;cursor:pointer;}
.cp-x:hover{color:var(--text);}
.cp-num{margin-top:6px;font-size:18px;font-weight:700;font-variant-numeric:tabular-nums;}
.cp-person{margin-top:2px;font-size:14px;font-weight:650;overflow-wrap:anywhere;}
.cp-person + .cp-client{font-size:13px;font-weight:600;}   /* под именем человека — его компания, чуть тише */
.cp-client{display:block;margin-top:2px;font-weight:650;overflow-wrap:anywhere;}
a.cp-client{color:var(--primary-strong);}
.cp-new{margin-top:2px;font-size:13px;color:var(--muted);}
.cp-deals{display:flex;flex-direction:column;gap:4px;margin-top:9px;font-size:12.5px;}
.cp-deals a{overflow:hidden;color:var(--text);text-overflow:ellipsis;white-space:nowrap;}
.cp-deals a:hover{color:var(--primary-strong);}
.cp-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:11px;}
@media (prefers-reduced-motion:reduce){.call-pop{animation:none;transition:none;} .cp-dot{animation:none;}}
/* без мыши тащить нечем — стадию выбирают в карточке, «Отказ» виден сразу */
@media (hover:none),(max-width:760px){
  .kb-stage{position:static;width:100%;height:38px;opacity:1;pointer-events:auto;margin-top:9px;font-size:16px;}
  .kb-lose,.kb-snooze{opacity:1;}
}

/* ── «Почта» (mail/*.html): письма строками, письмо с рамкой для HTML, новое письмо; общие ящики в «Сотрудниках» ── */
.mail-boxes{display:flex;flex-wrap:wrap;align-items:center;gap:6px 18px;margin:0 2px 14px;font-size:13px;}
.mail-box{display:inline-flex;flex-wrap:wrap;align-items:center;gap:4px 8px;}
.mail-list{padding:4px 0;}
.mail-row{display:grid;grid-template-columns:minmax(140px,220px) minmax(0,1fr) auto;gap:4px 16px;align-items:baseline;padding:11px 18px;border-top:1px solid var(--border);color:var(--text);font-size:13.5px;}
.mail-list .mail-row:first-child{border-top:0;}
.mail-row:hover{background:var(--surface-2);}
.mail-who,.mail-subj{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mail-subj b{font-weight:600;}
.mail-row.unread .mail-who,.mail-row.unread .mail-subj b{font-weight:800;}
.mail-subj .badge{margin-right:6px;padding:2px 8px;vertical-align:1px;}
.mail-when{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);white-space:nowrap;}
.mail-when .ic svg,.mail-files .ic svg{width:14px;height:14px;}
.mail-none{margin:18px;}
.mail-empty{padding:22px;}
.mail-empty p{margin:8px 0 0;}
.mail-head{padding:18px 20px;}
.mail-head-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 10px;font-size:15px;}
.mail-head .kv{margin-top:12px;}
.mail-files{display:flex;flex-wrap:wrap;gap:6px;}
.mail-body{margin-top:18px;padding:18px 20px;}
.mail-frame{display:block;width:100%;min-height:120px;border:0;}
.mail-text{white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.55;}
.mail-thread{margin-top:18px;padding:16px 0 4px;}
.mail-thread h3{margin:0 20px 8px;}
.mail-compose .field.wide{flex:1 1 100%;}
.mail-compose textarea{min-height:280px;}
.mail-set{margin-top:12px;}
.mail-set-box{margin-top:18px;padding-top:16px;border-top:1px solid var(--border);}
.fi-mail{font-size:inherit;}
@media (max-width:760px){
  .topbar .tb-sync .tb-lbl{display:none;} .topbar .tb-sync{padding:0 14px;}   /* «Обновить» — одной иконкой, как «Написать» */
  .mail-row{grid-template-columns:minmax(0,1fr) auto;padding:11px 14px;}
  .mail-when{grid-row:1;grid-column:2;}
  .mail-subj{grid-column:1 / -1;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
}

/* ── дашборд (из Finuchet) ── */
.dash-wide{grid-template-columns:2fr 1fr;}     /* динамика ЧА + где лежат деньги */
.dash-narrow{grid-template-columns:1fr 2fr;}   /* вчера + притоки/оттоки */
.delta[hidden]{display:none;}                  /* «за день / неделю / месяц» — видна одна */
.topbar .chips{flex-wrap:nowrap;flex:none;}    /* переключатель в топбаре — в одну строку */
/* и ровно в высоту кнопок и полей топбара — 44 (сам по себе он 45,5): в ряд с поиском не торчит (21.10) */
.topbar .chips{height:44px;align-items:stretch;}
.topbar .chips a,.topbar .chips button{display:inline-flex;align-items:center;padding-top:0;padding-bottom:0;}
.tb-actions{display:flex;align-items:center;gap:14px;min-width:0;}   /* кнопки страницы в топбаре — одним блоком */
.kpi-card{cursor:pointer;}
.kpi-card:focus-visible{outline:2px solid var(--primary);outline-offset:3px;}
.na-modal{max-width:640px;text-align:left;}
.na-modal-head{display:flex;align-items:center;gap:13px;margin-bottom:10px;}
.na-modal-head h3{margin:0;font-size:17px;line-height:1.2;}
.na-modal-body{max-height:min(70vh,560px);overflow:auto;margin:0 -6px;padding:0 6px;}

/* «Права ролей» в «Настройках → Сотрудники»: таблица раздел × роль; изменённое относительно стандартного — подсвечено */
.rights td{vertical-align:middle;}
.rights td:not(:first-child){min-width:150px;}
.rights .ss-trigger{height:38px;border-radius:11px;}
.rights td.changed .ss-trigger{border-color:var(--primary);background:var(--primary-soft);}
.rights tbody tr:hover{background:none;}

/* ── блокнот: кнопка справа на каждой странице, при наведении выезжает страница дня. Слой — над топбаром (30),
   под ТВ-режимом (50), модалками (200) и календарём (1000) ── */
.nb-tab{position:fixed;right:0;top:50%;z-index:45;transform:translateY(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;padding:13px 8px;border:1px solid var(--border-2);border-right:0;border-radius:13px 0 0 13px;background:var(--surface);color:var(--primary-strong);box-shadow:var(--shadow-soft);cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:650;transition:background .18s,padding .18s var(--ease),opacity .18s;}
.nb-open .nb-tab{opacity:0;}   /* краешек выглядывал из-под открытого блокнота; наведение на него по-прежнему держит блокнот */
/* подсветка при наведении — классом .hot из notebook.js, а не :hover: у края окна мышь выскакивает за него на миг,
   и :hover мигал вместе с шириной кнопки */
.nb-tab.hot,.nb-tab:focus-visible{background:var(--primary-soft);padding-right:11px;outline:none;}
.nb-tab .ic{font-size:17px;}
.nb-tab span{writing-mode:vertical-rl;transform:rotate(180deg);letter-spacing:.3px;}
/* ширина блокнота: 420 на большом экране, у́же на среднем — чтобы закреплённому рядом хватало места странице */
:root{--nb-w:clamp(340px,30vw,420px);}
/* во всю высоту окна, вплотную к правому краю, без скруглений: закреплённый занимает ровно свою ширину (21.10) */
.nb-panel{position:fixed;top:0;right:0;bottom:0;z-index:46;width:min(var(--nb-w),100vw);display:flex;flex-direction:column;background:var(--surface);border-left:1px solid var(--border-2);box-shadow:-18px 0 50px rgba(20,40,60,.16);transform:translateX(100%);visibility:hidden;transition:transform .24s var(--ease),visibility 0s linear .24s;}
.nb-open .nb-panel{transform:none;visibility:visible;transition:transform .24s var(--ease),visibility 0s;}
.nb-head{display:flex;align-items:center;gap:8px;padding:14px 14px 10px 20px;}
.nb-title{display:flex;align-items:baseline;gap:8px;min-width:0;}   /* серое «сегодня, вторник» — по низу заголовка */
.nb-head b{font-size:17px;}
.nb-when{color:var(--muted);font-size:12.5px;white-space:nowrap;}
.nb-head .spacer{flex:1;}
.nb-head .iconbtn{width:34px;height:34px;border-radius:11px;font-size:16px;flex:none;}
.nb-head .iconbtn[aria-pressed="true"]{background:var(--primary-soft);border-color:var(--primary);color:var(--primary-strong);}
.nb-nav{display:flex;align-items:center;gap:6px;padding:0 14px 12px;}
.nb-nav .dp{flex:1;min-width:0;}
.nb-nav .rp-trigger{min-width:0;height:38px;border-radius:11px;}
.nb-nav .iconbtn{width:38px;height:38px;border-radius:11px;flex:none;}
.nb-nav .iconbtn svg{width:18px;height:18px;display:block;}
.nb-nav .linkbtn{flex:none;font-size:13px;padding:0 4px;}
.nb-nav .linkbtn[hidden]{display:none;}
.nb-text{flex:1;min-height:0;margin:0 14px;padding:13px 15px;border:1px solid var(--border-2);border-radius:14px;background:var(--surface-2);resize:none;font:inherit;font-size:14px;line-height:1.55;color:var(--text);outline:none;transition:border .18s,box-shadow .18s,background .18s;}
.nb-text:focus{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);background:var(--surface);}
.nb-text::placeholder{color:var(--muted);}
/* строка внизу: слева — когда правили или что случилось, справа — зелёное «Сохранено» после каждого сохранения */
.nb-foot{display:flex;align-items:baseline;justify-content:space-between;gap:12px;min-height:42px;padding:10px 20px 13px;font-size:12px;color:var(--muted);}
.nb-info{min-width:0;}
.nb-info.note{color:var(--primary-strong);font-weight:600;}
.nb-info.err{color:var(--rose-ink);font-weight:600;}
.nb-mark{flex:none;color:var(--green-ink);font-weight:650;opacity:0;transition:opacity .3s var(--ease);}
.nb-mark.on{opacity:1;}
.nb-mark.wait{color:var(--muted);font-weight:500;}
@media (prefers-reduced-motion:reduce){.nb-panel,.nb-open .nb-panel{transition:none;}}
/* замок нужен там, где блокнот прячется сам и не на весь экран: на телефоне и в узком окне его нет */
@media (hover:none),(max-width:760px){#nbPin{display:none;}}
/* закреплённый блокнот на широком экране не лежит поверх страницы (закрывал поиск и кнопки топбара), а стоит рядом */
@media (min-width:1100px){.nb-docked .app{padding-right:var(--nb-w);} .nb-docked .nb-panel{box-shadow:none;}}
@media print{.nb-tab,.nb-panel{display:none;}}   /* при печати страницы кнопка блокнота не нужна */

/* ── «Каталог» (app/modules/catalog): список с фильтрами, карточка товара с фото, настройки витрины ── */
/* поиск и фильтры одной строкой: поиск тянется, выборы — по своей подписи (как .cp-bar у контрагентов) */
.ct-filterbar{display:flex;gap:12px;align-items:stretch;margin-bottom:14px;}
.ct-filterbar .searchbar{flex:1;min-width:0;margin-bottom:0;}
.ct-filterbar form{display:flex;gap:12px;flex:none;}
.ct-filterbar .field{margin-bottom:0;}
/* топбар списка в тесноте (узкое окно или блокнот рядом — места меньше ~820px): «Витрина» и «Настройки витрины» —
   иконками, иначе «Новый товар» уходит за край, а подпись под заголовком — во вторую строку (23.10) */
@media (min-width:761px) and (max-width:820px){.topbar .ct-tb{width:44px;padding:0;justify-content:center;} .topbar .ct-tb .tb-lbl{display:none;}}
@media (min-width:1100px) and (max-width:1171px){.nb-docked .topbar .ct-tb{width:44px;padding:0;justify-content:center;} .nb-docked .topbar .ct-tb .tb-lbl{display:none;}}
.ct-list{padding:8px 6px 6px;}
.ct-list tr[data-href]{cursor:pointer;}
.ct-chk{width:38px;}
.ct-chk label{display:flex;align-items:center;justify-content:center;min-height:34px;cursor:pointer;}
.ct-chk input,.ct-switch input{accent-color:var(--primary);cursor:pointer;}
.ct-chk input{width:16px;height:16px;}
.ct-prod{display:flex;align-items:center;gap:11px;min-width:0;}
.ct-thumb{flex:none;width:44px;height:44px;border-radius:11px;border:1px solid var(--border-2);background:#fff;display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--muted);}
.ct-thumb img{width:100%;height:100%;object-fit:contain;}
.ct-prod-name{display:flex;flex-direction:column;min-width:0;}
.ct-prod-name a{color:inherit;}
.ct-prod-name a:hover b{color:var(--primary-strong);}
.ct-warn{color:var(--amber-ink);font-weight:600;white-space:nowrap;}
.ct-site-cell .small{margin-top:5px;}
.ct-empty{text-align:center;padding:28px !important;}
/* «Выбрано: N» — над таблицей, пока есть выбранные; при прокрутке держится вверху */
.ct-bulk{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:9px 12px 9px 16px;margin-bottom:12px;border:1px solid var(--primary);border-radius:13px;background:var(--primary-soft);box-shadow:var(--shadow);}
.ct-bulk[hidden]{display:none;}
.ct-bulk>span{margin-right:auto;font-size:13.5px;color:var(--primary-strong);}
/* карточка товара: фото слева, поля справа */
.ct-card{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:18px;align-items:start;}
.ct-photos-head{margin-bottom:12px;gap:10px;}
.ct-photos-head h3{margin:0;}
.ct-photos.over{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);}
.ct-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:10px;}
/* фото лежит поверх плитки (absolute): своим размером оно не раздувает сетку — плитку задают колонки и квадрат */
.ct-ph{position:relative;margin:0;min-width:0;aspect-ratio:1/1;border-radius:13px;border:1px solid var(--border-2);background:#fff;overflow:hidden;}
.ct-ph>a,.ct-ph img{position:absolute;inset:0;display:block;width:100%;height:100%;}
.ct-ph img{object-fit:contain;}
.ct-ph.lead{grid-column:span 2;grid-row:span 2;border-color:var(--primary);}   /* не .main: так зовётся колонка страницы (app.css) */
.ct-ph[draggable="true"]{cursor:grab;}
.ct-ph.dragging{opacity:.35;}
.ct-main{position:absolute;left:8px;top:8px;padding:3px 9px;border-radius:20px;background:var(--primary);color:#fff;font-size:11px;font-weight:700;pointer-events:none;}
.ct-ph-act{position:absolute;right:6px;bottom:6px;display:flex;gap:5px;opacity:0;transition:opacity .15s;}
.ct-ph:hover .ct-ph-act,.ct-ph:focus-within .ct-ph-act{opacity:1;}
@media (hover:none){.ct-ph-act{opacity:1;}}
/* действия плитки — квадратные значки: с подписью «Главное» они не влезали в маленькую плитку, и «Скачать» уходило
   за её край; что делает кнопка — в подсказке (title) */
.ct-ph-act button,.ct-ph-act a{width:28px;height:28px;padding:0;border:0;border-radius:9px;background:rgba(255,255,255,.95);box-shadow:0 2px 8px rgba(20,40,60,.18);font:inherit;font-size:12px;font-weight:650;color:var(--text);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;text-decoration:none;}
.ct-ph-act button:hover,.ct-ph-act a:hover{color:var(--primary-strong);}
.ct-ph-act .ic{font-size:13px;}   /* значки — рисунком (app.js), одного размера: скачать, главное, убрать, удалить */
.ct-ph-act button[data-act="delete"]:hover{color:var(--rose-ink);}
.ct-ph.loading{display:flex;flex-direction:column;justify-content:center;gap:8px;padding:12px;background:var(--surface-2);}
.ct-bar{height:6px;border-radius:6px;background:var(--border-2);overflow:hidden;}
.ct-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--primary),var(--primary-2));transition:width .2s;}
.ct-fname{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* фото нового товара уходит на сервер: превью бледнее, полоска хода и подпись — поверх него */
.ct-ph.loading .ct-bar,.ct-ph.loading .ct-fname{position:relative;z-index:2;}
.ct-ph[data-q].loading img{opacity:.35;}
.ct-drop{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;aspect-ratio:1/1;padding:10px;border:2px dashed var(--border-2);border-radius:13px;color:var(--muted);text-align:center;cursor:pointer;transition:border-color .15s,background .15s,color .15s;}
.ct-drop:hover,.ct-photos.over .ct-drop{border-color:var(--primary);background:var(--primary-soft);color:var(--primary-strong);}
.ct-drop input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
.ct-drop .ic{font-size:22px;}
.ct-drop b{font-size:13px;color:var(--text);}
.ct-drop span{font-size:11.5px;line-height:1.35;}
.ct-photos:not(:has(.ct-ph[data-id],.ct-ph[data-q])) .ct-drop{grid-column:1 / -1;aspect-ratio:auto;min-height:220px;}   /* фото нет — зона во весь блок */
.ct-fields fieldset,.ct-site-form fieldset{border:0;margin:0;padding:0;min-width:0;}
.ct-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 14px;}
.ct-row:has(.ct-narrow){grid-template-columns:minmax(0,1fr) 150px;}
.ct-fields .combo-in{height:44px;border-radius:13px;padding:0 14px;font-size:14px;}   /* поля с поиском — как остальные поля карточки */
.ct-site{display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center;padding:14px;margin:2px 0 16px;border:1px solid var(--border);border-radius:14px;background:var(--surface-2);}
.ct-site .field{flex:1 1 200px;margin:0;}
.ct-switch{flex:1 1 200px;display:flex;align-items:center;gap:11px;cursor:pointer;}
.ct-switch input{width:20px;height:20px;flex:none;}
.ct-switch span{display:flex;flex-direction:column;}
.ct-switch small{color:var(--muted);font-size:12px;}
.ct-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:6px;}
/* «Сохранить» в карточке товара всегда на виду: форма длиннее экрана — полоса с кнопками держится у его низа.
   bottom — минус нижний отступ .scroll (26, на телефоне 16): прилипание Chrome отсчитывает от края отступа, и с
   bottom:0 полоса висела на 26 выше низа окна, а в щель под ней было видно поля формы (23.10, снимок пользователя) */
.ct-fields .ct-actions{position:sticky;bottom:-26px;z-index:3;margin:8px -20px -20px;padding:12px 20px;background:var(--surface);border-top:1px solid var(--border);border-radius:0 0 var(--radius) var(--radius);box-shadow:0 -10px 20px -16px rgba(20,40,60,.28);}
.ct-keys{margin-left:auto;}
.ct-nav{width:44px;justify-content:center;padding:0;}
.ct-nav svg{display:block;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.ct-nav.off{opacity:.35;pointer-events:none;}
/* настройки витрины: порядок категорий */
.ct-site-grid{align-items:start;}
.ct-site-grid .card h3{margin-bottom:14px;}
.ct-order{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;}
.ct-order li{display:flex;align-items:center;gap:10px;padding:7px 8px 7px 12px;border:1px solid var(--border-2);border-radius:12px;background:var(--surface);cursor:grab;}
.ct-order li.dragging{opacity:.4;}
.ct-order li .small{margin-left:auto;}
.ct-grip{color:var(--muted);letter-spacing:-3px;}
.ct-move{display:flex;gap:4px;}
.ct-move .pill{height:30px;width:30px;padding:0;justify-content:center;font-size:13px;}
@media (max-width:1060px){.ct-card{grid-template-columns:1fr;}}

/* ── телефон: меню выезжает по кнопке ☰, подписи в нём видны сразу ── */
.nav-burger,.nav-scrim{display:none;}
@media (max-width:760px){
  .deal-form .f-source{width:196px;} .deal-form .f-urgency{width:116px;}   /* шрифт полей здесь 16px */
  .app{grid-template-columns:1fr;height:100vh;height:100dvh;}
  .main{height:100vh;height:100dvh;}
  .sidebar{position:fixed;top:0;bottom:0;left:0;z-index:150;width:252px;transform:translateX(-105%);transition:transform .2s var(--ease);}
  .sidebar:hover{width:252px;box-shadow:none;}
  .nav-open .sidebar{transform:none;box-shadow:8px 0 36px rgba(20,40,60,.18);}
  .nav-open .nav-scrim{display:block;position:fixed;inset:0;z-index:140;background:rgba(18,38,48,.32);}
  .sidebar .nav a{gap:12px;font-size:14px;padding:11px 14px 11px 0;}
  .sidebar .brand,.sidebar .nav .group{opacity:1;}
  .sidebar .side-foot>div:not(.avatar),.sidebar .side-foot a.logout{display:block;}
  .nav-burger{display:grid;flex:none;}
  .topbar{height:58px;padding:0 14px;gap:10px;}
  .topbar h1{font-size:16px;}
  .topbar .sub{display:none;}
  .scroll{padding:16px;}
  .grid.g2,.grid.g3,.grid.g4,.grid.dash-wide,.grid.dash-narrow{grid-template-columns:1fr;}
  .card{overflow-x:auto;}            /* широкие таблицы прокручиваются внутри карточки */
  .login-card{width:calc(100vw - 32px);padding:28px 22px;}
  .modal{padding:22px 18px;}
  /* 16px в полях — иначе iPhone приближает страницу при вводе */
  .field input,.field select,.ss-trigger,.erow input.v-edit,.erow select.v-edit{font-size:16px;}
  /* ТВ-режим — для большого экрана; на телефоне кнопка не нужна, переключатель срока — компактнее */
  #tvBtn,.topbar .tb-div{display:none;}
  /* кнопки не помещаются рядом с заголовком — уходят второй строкой целиком и прокручиваются вбок */
  .topbar{height:auto;min-height:58px;flex-wrap:wrap;row-gap:8px;padding:9px 14px;}
  .tb-actions{gap:10px;overflow-x:auto;scrollbar-width:none;}
  .tb-actions::-webkit-scrollbar{display:none;}
  .topbar .chips button{padding:7px 10px;}
  /* доска: колонки листаются вбок по одной, от края до края экрана; вниз — вся страница */
  .tb-search{width:150px;}
  .topbar:has(.tb-search) .sub{display:none;}
  /* «Новая сделка», «Новый контрагент» — одним «+» (21.10) */
  .topbar .pill.role .tb-lbl{display:none;} .topbar .pill.role:has(.tb-lbl){padding:0 14px;}
  .kb{height:auto;margin:-16px -16px 0;padding-bottom:14px;scroll-snap-type:x mandatory;}
  .kb-col{flex-basis:86vw;scroll-snap-align:start;}
  .kb-col.shrunk{flex-basis:44px;scroll-snap-align:none;}   /* листая, полоски проскакиваешь */
  .kb-list{overflow:visible;}
  /* блокнот — на весь экран; кнопка ниже, под большим пальцем */
  .nb-tab{top:auto;bottom:110px;transform:none;padding:11px 7px;}
  .nb-panel{inset:0;width:100vw;border:0;border-radius:0;}
  .nb-text{font-size:16px;}
  /* окно входящего — во всю ширину внизу, запись — уже */
  .call-pops{left:16px;right:16px;width:auto;}
  .calls audio{width:200px;}
  /* каталог: поля карточки — столбиком, подсказка про Ctrl+Enter не нужна */
  .ct-row,.ct-row:has(.ct-narrow){grid-template-columns:1fr;}
  .ct-keys{display:none;}
  .ct-fields .ct-actions{bottom:-16px;}   /* .scroll здесь с отступом 16 */
  .ct-filterbar{flex-wrap:wrap;} .ct-filterbar .searchbar,.ct-filterbar form{flex:1 1 100%;} .ct-filterbar form .field{flex:1;min-width:0;}
  .ct-grid{grid-template-columns:repeat(3,minmax(0,1fr));}
  /* плитка ~100px: три значка по 26 — внутри неё, а не «Скачать» за краем */
  .ct-ph-act{right:4px;bottom:4px;gap:3px;} .ct-ph-act button,.ct-ph-act a{width:26px;height:26px;}
  .ct-fields .combo-in{font-size:16px;}
}

/* «Движение денег» — как /dds в Sollo (26.10): две карточки сверху, автор подписью под датой, длинный текст — в две
   строки с раскрытием по щелчку, фильтр в топбаре — по содержимому */
.dds-topbar{display:flex;gap:16px;align-items:stretch;margin-bottom:22px;}
.dds-topbar>.card{flex:1 1 0;min-width:0;}
.dds-acc{padding:16px;}
.dds-acc .big{margin-top:6px;}
.dds-acc .delta{margin-top:7px;}
.dds-h{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dds-bal{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;min-width:0;}
.dds-bal .delta{margin-top:0;white-space:nowrap;}
.dds-by{font-size:11.5px;color:var(--faint);font-weight:500;margin-top:2px;white-space:nowrap;}
.dds-cmt{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.dds-cmt.is-clip{cursor:pointer;}
.dds-cmt.is-clip:hover{color:var(--primary);}
.dds-cmt.is-full{-webkit-line-clamp:unset;overflow:visible;}
#moneyFilter .combo-in{width:180px;min-width:140px;max-width:240px;field-sizing:content;text-overflow:ellipsis;}
#moneyFilter .combo-in.has-val{font-weight:600;}
#payModal .dds-submit{flex:1 1 100%;flex-direction:row;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end;}
#payModal textarea{width:100%;min-height:46px;max-height:170px;resize:vertical;border:1px solid var(--border-2);border-radius:13px;padding:11px 14px;font:inherit;font-size:14px;line-height:1.45;color:var(--text);background:var(--surface);outline:none;transition:border .18s,box-shadow .18s;}
#payModal textarea:focus{border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft);}
@media (max-width:760px){ .dds-topbar{flex-direction:column;} }
/* пять фильтров и «+ Движение» одной строкой помещаются от 1400 (с закреплённым блокнотом — от 1750); уже — фильтр
   второй строкой под заголовком и сам переносится, а не уходит за край. Телефон — как у всех: строка листается */
@media (min-width:761px) and (max-width:1400px){
  .topbar:has(#moneyFilter){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
  .topbar:has(#moneyFilter) .tb-actions{flex-wrap:wrap;row-gap:8px;}
  #moneyFilter{flex-wrap:wrap;row-gap:8px;flex:1 1 auto;min-width:0;}
}
@media (min-width:1401px) and (max-width:1750px){
  .nb-docked .topbar:has(#moneyFilter){height:auto;min-height:66px;flex-wrap:wrap;row-gap:8px;padding-top:10px;padding-bottom:10px;}
  .nb-docked .topbar:has(#moneyFilter) .tb-actions{flex-wrap:wrap;row-gap:8px;}
  .nb-docked #moneyFilter{flex-wrap:wrap;row-gap:8px;flex:1 1 auto;min-width:0;}
}
