/* ─────────────────────────────────────────────────────────────────────────────────────────
 * [CARD-V8-LOOK] Вид карточки сделки по эталонным мокапам (v8-order / v8-purchase).
 *
 * ЧТО ЭТО. Владелец: «нам надо ТОЧНО ПО МОКАПУ дизайн сделать, сейчас вообще не то». Файл —
 * собранные слои мокапа в том же порядке, в каком их подключает генератор: базовый вид →
 * карточка v8 → финальные правки → шкала → док задач → вкладка расчётов → доступность.
 * Порядок значим: каждый следующий слой правит предыдущий, перестановка меняет вид.
 *
 * ⛔ ПРАВИЛА ПРАВКИ. Источник истины — слои в scratchpad, этот файл СОБИРАЕТСЯ из них скриптом.
 * Править здесь руками нельзя: правка потеряется при следующей сборке мокапа, и живой вид
 * разойдётся с эталоном — ровно то расхождение, которое сторож [CARD-MOCKUP-MATCHES-LIVE]
 * и должен ловить.
 *
 * Применяется ТОЛЬКО при включённом виде v8 (флаг sc_pref_deal_card_v8) — классика и v6
 * остаются нетронутыми, откат = одна запись в ключ.
 * ───────────────────────────────────────────────────────────────────────────────────────── */

/* Всё ниже действует только при html[data-card-v8] — признак ставит клиент по личной
   настройке. Без признака файл не влияет ни на один экран. */
@scope (html[data-card-v8]) {
  /* ─────────────────────────────────────────────────────────────────────────────────────────
   * [CARD-V8-LOOK] Вид карточки сделки по эталонным мокапам (v8-order / v8-purchase).
   *
   * ЧТО ЭТО. Владелец: «нам надо ТОЧНО ПО МОКАПУ дизайн сделать, сейчас вообще не то». Файл —
   * собранные слои мокапа в том же порядке, в каком их подключает генератор: базовый вид →
   * карточка v8 → финальные правки → шкала → док задач → вкладка расчётов → доступность.
   * Порядок значим: каждый следующий слой правит предыдущий, перестановка меняет вид.
   *
   * ⛔ ПРАВИЛА ПРАВКИ. Источник истины — слои в scratchpad, этот файл СОБИРАЕТСЯ из них скриптом.
   * Править здесь руками нельзя: правка потеряется при следующей сборке мокапа, и живой вид
   * разойдётся с эталоном — ровно то расхождение, которое сторож [CARD-MOCKUP-MATCHES-LIVE]
   * и должен ловить.
   *
   * Применяется ТОЛЬКО при включённом виде v8 (флаг sc_pref_deal_card_v8) — классика и v6
   * остаются нетронутыми, откат = одна запись в ключ.
   * ───────────────────────────────────────────────────────────────────────────────────────── */
  
  /* ═══ слой: sales-css.txt ═══ */
  
  :root{
    --bg:#f6f7f9; --surface:#ffffff; --surface2:#f3f4f6; --surface3:#e9ebef;
    --border:#e5e7eb; --border2:#d1d5db;
    --text:#111827; --text2:#374151; --text3:#6b7280;
    --accent:#3b82f6; --pri-bg:#2563eb; --pri-bg-h:#1d4ed8;
    --green:#16a34a; --green-bg:#dcfce7; --green-fg:#166534;
    --red:#ef4444; --red-bg:#fee2e2; --red-fg:#991b1b;
    --orange:#d97706; --orange-bg:#fef3c7; --orange-fg:#92400e;
    --blue-bg:#eff6ff; --blue-bd:#bfdbfe; --blue-fg:#1e40af;
    --mono:ui-monospace,'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
  }
  *{box-sizing:border-box}
  /* [FONT-SELF-HOSTED] тот же подключённый файлом Inter, что и в живой системе */
  @font-face{font-family:'InterVariable';src:url('/fonts/InterVariable.woff2') format('woff2');
    font-weight:100 900;font-style:normal;font-display:swap}
  /* [FONT-MANAT-GLYPH] ₼ (U+20BC) нет ни в одном шрифте — без этого фейса он рисуется пустым квадратом
     рядом с каждой суммой. unicode-range ровно на манат: на остальной текст фейс не влияет. */
  @font-face{font-family:'SofconManat';src:url('/fonts/SofconManat.woff2') format('woff2');
    unicode-range:U+20BC;font-weight:100 900;font-style:normal;font-display:swap}
  @font-face{font-family:'Inter-fallback';src:local('Arial'),local('Liberation Sans'),local('DejaVu Sans');
    size-adjust:107%;ascent-override:90%;descent-override:22.5%;line-gap-override:0%}
  a{color:var(--accent);text-decoration:none}
  button{font:inherit}
  .main{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}
  
  /* ── шапка ── */
  .hero{background:var(--surface);border-bottom:1px solid var(--border);padding:6px 20px 0;flex-shrink:0}
  .crumbs{font-size:12px;color:var(--text3);display:flex;gap:6px}
  .crumbs b{color:var(--text2);font-weight:600}
  .title-row{display:flex;align-items:center;gap:10px;margin:2px 0 2px;flex-wrap:wrap}
  .title-row h1{font-size:17px;margin:0;letter-spacing:-.02em;font-weight:700}
  .badge{font-size:11px;font-weight:600;border-radius:999px;padding:2px 9px;display:inline-flex;align-items:center;gap:5px}
  .badge.ok{background:var(--green-bg);color:var(--green-fg)}
  .badge .dot{width:6px;height:6px;border-radius:50%;background:var(--green)}
  .title-row .sp{flex:1}
  .btn{border:1px solid var(--border);background:var(--surface);border-radius:8px;padding:6px 13px;
    font-size:12px;font-weight:600;color:var(--text2);cursor:pointer;display:inline-flex;align-items:center;gap:6px}
  .btn:hover{border-color:var(--border2);background:var(--surface2)}
  .btn.pri{background:var(--pri-bg);border-color:transparent;color:#fff}
  .btn.pri:hover{background:var(--pri-bg-h)}
  .btn.sm{padding:4px 10px;min-height:24px}
  .me{display:flex;align-items:center;gap:9px;padding:2px 6px}
  .me .ava{width:30px;height:30px;border-radius:50%;background:#5e35b1;color:#fff;font-size:12px;
    font-weight:700;display:flex;align-items:center;justify-content:center}
  .me .nm{font-size:12px;font-weight:600;line-height:1.2}
  .me .rl{font-size:11px;color:var(--text3);line-height:1.2}
  .meta-row{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--text3);margin:2px 0 8px;flex-wrap:wrap}
  .pchips{display:flex;gap:6px;margin:3px 0 6px;flex-wrap:wrap}
  .pchip{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--border);border-radius:10px;
    background:var(--surface);padding:3px 9px;min-width:0;color:inherit;transition:border-color .12s,box-shadow .12s}
  .pchip:hover{border-color:var(--accent);box-shadow:0 1px 6px rgba(59,130,246,.15)}
  .pchip.flat:hover{box-shadow:none;border-color:var(--border)}
  .pchip .pa{width:26px;height:26px;border-radius:50%;color:#fff;font-size:11px;font-weight:700;
    display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
  .pchip .pt{display:flex;flex-direction:row;align-items:baseline;gap:5px;min-width:0}
  .pchip .pl{font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);line-height:1.2}
  .pchip .pv{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px;line-height:1.25}
  .pchip .pgo{color:var(--border2);font-size:12px}
  .pchip:hover .pgo{color:var(--accent)}
  .pchip .pact{color:var(--text3);font-size:12px;padding:2px 3px;border-radius:5px}
  .pchip .pact:hover{background:var(--blue-bg);color:var(--accent)}
  .meta-row b{color:var(--text2);font-weight:600}
  .alerts{display:flex;gap:8px;margin:0 0 8px;flex-wrap:wrap}
  .alert{font-size:11px;font-weight:600;border-radius:7px;padding:3px 10px}
  .alert.red{background:var(--red-bg);color:var(--red-fg)}
  .alert.amb{background:var(--orange-bg);color:var(--orange-fg)}
  .kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:0 -20px;border-top:1px solid var(--border)}
  .kpi{padding:4px 14px 6px;border-right:1px solid var(--border);min-width:0}
  .kpi:last-child{border-right:0}
  .kpi .kl{font-size:11px;color:var(--text3)}
  .kpi .kv{font-size:15px;font-weight:700;letter-spacing:-.01em;margin-top:1px;white-space:nowrap;font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis}
  .kpi .kv .of{font-size:11px;color:var(--text3);font-weight:500}
  .kpi .kv.red{color:var(--red)}
  /* [SETUP-MARKS-FORCED-VISIBLE] Пустое поле, показанное ТОЛЬКО ради настройки, помечено — так же,
     как Salesforce App Builder и Power Apps помечают скрытые элементы в редакторе. Без пометки
     настройщик видит полный список и решает, что его видит и пользователь. Метка тихая: пунктир
     слева и приглушённая подпись, чтобы не спорить с содержимым.
     ⛔ ПРАВИЛО ЖИВЁТ ЗДЕСЬ, В СЛОЕ-ИСТОЧНИКЕ. Раньше оно лежало ТОЛЬКО в собранном public/card-v8.css
     (правка руками мимо слоёв) — и первая же честная пересборка стёрла бы его вместе с инвариантом,
     который его проверяет (scripts/check-invariants.sh, «v8-forced-visible» в card-v8.css). Ровно тот
     класс, о котором предупреждает [CSS-EDIT-GOES-TO-SOURCE-LAYER]. */
  .fi.v8-forced-visible{position:relative;opacity:.72}
  .fi.v8-forced-visible::before{content:'';position:absolute;left:-6px;top:2px;bottom:2px;
    border-left:2px dashed var(--text3);border-radius:1px}
  /* Размер — из общей шкалы {11,13,15,17,19}: гейт справедливо поймал 10px как чужой.
     Единая шкала — это не придирка: разнобой размеров и есть та «неаккуратность», которую видно
     глазом раньше, чем осознаёшь причину. */
  .fi.v8-forced-visible .k::after{content:' · скрыто вне настройки';font-size:11px;color:var(--text3);font-weight:400}
  .kpi .kv.grn{color:var(--green-fg)}
  .kpi .bar{height:4px;border-radius:999px;background:#eef1f5;margin-top:3px;overflow:hidden}
  .kpi .bar i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#3b82f6,#60a5fa)}
  .kpi .bar i.sup{background:linear-gradient(90deg,#d97706,#f59e0b)}
  /* липкая навигация по вкладкам */
  .anchor-bar{display:flex;gap:2px;margin:0 -20px;padding:0 12px;border-top:1px solid var(--border);
    background:var(--surface);position:sticky;top:0;z-index:30;box-shadow:0 1px 0 var(--border);
    overflow-x:auto;scrollbar-width:none;align-items:center}
  .anchor-bar a{font-size:11px;font-weight:600;color:var(--text3);padding:8px 9px;border-bottom:2px solid transparent;white-space:nowrap;text-transform:uppercase;letter-spacing:.4px}
  .anchor-bar a:hover{color:var(--text)}
  .anchor-bar a.on{color:var(--accent);border-bottom-color:var(--accent)}
  .anchor-bar .he{margin-left:auto;font-size:11px;color:var(--text3);display:flex;gap:5px;align-items:center;cursor:pointer;white-space:nowrap;padding-right:6px}
  .cardb[id]{scroll-margin-top:44px}
  
  /* ── тело: центр + фиксированный док ── */
  .body-scroll{flex:1;min-width:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable;padding:12px}
  .body{min-width:0;display:flex;flex-direction:column;gap:12px;padding-bottom:24px}
  /* СКОЛЬКО ВКЛАДОК В РЯДУ — живая настройка владельца: число колонок держит --sec-cols,
     его выставляет applyCols() (JS), измерив реальную ширину тела. Настройка = МАКСИМУМ:
     на узком окне applyCols сам ужимает число колонок, чтобы не было горизонтального скролла. */
  .grid3{display:grid;grid-template-columns:repeat(var(--sec-cols,2),minmax(0,1fr));gap:12px;align-items:start}
  @media (max-width:1180px){ .grid3{--sec-cols:1} }   /* запасной путь, если JS не отработал */
  .stack{display:flex;flex-direction:column;gap:12px;min-width:0}
  
  /* карточка-вкладка (плотность живой системы: шапка 7×11, строки 32px) */
  .cardb{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden;
    box-shadow:0 1px 2px rgba(15,23,42,.05),0 12px 32px -16px rgba(15,23,42,.10)}
  .cardb .hd{display:flex;align-items:center;gap:7px;padding:7px 11px;border-bottom:1px solid var(--border);
    background:var(--surface2);cursor:pointer;user-select:none}
  .cardb .hd svg{width:13px;height:13px;color:var(--text3);flex-shrink:0}
  .cardb .hd h3{font-size:12px;font-weight:700;margin:0;text-transform:uppercase;letter-spacing:.4px;color:var(--text2)}
  .cardb .hd .cnt{font-size:11px;color:var(--text3);font-weight:500}
  .cardb .hd::after{content:'▾';margin-left:auto;color:var(--text3);font-size:11px;transition:transform .15s}
  .cardb.collapsed .hd::after{transform:rotate(-90deg)}
  .cardb.collapsed .hd{border-bottom:0}
  .cardb.collapsed .bd{display:none}
  .cardb .hd .act{margin-left:6px;color:var(--text3);cursor:pointer;font-size:12px;min-height:22px;display:inline-flex;align-items:center}
  .cardb .hd .act:hover{color:var(--accent)}
  .cardb .bd{padding:0}
  
  /* поля: подпись 110-150 / значение справа; широкие вкладки — сетка колонок */
  .fgrid{display:block}
  .cardb .fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:0 22px;align-items:start;grid-auto-rows:min-content}
  .cardb .fgrid .fi.long{grid-column:1/-1}
  .fi{display:grid;grid-template-columns:minmax(110px,150px) minmax(0,240px) minmax(0,1fr);align-items:center;gap:12px;
    padding:5px 12px;min-height:32px;border-bottom:1px solid var(--surface2);min-width:0}
  .fgrid > .fi:last-child{border-bottom:0}
  .fi:hover{background:var(--surface2)}
  .fi .k{font-size:11px;color:var(--text3);white-space:normal;line-height:1.2;overflow:visible}
  .fi .k .sig{margin-left:4px;color:var(--text3);font-size:11px}
  .fi .v{font-size:13px;font-weight:600;text-align:right;font-variant-numeric:tabular-nums;justify-self:stretch;
    width:100%;max-width:240px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-radius:7px;padding:2px 7px;cursor:pointer}
  .fi .v:hover{background:var(--surface3)}
  .fi.ro .v{cursor:default}
  .fi.ro .v:hover{background:transparent}
  .fi.long{grid-template-columns:1fr;gap:1px;align-items:start}
  .fi.long .v{text-align:left;white-space:normal;justify-self:start;max-width:100%}
  .fi .v .pen{opacity:0;color:var(--border2);margin-left:4px}
  .fi:hover .v .pen{opacity:1}
  .fi .v:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
  .fi.empty .v{color:var(--text3);font-weight:400;font-style:italic;border:1px dashed var(--border2);
    border-radius:7px;padding:2px 9px;font-size:12px}
  .fi.empty .v:hover{color:var(--accent);border-color:var(--accent);background:transparent}
  .fi input,.fi select{font:600 13px/1.4 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text);height:28px;
    border:1px solid var(--blue-bd);border-radius:7px;padding:2px 8px;background:var(--surface);
    outline:2px solid var(--blue-bg);justify-self:end;min-width:0;width:min(100%,320px);text-align:right}
  .fi select{text-align:left}
  .fi.saved .v{animation:sf .8s}
  @keyframes sf{0%{background:var(--green-bg)}100%{background:transparent}}
  .presets{display:flex;gap:4px;flex-wrap:wrap;margin-top:3px;grid-column:1/-1}
  .presets .pr{font-size:11px;font-weight:600;border:1px solid var(--border);border-radius:999px;padding:2px 9px;
    background:var(--surface);cursor:pointer;color:var(--text2);min-height:22px}
  .presets .pr:hover{border-color:var(--accent);color:var(--accent)}
  
  /* таблица товаров */
  table.items{width:auto;min-width:100%;border-collapse:collapse;font-size:12px}
  table.items th:first-child,table.items td.nm{position:sticky;left:0;z-index:1;background:var(--surface);max-width:420px}
  table.items thead th:first-child{background:var(--surface2)}
  table.items tfoot td:first-child{position:sticky;left:0;background:var(--surface2)}
  table.items th:last-child .th-rz{right:0;width:4px}
  #items-box,#rel-box{scrollbar-gutter:stable}
  table.items th{font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);text-align:left;
    padding:6px 10px;border-bottom:1px solid var(--border);background:var(--surface2)}
  table.items th.r,table.items td.r{text-align:right}
  table.items td{padding:5px 10px;border-bottom:1px solid var(--surface2);white-space:nowrap}
  table.items td.nm{white-space:normal;font-weight:600;min-width:200px}
  table.items td.r{font-variant-numeric:tabular-nums}
  table.items tfoot td{font-weight:700;border-top:1px solid var(--border);border-bottom:0;background:var(--surface2)}
  .check{font-size:11px;font-weight:600;border-radius:7px;padding:3px 10px;display:inline-flex;gap:6px;align-items:center}
  .check.ok{background:var(--green-bg);color:var(--green-fg)}
  .check.warn{background:var(--orange-bg);color:var(--orange-fg)}
  
  /* ── ПРАВЫЙ ДОК: на всю высоту экрана, ФИКСИРОВАН, композер ПРИЖАТ К НИЗУ ── */
  /* док НИЖЕ шапки: колонка на всю оставшуюся высоту, до низа окна; фиксирован по построению */
  .dock{width:clamp(320px,26vw,460px);flex-shrink:0;display:flex;flex-direction:column;min-height:0;height:100%;
    background:var(--surface);border-left:1px solid var(--border);overflow:hidden}
  .dock .dock-hd{padding:8px 14px 6px;border-bottom:1px solid var(--border);display:flex;align-items:baseline;gap:6px;flex-shrink:0}
  .dock .dock-hd b{font-size:11px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--text3)}
  .dock .dock-hd .sub{font-size:11px;color:var(--text3)}
  .dock .sec-hd{display:flex;align-items:center;gap:7px;padding:8px 14px 4px;flex-shrink:0}
  .dock .sec-hd h3{font-size:12px;font-weight:700;margin:0}
  .dock .sec-hd .cnt{font-size:11px;color:var(--text3)}
  .dock .sec-hd .act{margin-left:auto;color:var(--text3);cursor:pointer;min-height:22px}
  .dock .sec-hd.hist{border-top:1px solid var(--border);margin-top:2px}
  .dock-tasks{flex-shrink:0;max-height:clamp(84px,26vh,240px);overflow-y:auto;overscroll-behavior:contain}
  .tasks-list{padding:0 14px 6px}
  .task{display:flex;align-items:flex-start;gap:9px;padding:6px 0;border-bottom:1px solid var(--surface2)}
  .task:last-child{border-bottom:0}
  .task .chk{width:18px;height:18px;border:1.5px solid var(--border2);border-radius:4px;margin-top:1px;flex-shrink:0;cursor:pointer;
    display:flex;align-items:center;justify-content:center;color:transparent;font-size:11px}
  .task.done .chk{background:var(--green);border-color:var(--green);color:#fff}
  .task.done .chk::after{content:'✓'}
  .task .tx .t{font-size:12px;font-weight:600}
  .task.done .tx .t{text-decoration:line-through;color:var(--text3);font-weight:500}
  .task .tx .d{font-size:11px;color:var(--text3)}
  .fchips{display:flex;gap:3px;background:var(--surface2);border-radius:8px;padding:2px;margin:4px 14px 2px;width:fit-content;flex-shrink:0}
  .fchips .fc{font-size:11px;padding:3px 9px;border-radius:6px;border:0;background:transparent;color:var(--text2);cursor:pointer;font-weight:600;min-height:24px}
  .fchips .fc.on{background:var(--surface);box-shadow:0 1px 3px rgba(0,0,0,.08)}
  /* лента: растягивается на всё оставшееся, свой скролл, прикол к низу как чат */
  .act-scroll{flex:1;min-height:80px;overflow-y:auto;overscroll-behavior:contain;padding:2px 14px 8px;
    display:flex;flex-direction:column;
    -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 10px,#000 calc(100% - 10px),transparent 100%);
    mask-image:linear-gradient(180deg,transparent 0,#000 10px,#000 calc(100% - 10px),transparent 100%)}
  .act-item{display:flex;gap:9px;padding:6px 0}
  .act-item .ic{width:24px;height:24px;border-radius:50%;border:1px solid var(--border);background:var(--surface);
    display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--text3);font-size:11px}
  .act-item .bx{flex:1;min-width:0}
  .act-item .who{font-size:12px}
  .act-item .who b{font-weight:600}
  .act-item .who .tm{color:var(--text3);margin-left:6px;font-size:11px}
  .act-item .msg{font-size:12px;color:var(--text2);margin-top:1px;overflow-wrap:anywhere}
  .act-item .msg .fc-old{text-decoration:line-through;color:var(--text3)}
  .act-item .msg .fc-new{font-weight:600;color:var(--text)}
  /* композер ПРИЖАТ К НИЗУ дока (требование владельца) */
  .compose{border-top:1px solid var(--border);padding:8px 12px 10px;flex-shrink:0;background:var(--surface);box-shadow:0 -8px 16px -14px rgba(15,23,42,.4)}
  .compose .row{display:flex;gap:6px;align-items:flex-end}
  .compose .row.kinds{margin-bottom:6px;align-items:center}
  .ckind.on{background:var(--blue-bg);border-color:var(--blue-bd);color:#1d4ed8}
  .compose textarea{flex:1;border:1px solid var(--border);border-radius:10px;background:var(--surface);
    min-height:34px;max-height:150px;resize:none;overflow-y:auto;padding:7px 11px;font:12px/1.45 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text)}
  .compose textarea:focus{outline:2px solid var(--blue-bd);border-color:var(--blue-bd)}
  .compose #send{height:34px;width:38px;justify-content:center;font-size:15px}
  @media (max-width:1345px){
    .main{display:block}
    .body-scroll{overflow:visible;padding:12px}
    .dock{width:auto;height:auto;max-height:70vh;border:1px solid var(--border);border-radius:11px;margin:0 12px 12px}
  }
  
  details.fold{border-top:1px solid var(--border)}
  details.fold summary{font-size:11px;font-weight:600;color:var(--text3);cursor:pointer;padding:6px 12px;list-style:none;display:flex;gap:6px;align-items:center;min-height:27px}
  details.fold summary::before{content:'▸';font-size:11px;transition:transform .15s}
  details.fold[open] summary::before{transform:rotate(90deg)}
  
  /* режим настройки вкладок: перестановка/удаление/добавление вкладок и полей */
  .sec-tools{display:none;gap:4px;margin-left:8px}
  .sec-tools button{border:1px solid var(--border);background:var(--surface);border-radius:6px;
    font-size:11px;padding:1px 7px;cursor:pointer;color:var(--text2);min-height:22px}
  .sec-tools button:hover{border-color:var(--accent);color:var(--accent)}
  #add-sec{display:none;margin:0 0 12px;border:1px dashed var(--border2);background:transparent;border-radius:11px;
    padding:10px;font-size:12px;font-weight:600;color:var(--text3);cursor:pointer;width:100%}
  #add-sec:hover{color:var(--accent);border-color:var(--accent)}
  .modal-bg{position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:90;display:none;align-items:center;justify-content:center}
  .modal-bg.on{display:flex}
  .modal{background:var(--surface);border-radius:14px;padding:18px 20px;width:430px;max-width:92vw;box-shadow:0 18px 50px rgba(0,0,0,.25)}
  .modal h4{margin:0 0 10px;font-size:15px}
  .modal input[type=text]{width:100%;border:1px solid var(--border);border-radius:8px;padding:8px 11px;font:13px Inter,sans-serif;margin-bottom:10px}
  .type-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:12px}
  .type-grid button{border:1px solid var(--border);background:var(--surface);border-radius:8px;padding:7px 4px;
    font-size:11px;font-weight:600;color:var(--text2);cursor:pointer}
  .type-grid button.on,.type-grid button:hover{border-color:var(--accent);color:var(--accent);background:var(--blue-bg)}
  .modal .row{display:flex;gap:8px;justify-content:flex-end}
  
  .fi.hit{outline:2px solid var(--accent);outline-offset:-1px;border-radius:7px}
  
  /* ── ЖИВАЯ ПЛОСКОСТЬ: свободное перетаскивание вкладок и полей в режиме настройки ── */
  .drag-h{cursor:grab;color:var(--text3);font-size:13px;padding:0 4px;user-select:none}
  .drag-h:active{cursor:grabbing}
  .cardb.dragging{opacity:.45;outline:2px solid var(--accent)}
  /* плейсхолдер МЕСТА вставки: горизонтальная полоса там, куда встанет вкладка/поле */
  .drop-ph{border-top:3px solid var(--accent);border-radius:3px;margin:2px 0;box-shadow:0 0 6px rgba(59,130,246,.5);pointer-events:none}
  .drop-phf{pointer-events:none;background:var(--accent);border-radius:3px}
  .fgrid .drop-phf{height:3px;margin:2px 8px}
  .hfields .drop-phf{width:3px;align-self:stretch;min-height:34px}
  /* поля в режиме настройки таскаются, не редактируются */
  .fi.dragging{opacity:.45;outline:2px solid var(--accent);border-radius:7px}
  /* пустая колонка: в настройке — пунктирная зона-приёмник, вне настройки — сетка схлопывается без дыры */
  /* тонкая полоса-хинт сверху при входе в режим настройки */
  .admin-hint{display:none;background:var(--blue-bg);color:var(--blue-fg);border-bottom:1px solid var(--blue-bd);font-size:11px;font-weight:600;text-align:center;padding:4px 10px;flex-shrink:0}
  /* регулятор «сколько вкладок в ряду» — сегментированный переключатель в панели настройки */
  .cols-ctl{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
  .cols-ctl .lbl{font-size:11px;font-weight:600;color:var(--blue-fg)}
  .cols-seg{display:inline-flex;border:1px solid var(--blue-bd);border-radius:8px;overflow:hidden;background:var(--surface)}
  .cols-seg button{border:0;border-left:1px solid var(--blue-bd);background:transparent;color:var(--text2);
    font:600 11px/1 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;padding:0 9px;min-height:22px;cursor:pointer}
  .cols-seg button:first-child{border-left:0}
  .cols-seg button:hover{color:var(--accent)}
  .cols-seg button.on{background:var(--blue-bg);color:var(--accent)}
  .cols-eff{font-size:11px;font-weight:600;color:var(--text3)}
  /* крестик на чипе шапки: «убрать из шапки» — поле вернётся в свою вкладку */
  .hf-x{display:none;position:absolute;top:-6px;right:-6px;width:16px;height:16px;border-radius:50%;background:var(--surface);border:1px solid var(--border2);color:var(--text3);font-size:11px;align-items:center;justify-content:center;cursor:pointer;z-index:3;line-height:1}
  .hf-x:hover{color:var(--red);border-color:var(--red)}
  /* настраиваемые таблицы: попап колонок + ручки ресайза */
  .tcols{margin-left:auto}
  .colpop{position:fixed;z-index:95;background:var(--surface);border:1px solid var(--border);border-radius:11px;
    box-shadow:0 12px 34px rgba(15,23,42,.18);padding:10px 13px;width:220px;display:flex;flex-direction:column;gap:2px}
  .colpop b{font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text3);margin-bottom:4px}
  .colpop label{display:flex;gap:7px;align-items:center;font-size:12px;padding:3px 2px;cursor:pointer;border-radius:6px}
  .colpop label:hover{background:var(--surface2)}
  .colpop .mut{color:var(--text3);font-size:11px}
  th{position:relative}
  .th-rz{position:absolute;right:-4px;top:0;bottom:0;width:8px;cursor:col-resize;z-index:2}
  .th-rz:hover{background:linear-gradient(90deg,transparent 3px,var(--accent) 3px,var(--accent) 5px,transparent 5px)}
  /* перетаскивание колонки за заголовок th */
  table.items th[draggable]{cursor:grab}
  table.items th.col-drag{opacity:.45;background:var(--blue-bg)}
  table.items th.col-drop{box-shadow:inset 3px 0 0 var(--accent)}
  
  /* задачи — живые данные системы в новом дизайне */
  .task{align-items:flex-start}
  .task.late{border-left:3px solid var(--red);padding-left:8px;margin-left:-11px;background:linear-gradient(90deg,var(--red-bg),transparent 60%);border-radius:0 8px 8px 0}
  .task .tx{min-width:0;flex:1}
  .task .tx .d{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
  .task .due.red{color:var(--red);font-weight:700}
  .task .ava-s{width:16px;height:16px;border-radius:50%;color:#fff;font-size:11px;font-weight:700;
    display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
  .task-res{display:block;font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
    max-width:100%;margin-top:1px;font-style:italic;cursor:pointer}
  .task-res:hover{color:var(--text2)}
  
  /* задачи внутри единой ленты (как амо): чекбокс вместо иконки, карточка-строка */
  .act-item.task-line{border:1px solid var(--border);border-radius:10px;padding:7px 10px;margin:3px 0;background:var(--surface)}
  .act-item.task-line.late{border-left:3px solid var(--red);background:linear-gradient(90deg,var(--red-bg),var(--surface) 55%)}
  .act-item.task-line.done .who b{text-decoration:line-through;color:var(--text3);font-weight:500}
  .act-item.task-line .chk{width:18px;height:18px;border:1.5px solid var(--border2);border-radius:4px;margin-top:1px;flex-shrink:0;
    cursor:pointer;display:flex;align-items:center;justify-content:center;color:transparent;font-size:11px}
  .act-item.task-line.done .chk{background:var(--green);border-color:var(--green);color:#fff}
  .act-item.task-line.done .chk::after{content:'✓'}
  .fchips .cnt{font-size:11px;color:var(--text3)}
  
  /* поля ОСНОВНОГО в шапке: компактные чип-поля, кликом редактируются (тот же .fi-движок) */
  .hfields{display:flex;gap:5px;margin:0 0 6px;flex-wrap:wrap;align-items:stretch}
  .hfields .fi{display:inline-flex;flex-direction:row;align-items:center;gap:6px;min-height:0;
    border:1px solid var(--border);border-radius:10px;background:var(--surface);padding:4px 9px;min-width:0}
  .hfields .fi:hover{background:var(--surface)}
  .hfields .fi .k{font-size:11px;text-transform:uppercase;letter-spacing:.4px;white-space:nowrap}
  .hfields .fi .v{font-size:12px;font-weight:600;text-align:left;justify-self:start;max-width:220px;padding:0}
  .hfields .fi.empty .v{border:none;padding:0;font-size:11px}
  .hfields .fi.ro{background:var(--surface2);border-color:transparent}
  .hfields .fi input,.hfields .fi select{height:24px;width:150px;min-width:0;text-align:left;font-size:12px}
  
  /* D4: низкое окно/зум — шапка не съедает пол-экрана */
  @media (max-height:820px){
    .hero{padding:6px 20px 0}
    .title-row h1{font-size:17px}
    .kpi{padding:5px 14px 6px}
    .kpi .kv{font-size:15px}
    .kpi .bar{display:none}
    .pchips{margin:2px 0 6px}
    .hfields{margin:0 0 5px}
  }
  @media (max-height:720px){
    .crumbs{display:none}
    .pchip .pl{display:none}
    .compose{padding:5px 10px 6px}
    .fchips{margin:2px 14px 0}
  }
  
  /* фильтр ленты классом (0 инлайн-стилей) */
  #feed.f-task .act-item:not([data-kind="task"]),
  #feed.f-note .act-item:not([data-kind="note"]),
  #feed.f-change .act-item:not([data-kind="change"]){display:none}
  /* containment: медиана кадра 23→17мс, 43→58 FPS (замер аудита) */
  .cardb{content-visibility:auto;contain-intrinsic-size:auto 320px}
  #feed .act-item{content-visibility:auto;contain-intrinsic-size:auto 56px}
  /* липкая шапка таблиц при длинных списках */
  table.items thead th{position:sticky;top:0;z-index:2;background:var(--surface2)}
  table.items thead th:first-child{z-index:3}
  #items-box,#rel-box{max-height:70vh;overflow-y:auto}
  /* навигация: вкладки не прячутся за краем, поиск/тумблер закреплены справа */
  .anchor-bar{scrollbar-width:thin}
  .anchor-bar::-webkit-scrollbar{height:6px}
  .anchor-bar .he{position:sticky;right:0;background:var(--surface);z-index:2}
  /* ── A11Y: контраст и фокус ── */
  :focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .cardb .hd h3,.cardb .hd .cnt,.cardb .hd .act,table.items th{color:#57606e}
  .btn.pri{background:#2563eb}
  .btn.pri:hover{background:#1d4ed8}
  .kpi .kv.red{color:var(--red-fg)}
  .pchip .pgo{color:var(--text3)}
  .chk,.task .chk,.task-line .chk{border-color:#9ca3af}
  .ava-s{color:#fff!important;border-radius:50%!important}
  .task .chk,.task-line .chk{width:20px;height:20px;padding:0}
  .colpop label{min-height:26px}
  .sec-tools button,.cardb .hd .act,.pact{min-height:24px}
  .th-rz{width:10px;right:-5px}
  
  .hfields .fi{align-self:start}
  .hfields .fi input,.hfields .fi select{width:150px;max-width:150px;min-width:150px}
  .hfields .fi.long{grid-template-columns:1fr}
  .hfields .fi .v,.hfields .fi.long .v{max-width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .fi input,.fi select{height:24px;min-width:min(180px,100%)}
  .fi textarea{font:500 13px/1.4 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;border:1px solid var(--blue-bd);border-radius:7px;padding:6px 9px}
  
  .hfields .fi .v{max-height:34px;overflow:hidden}
  .act-item .msg{display:-webkit-box;-webkit-line-clamp:6;-webkit-box-orient:vertical;overflow:hidden}
  
  /* аудит типографа 2026-08-14: tabular-nums на все числа-метаданные, единые пары */
  .who .tm,.msg .due,.hd .cnt,.fchips .fc,.dock-hd .sub,.badge,.alert,.check,.crumbs b{font-variant-numeric:tabular-nums}
  .fchips .fc{white-space:nowrap}
  .title-row h1{line-height:1.2}
  .compose textarea{font-size:13px}
  .msg .due{font-size:11px}
  /* длина строки юртекстов ограничена читаемым пределом */
  .fi.long .v{max-width:72ch}
  
  .kpi .kv.txt{font-size:15px;font-family:'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif}
  .kpi .kv .of{font-size:11px;color:var(--text3);font-weight:500;font-family:'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif}
  
  /* владелец: полоса вкладок не нужна; поиск поля и тумблер пустых переехали в титульную строку —
     полоса скрыта целиком (якоря остаются в DOM для навигации/скролл-спая) */
  .anchor-bar a{display:none}
  .anchor-bar{display:none;padding:4px 12px;box-shadow:none;border-top:1px solid var(--border)}
  
  /* [BUG-3/П.5] поиск поля удалён совсем; «скрыть пустые» живёт в титульной строке рядом с «Настроить вкладки» */
  .title-row .crumbs{margin-right:4px}
  .title-row .he{font-size:11px;color:var(--text3);display:flex;gap:5px;align-items:center;cursor:pointer;white-space:nowrap}
  
  /* [BUG-4] компакт-бейджи статусов у KPI/чипов: полный текст — в tooltip (title) */
  .kbadge{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-weight:700;line-height:1;
    border-radius:999px;padding:2px 6px;margin-left:5px;vertical-align:middle;cursor:help;white-space:nowrap}
  .kbadge.ok{background:var(--green-bg);color:var(--green-fg)}
  .kbadge.warn{background:var(--orange-bg);color:var(--orange-fg)}
  .kbadge.red{background:var(--red-bg);color:var(--red-fg)}
  .kbadge.blu{background:var(--blue-bg);color:var(--blue-fg)}
  .pchips .kbadge{align-self:center;margin-left:0}
  .late-b{color:var(--red-fg);font-weight:700}
  
  /* [BUG-2] режим настройки: «✕» скрытия есть у КАЖДОГО поля тела и чипа шапки (виден на hover) */
  .fi-x{display:none;position:absolute;top:50%;right:8px;transform:translateY(-50%);width:16px;height:16px;
    border-radius:50%;background:var(--surface);border:1px solid var(--border2);color:var(--text3);
    font-size:11px;align-items:center;justify-content:center;cursor:pointer;z-index:3;line-height:1}
  .fi-x:hover{color:var(--red);border-color:var(--red)}
  .hfields .fi .fi-x{top:-6px;right:-6px;transform:none}
  
  /* ── [layout_orientation] ОРИЕНТАЦИЯ ВКЛАДКИ: «вертикально» = колонка в сетке .grid3,
     «горизонтально» (.cardb.horiz) = вкладка во всю ширину тела, а её поля — ГАЗЕТНЫМИ колонками
     на ЕДИНОЙ сетке: порядок чтения сверху вниз внутри колонки, затем следующая колонка
     (grid-auto-flow:column; число строк --hrows считает applyHoriz() от числа полей и ширины);
     колонки равной ширины (grid-auto-columns:minmax(0,1fr)); поля одной строки делят ОБЩИЙ
     row-track сетки → подписи/значения соседних колонок сидят на одной горизонтали.
     INFO/SYSTEM — те же вкладки с «горизонтально» по умолчанию (один механизм, не вторая реализация). */
  .cardb.horiz .bd > .fgrid{grid-template-columns:none;grid-auto-flow:column;
    grid-auto-columns:minmax(0,1fr);grid-template-rows:repeat(var(--hrows,8),auto)}
  .cardb.horiz .bd > .fgrid > .fi.long{grid-column:auto}
  /* переключатель ориентации на заголовке вкладки (виден только в режиме настройки — внутри .sec-tools) */
  .sec-tools [data-orient]{font-size:12px;line-height:1}
  .sec-tools [data-orient].h-on{background:var(--blue-bg);border-color:var(--blue-bd);color:var(--accent)}
  
  /* ═══ слой: v8-css.txt ═══ */
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     v8 · ОБЩИЙ СЛОЙ ДВУХ ФИНАЛЬНЫХ МОКАПОВ (v8-order.html + v8-purchase.html).
     Файл ТОЛЬКО для v8: подключается ПОСЛЕ общего sales-css.txt, ничего в нём не правит.
     v7-17/18/19 этот файл не подключают → их вид не может измениться.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  
  /* ── компактная шапка: крошки в одной строке с заголовком, фактов-строка, прогресс ── */
  .hero{padding:5px 20px 0}
  .title-row{margin:0 0 1px;gap:9px}
  .title-row .crumbs{align-self:center}
  /* крошка-родитель: ЕДИНСТВЕННЫЙ путь от закупки к её заказу — обычная ссылка, как в SLDS breadcrumbs */
  .crumbs a.c-up{color:var(--accent);font-weight:600;text-decoration:none}
  .crumbs a.c-up:hover{text-decoration:underline}
  .crumbs .c-top{display:flex;gap:6px;color:var(--text3)}
  .crumbs .cpos{color:var(--text3);cursor:help}
  .factbar{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--text3);
    white-space:nowrap;overflow-x:auto;scrollbar-width:none;margin:1px 0 2px}
  .factbar::-webkit-scrollbar{height:0}
  .factbar b{color:var(--text2);font-weight:600}
  .factbar .sep{color:var(--border2)}
  .prog{height:6px;border-radius:999px;background:var(--surface3);overflow:hidden}
  .prog i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#2563eb,#60a5fa)}
  .prog-cap{font-size:11px;color:var(--text3);margin:2px 0 3px}
  /* строка условий сделки (инкотермс/поставка/оплата) — под чипами, одной строкой */
  .terms{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text3);
    white-space:nowrap;overflow-x:auto;scrollbar-width:none;margin:0 0 5px}
  .terms::-webkit-scrollbar{height:0}
  .terms .tl{text-transform:uppercase;font-size:11px;letter-spacing:.4px}
  .terms b{color:var(--text);font-weight:600}
  .terms .sep{color:var(--border2)}
  .tset{border:1px dashed var(--border2);border-radius:7px;background:transparent;color:var(--text3);
    font:600 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;padding:1px 8px;cursor:pointer;min-height:20px}
  .tset:hover{border-color:var(--accent);color:var(--accent)}
  .terms a.edit{font-size:11px;font-weight:600}
  
  /* ── денежная полоса хаба: ровно 4 числа, тот же вид, что у KPI ── */
  /* внутри карточки отрицательные поля общей .kpis не нужны — первое число резалось слева */
  #sec-money .kpis{margin:0;grid-template-columns:repeat(4,minmax(0,1fr));border-top:0}
  #sec-money .kpi{padding:7px 14px 8px}
  #sec-money .kpi .kv{font-size:17px}
  .moneybar{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden;
    box-shadow:0 1px 2px rgba(15,23,42,.05)}
  .moneybar .kpis{margin:0;border-top:0;grid-template-columns:repeat(4,minmax(0,1fr))}
  .moneybar .kpi{padding:7px 14px 8px}
  .moneybar .kpi .kv{font-size:17px}
  .money-note{font-size:11px;color:var(--text3);padding:0 14px 7px}
  .money-text{padding:12px 14px;font-size:12px;color:var(--orange-fg);background:var(--orange-bg);font-weight:600}
  
  /* ── красный блок «не разнесено» ── */
  .redbox{background:var(--surface);border:1px solid var(--red);border-radius:12px;overflow:hidden}
  .redbox .rb-hd{display:flex;align-items:baseline;gap:8px;padding:9px 13px 1px;flex-wrap:wrap}
  .redbox .rb-t{font-size:13px;font-weight:700;color:var(--red-fg)}
  .redbox .rb-s{font-size:11px;color:var(--text3)}
  .redbox .rb-d{font-size:11px;color:var(--text3);padding:0 13px 6px}
  .ur{display:flex;align-items:center;gap:10px;padding:5px 13px;border-top:1px solid var(--surface2);font-size:12px}
  .ur:hover{background:var(--surface2)}
  .ur.all{background:var(--surface2);font-weight:600}
  .ur input[type=checkbox]{width:16px;height:16px;accent-color:var(--accent);cursor:pointer;flex-shrink:0;margin:0}
  .ur .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ur .q{color:var(--text3);font-variant-numeric:tabular-nums;min-width:26px;text-align:right}
  .ur .sum{font-weight:700;font-variant-numeric:tabular-nums;min-width:104px;text-align:right}
  .selbar{display:none;align-items:center;gap:8px;padding:8px 13px;border-top:1px solid var(--border);
    background:var(--blue-bg);flex-wrap:wrap}
  .selbar.on{display:flex}
  .selbar .cnt2{font-size:12px;font-weight:700;color:var(--blue-fg)}
  .selbar input[type=text]{border:1px solid var(--blue-bd);border-radius:8px;padding:4px 9px;min-height:26px;
    font:12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;background:var(--surface);color:var(--text);width:250px;max-width:100%}
  .splitbar{display:flex;align-items:center;gap:9px;padding:8px 13px;border-top:1px solid var(--border);flex-wrap:wrap}
  .splitbar .hint{font-size:11px;color:var(--text3)}
  /* ── [SPLIT-COMMAND-LIVES-WITH-DATA] форма разбиения по количеству: ОДНО поле и живой остаток ──
     Раскрывается ПОД полосой выбора, в той же карточке, где стоит строка. Отдельным окном её делать
     нельзя: боковая панель закрывает предыдущую, и человек теряет из виду сам состав, ради которого
     всё затевалось (тот же довод, что у формы отделения на экране заказа). */
  .qsplit{padding:9px 13px;border-top:1px solid var(--border);background:var(--surface2)}
  .qsplit[hidden]{display:none}
  .qsplit .qs-t{font-size:13px;font-weight:600;margin-bottom:6px}  /* шкала {11,13,15,17,19}: 12px вне её */
  .qsplit .qs-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .qsplit .qs-l{font-size:11px;color:var(--text3)}
  .qsplit .qs-i{border:1px solid var(--blue-bd);border-radius:8px;padding:4px 9px;min-height:26px;width:110px;
    text-align:right;font:12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    font-variant-numeric:tabular-nums;background:var(--surface);color:var(--text)}
  .qsplit .qs-u{font-size:11px;color:var(--text3);font-variant-numeric:tabular-nums}
  .qsplit .qs-left{font-size:11px;color:var(--text3);font-variant-numeric:tabular-nums}
  .qsplit .qs-left.bad{color:var(--red-fg)}
  .qsplit .qs-act{display:flex;gap:8px;margin-top:8px}
  
  /* ── таблицы v8: чекбоксы строк, группы по этапам, сортировка, знак маржи ── */
  table.items th.selc,table.items td.selc{width:38px;padding:5px 4px 5px 12px;text-align:center}
  table.items td.selc input,table.items th.selc input{width:15px;height:15px;cursor:pointer;accent-color:var(--accent);margin:0}
  table.items tr.sel td{background:var(--blue-bg)}
  table.items tr.grp td{background:var(--surface3);color:var(--text3);font-size:11px;font-weight:700;
    text-transform:uppercase;letter-spacing:.5px;padding:4px 12px;white-space:nowrap}
  table.items td.neg{color:var(--red-fg);font-weight:700}
  table.items td.pos{color:var(--green-fg);font-weight:600}
  table.items td.mut{color:var(--text3)}
  table.items td.code{font-family:var(--mono);font-weight:700;white-space:nowrap}
  table.items th.srt{cursor:pointer}
  /* ручка ресайза ВНУТРИ своей ячейки: при right:-5px её перекрывал следующий th и потянуть было нельзя */
  table.items th .th-rz{right:0;width:12px;z-index:5}
  table.items th .sar{font-size:11px;margin-left:4px;color:var(--accent)}
  .sdot{display:inline-block;width:3px;height:12px;border-radius:2px;margin-right:8px;vertical-align:-1px}
  .tbl-cap{font-size:11px;color:var(--text3);padding:7px 14px}
  .tbl-cap b{color:var(--text2)}
  
  /* ── сворачиваемый блок условий оплаты ── */
  details.terms-fold{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden}
  details.terms-fold > summary{list-style:none;cursor:pointer;padding:9px 13px;font-size:12px;font-weight:700;
    text-transform:uppercase;letter-spacing:.4px;color:var(--text2);display:flex;gap:7px;align-items:center;background:var(--surface2)}
  details.terms-fold > summary::-webkit-details-marker{display:none}
  details.terms-fold > summary::before{content:'▸';font-size:11px;color:var(--text3);transition:transform .15s}
  details.terms-fold[open] > summary::before{transform:rotate(90deg)}
  .terms-body{padding:10px 14px;font-size:12px;color:var(--text2);line-height:1.6}
  .terms-body .row2{display:flex;gap:10px;align-items:baseline;padding:3px 0;border-bottom:1px solid var(--surface2);flex-wrap:wrap}
  .terms-body .row2:last-child{border-bottom:0}
  .terms-body .lb{font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);min-width:150px}
  
  /* ── плашка RBAC ── */
  .rbac{display:flex;align-items:center;gap:9px;background:var(--surface2);border:1px dashed var(--border2);
    border-radius:11px;padding:9px 13px;font-size:12px;color:var(--text3)}
  .rbac b{color:var(--text2)}
  
  /* ── меню «⚡ Действия» (D4) ── */
  .menu{position:fixed;z-index:96;background:var(--surface);border:1px solid var(--border);border-radius:11px;
    box-shadow:0 12px 34px rgba(15,23,42,.18);padding:5px;min-width:250px;display:flex;flex-direction:column;gap:1px}
  .menu button{border:0;background:transparent;text-align:left;cursor:pointer;color:var(--text2);
    font:600 12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;padding:7px 9px;border-radius:8px;
    display:flex;gap:8px;align-items:center;min-height:28px}
  .menu button:hover{background:var(--surface2);color:var(--text)}
  .menu button.danger{color:var(--red-fg)}
  .menu button.danger:hover{background:var(--red-bg)}
  .menu .sep{height:1px;background:var(--border);margin:4px 2px}
  .menu .mt{font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text3);padding:5px 9px 2px;font-weight:700}
  
  /* ── D1: пул скрытых вкладок + инлайн-подтверждение вместо confirm (D6) ── */
  .tabs-pool{display:none;align-items:center;gap:7px;flex-wrap:wrap;font-size:11px;color:var(--text3);
    border:1px dashed var(--border2);border-radius:11px;padding:7px 11px;background:var(--surface)}
  .tabs-pool.on{display:flex}
  .tabs-pool .tp-l{font-weight:700;text-transform:uppercase;letter-spacing:.4px}
  .tabs-pool button{border:1px solid var(--border);background:var(--surface);border-radius:999px;
    font:700 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text2);padding:3px 11px;cursor:pointer;min-height:24px}
  .tabs-pool button:hover{border-color:var(--accent);color:var(--accent);background:var(--blue-bg)}
  .hd-confirm{display:inline-flex;align-items:center;gap:6px;margin-left:auto;font-size:11px;font-weight:700;color:var(--red-fg)}
  .hd-confirm button{border:1px solid var(--border);background:var(--surface);border-radius:7px;
    font:700 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;padding:2px 9px;cursor:pointer;min-height:22px;color:var(--text2)}
  .hd-confirm button.yes{background:var(--red-bg);border-color:var(--red-bg);color:var(--red-fg)}
  .hd-confirm button:hover{border-color:var(--accent)}
  
  /* ── D15: чипы связей настраиваются как поля (✕ + перетаскивание) ── */
  .pchip-x{display:none;position:absolute;top:-6px;right:-6px;width:16px;height:16px;border-radius:50%;
    background:var(--surface);border:1px solid var(--border2);color:var(--text3);font-size:11px;
    align-items:center;justify-content:center;cursor:pointer;z-index:3;line-height:1}
  .pchip-x:hover{color:var(--red);border-color:var(--red)}
  .pchip.dragging{opacity:.45;outline:2px solid var(--accent)}
  .pchips .drop-phc{width:3px;align-self:stretch;min-height:30px;background:var(--accent);border-radius:3px;pointer-events:none}
  .chip-add{display:none;border:1px dashed var(--border2);background:transparent;border-radius:10px;
    font:600 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text3);padding:4px 10px;cursor:pointer;min-height:26px}
  .chip-add:hover{border-color:var(--accent);color:var(--accent)}
  
  /* ── D2: лента открывается снизу, кнопка возврата к новым ── */
  .dock{position:relative}
  .to-new{position:absolute;right:16px;bottom:96px;z-index:5;display:none;align-items:center;gap:6px;
    background:var(--pri-bg);color:#fff;border:0;border-radius:999px;padding:5px 12px;cursor:pointer;
    font:700 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;box-shadow:0 6px 18px rgba(37,99,235,.35);min-height:26px}
  .to-new.on{display:inline-flex}
  .act-item.fresh{animation:v8fresh 1.6s ease-out}
  @keyframes v8fresh{0%{background:var(--blue-bg)}100%{background:transparent}}
  
  /* ── 5a: полоса фильтров дока — ОДНА строка, ≤28px, без переноса ── */
  .dock .fchips{display:flex;flex-wrap:nowrap;align-items:center;gap:2px;width:auto;margin:4px 10px 2px;
    padding:2px;max-height:26px;overflow:hidden}
  .dock .fchips .fc{font-size:11px;font-weight:700;padding:2px 6px;min-height:20px;line-height:16px;
    display:inline-flex;align-items:center;gap:4px;white-space:nowrap;flex-shrink:0}
  .dock .fchips .fc i{font-style:normal;font-size:11px;font-weight:700;color:var(--text3);
    background:var(--surface3);border-radius:5px;padding:0 4px;line-height:14px}
  .dock .fchips .fc.on i{background:var(--blue-bg);color:var(--blue-fg)}
  .dock .fchips .fsum{margin-left:auto;font-size:11px;color:var(--text3);white-space:nowrap;
    cursor:help;font-variant-numeric:tabular-nums;padding-left:6px;min-width:0;flex-shrink:0}
  .dock .fchips .fsum b{color:var(--red-fg);font-weight:700}
  .dock .fchips.tight{gap:1px}
  .dock .fchips.tight .fc{padding:2px 4px;gap:3px}
  .dock .fchips.tight .fc i{padding:0 3px}
  .dock .fchips.tight .fsum{padding-left:4px}
  /* подпись прогресса на узком окне переезжает в строку фактов (шапка не растёт) */
  .only-narrow{display:none}
  /* просроченный срок в ленте — красным (в общем CSS правило было только для старого .task) */
  .act-item.task-line .due.red{color:var(--red-fg);font-weight:700}
  
  /* ── D13: композер растёт до 5 строк ── */
  .compose textarea{max-height:112px}
  
  /* ── горизонтальные вкладки в 4 колонки: подпись сверху, значение под ней (эталон владельца) ── */
  .cardb.horiz .bd > .fgrid{gap:0 18px}
  .cardb.horiz .bd > .fgrid > .fi{grid-template-columns:minmax(0,1fr);gap:0;align-items:start;
    padding:4px 12px 5px;min-height:0}
  .cardb.horiz .bd > .fgrid > .fi.long{grid-column:auto}
  .cardb.horiz .fi .k{font-size:11px;text-transform:uppercase;letter-spacing:.4px;line-height:1.35}
  .cardb.horiz .fi .v{text-align:left;justify-self:start;width:100%;max-width:100%;white-space:normal;
    overflow:visible;text-overflow:clip;min-height:20px;padding:1px 5px;margin-left:-5px;line-height:1.35}
  .cardb.horiz .fi.empty .v{display:inline-block;width:auto;margin-left:0;padding:1px 8px}
  .cardb.horiz .fi input,.cardb.horiz .fi select{justify-self:start;text-align:left}
  .cardb.horiz .fi .inh{font-size:11px;font-weight:700;color:var(--blue-fg);background:var(--blue-bg);
    border-radius:5px;padding:0 4px;margin-left:5px;cursor:help;letter-spacing:0;text-transform:none}
  
  /* ── D7: на узком окне чипы одной строкой, док остаётся закреплённым справа,
        шапка ужимается (была 29-31%, стала ~19-20%) ── */
  @media (max-width:1400px){
    .pchips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-bottom:1px;margin:2px 0 4px}
    .pchips::-webkit-scrollbar{height:0}
    .pchip,.chip-add{flex-shrink:0}
    .pchip{padding:2px 8px}
    .pchip .pa{width:22px;height:22px;font-size:11px}
    .pchip .pv{max-width:170px}
    .hero{padding:4px 14px 0}
    .title-row h1{font-size:17px}
    /* узко — крошки уступают место названию; но крошка С РОДИТЕЛЕМ не исчезает: это единственный путь
       наверх. Усечение как в SLDS: верхние уровни скрываются, остаются родитель и текущая запись. */
    .title-row .crumbs{display:none}
    .title-row .crumbs.has-parent{display:flex}
    .crumbs.has-parent .c-top{display:none}
    .kpis{margin:0 -14px}
    .kpi{padding:3px 12px 5px}
    .kpi .kv{font-size:15px}
    .moneybar .kpi .kv{font-size:15px}
    .terms{margin-bottom:4px}
    .factbar{margin:0 0 2px}
    .prog-cap{display:none}
    .only-narrow{display:inline}
    /* заголовочная строка обязана оставаться ОДНОЙ строкой: демо-селектор ужимается */
    .demo label{display:none}
    .demo select{max-width:170px}
    .title-row .btn{padding:5px 10px}
    .title-row .he{font-size:11px}
  }
  /* отмена «блочного потока» общего CSS: док не уезжает вниз, шапка не растёт */
  @media (max-width:1345px){
    .main{display:flex}
    .body-scroll{overflow-y:auto;padding:12px}
    .dock{width:clamp(300px,26vw,400px);height:100%;max-height:none;margin:0;border:0;
      border-left:1px solid var(--border);border-radius:0}
  }
  
  /* .sibs (полоса-переключатель соседних закупок) и .idbar (полоса идентичности) удалены вместе со своей
     разметкой: семья заказа перечисляется таблицей «Связанные сделки», связь с родителем — крошкой. */
  
  /* ── демо-переключатель состояний (только мокап) ── */
  .demo{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text3)}
  .demo select{border:1px solid var(--border);border-radius:7px;padding:2px 6px;min-height:24px;
    font:600 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;background:var(--surface);color:var(--text2)}
  body.demo-empty #sec-money,body.demo-empty #sec-unalloc,body.demo-empty #sec-parts,
  body.demo-empty #sec-terms,body.demo-empty #sec-rbac,body.demo-empty .factbar,
  
  /* ── мастер трёх шагов (перенесён из v7-19 без изменений) ── */
  .wz-card{border-color:var(--blue-bd);box-shadow:0 2px 10px rgba(59,130,246,.10)}
  .wz-card > .hd{background:var(--blue-bg)}
  .wz-card > .hd h3,.wz-card > .hd .cnt{color:var(--blue-fg)}
  .wz{display:flex;align-items:stretch;gap:8px;padding:12px 14px;flex-wrap:wrap}
  .wz-arr{align-self:center;color:var(--border2);font-size:15px;flex-shrink:0}
  .wz-step{flex:1 1 260px;min-width:250px;display:flex;gap:10px;border:1px solid var(--border);
    border-radius:11px;padding:10px 12px;background:var(--surface)}
  .wz-step .wz-n{width:26px;height:26px;border-radius:50%;background:var(--surface3);color:var(--text3);
    font-size:15px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}
  .wz-step .wz-b{min-width:0;flex:1}
  .wz-step .wz-t{font-size:13px;font-weight:700}
  .wz-step .wz-d{font-size:11px;color:var(--text3);margin-top:2px;line-height:1.35}
  .wz-step .wz-act{display:flex;gap:6px;align-items:center;margin-top:8px;flex-wrap:wrap}
  .wz-step .wz-lb{font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:.4px}
  .wz-step select{border:1px solid var(--border);border-radius:7px;padding:4px 7px;
    font:12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    background:var(--surface);color:var(--text);max-width:210px;min-height:26px}
  .wz-step.active{border-color:var(--accent);background:var(--blue-bg);box-shadow:0 0 0 3px rgba(59,130,246,.12)}
  .wz-step.active .wz-n{background:var(--accent);color:#fff}
  .wz-step.active .wz-d{color:var(--blue-fg)}
  .wz-step.done{border-color:#bbf7d0;background:#f0fdf4}
  .wz-step.done .wz-n{background:var(--green);color:#fff;font-size:0}
  .wz-step.done .wz-n::after{content:'✓';font-size:13px}
  .wz-step.locked{opacity:.62;background:var(--surface2)}
  .wz-step.locked .wz-t{color:var(--text3)}
  .wz-step.locked .wz-act{display:none}
  .btn:disabled,.wz-step select:disabled{opacity:.5;cursor:not-allowed}
  .empty-state{display:flex;flex-direction:column;align-items:center;gap:8px;padding:26px 16px;text-align:center}
  .empty-state .es-ic{width:38px;height:38px;border-radius:11px;background:var(--surface2);color:var(--text3);
    display:flex;align-items:center;justify-content:center;font-size:17px}
  .empty-state .es-t{font-size:13px;font-weight:700}
  .empty-state .es-d{font-size:12px;color:var(--text3);max-width:520px;line-height:1.45}
  .empty-state .es-act{display:flex;gap:7px;margin-top:3px;flex-wrap:wrap;justify-content:center}
  .pv-rule{font-size:11px;color:var(--text3);padding:8px 14px;border-bottom:1px solid var(--border);line-height:1.5}
  .pv-rule b{color:var(--text2)}
  .pv-foot{display:flex;align-items:center;gap:8px;padding:9px 14px;border-top:1px solid var(--border);flex-wrap:wrap}
  .pv-foot .sp{flex:1}
  table.items select.supsel{width:100%;max-width:100%;border:1px solid var(--border);border-radius:7px;
    padding:2px 5px;font:12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    background:var(--surface);color:var(--text);min-height:24px}
  table.items select.supsel.none{border-style:dashed;border-color:var(--border2);color:var(--text3)}
  
  /* ══ ЗАДАЧИ И ПРИМЕЧАНИЯ: те же настройки, что в живой системе ══ */
  /* компактная форма задачи в доке (не модалка): поля в две колонки */
  .tform{display:none;border:1px solid var(--blue-bd);background:var(--blue-bg);border-radius:10px;
    padding:7px 9px;margin-bottom:6px}
  .tform .tf-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px 9px}
  .tform .tf-f{display:flex;flex-direction:column;gap:2px;min-width:0}
  .tform .tf-f.wide{grid-column:1/-1}
  .tform label{font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);font-weight:700}
  .tform select,.tform input{border:1px solid var(--border);border-radius:7px;background:var(--surface);
    color:var(--text);min-height:24px;padding:2px 6px;min-width:0;width:100%;
    font:600 11px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif}
  .tform .tf-quick{display:flex;gap:4px;margin-top:3px;flex-wrap:wrap}
  .tform .tf-quick button{border:1px solid var(--border);background:var(--surface);border-radius:999px;
    font:700 10px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    color:var(--text2);padding:2px 8px;cursor:pointer;min-height:20px}
  .tform .tf-quick button:hover,.tform .tf-quick button.on{border-color:var(--accent);color:var(--accent);background:var(--surface)}
  .tform .tf-note{font-size:11px;color:var(--text3);margin-top:4px;line-height:1.4}
  .tform .tdot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;vertical-align:0}
  /* тип задачи в ленте */
  .act-item.task-line .ttype{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
    border-radius:999px;padding:1px 7px;margin-right:6px;background:var(--surface2);color:var(--text2);white-space:nowrap}
  .act-item.task-line .tteam{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
    border-radius:999px;padding:1px 7px;background:var(--orange-bg);color:var(--orange-fg);margin-left:5px}
  .act-item.task-line .claim{border:1px solid var(--border);background:var(--surface);border-radius:7px;
    font:700 10px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    padding:1px 8px;cursor:pointer;color:var(--text2);margin-left:6px;min-height:20px}
  .act-item.task-line .claim:hover{border-color:var(--accent);color:var(--accent)}
  .act-item.task-line .tdur{font-size:11px;color:var(--text3);margin-left:5px}
  /* форма результата при закрытии задачи (результат живёт ВНУТРИ карточки задачи) */
  .tres{display:flex;flex-direction:column;gap:5px;margin-top:6px;border-top:1px dashed var(--border);padding-top:6px}
  .tres textarea{border:1px solid var(--blue-bd);border-radius:8px;padding:5px 8px;resize:vertical;min-height:42px;
    font:12px/1.4 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text);background:var(--surface)}
  .tres .rw{display:flex;gap:6px;align-items:center}
  .tres .err{font-size:11px;color:var(--red-fg);font-weight:700;display:none}
  .tres.bad .err{display:block}
  .tres.bad textarea{border-color:var(--red)}
  /* шаблоны примечаний и @-упоминания */
  .tplpop{position:fixed;z-index:97;background:var(--surface);border:1px solid var(--border);border-radius:12px;
    box-shadow:0 14px 40px rgba(15,23,42,.2);width:360px;max-width:94vw;display:flex;flex-direction:column;overflow:hidden}
  .tplpop .tp-s{padding:8px;border-bottom:1px solid var(--border)}
  .tplpop .tp-s input{width:100%;border:1px solid var(--border);border-radius:8px;padding:5px 9px;min-height:26px;
    font:12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text);background:var(--surface)}
  .tplpop .tp-c{display:flex;gap:3px;padding:6px 8px;border-bottom:1px solid var(--border);overflow-x:auto;scrollbar-width:none}
  .tplpop .tp-c button{border:1px solid var(--border);background:var(--surface);border-radius:999px;padding:2px 8px;
    font:700 10px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text2);cursor:pointer;white-space:nowrap;min-height:20px}
  .tplpop .tp-c button.on{background:var(--blue-bg);border-color:var(--accent);color:var(--blue-fg)}
  .tplpop .tp-l{max-height:270px;overflow-y:auto;padding:4px}
  .tplpop .tp-i{padding:6px 8px;border-radius:8px;cursor:pointer}
  .tplpop .tp-i:hover{background:var(--surface2)}
  .tplpop .tp-i b{display:block;font-size:12px;font-weight:700}
  .tplpop .tp-i span{display:block;font-size:11px;color:var(--text3);margin-top:1px;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tplpop .tp-i i{font-style:normal;font-size:11px;font-weight:700;color:var(--blue-fg);background:var(--blue-bg);border-radius:5px;padding:0 4px;margin-left:5px}
  .tplpop .tp-e{padding:14px;font-size:12px;color:var(--text3);text-align:center}
  .mentions{position:fixed;z-index:98;background:var(--surface);border:1px solid var(--border);border-radius:10px;
    box-shadow:0 12px 30px rgba(15,23,42,.18);width:220px;max-height:210px;overflow-y:auto;padding:4px;display:none}
  .mentions.on{display:block}
  .mentions button{display:flex;width:100%;gap:7px;align-items:center;border:0;background:transparent;cursor:pointer;
    border-radius:7px;padding:5px 7px;font:600 12px/1.3 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;color:var(--text2);text-align:left}
  .mentions button:hover,.mentions button.on{background:var(--blue-bg);color:var(--blue-fg)}
  .msg .mn{color:var(--accent);font-weight:700}
  
  /* низкое окно: шапка не съедает экран (дополняет общие правила) */
  @media (max-height:820px){
    .moneybar .kpi{padding:5px 14px 6px}
    .moneybar .kpi .kv{font-size:15px}
    .prog-cap{margin:1px 0 2px}
  }
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     v9 · ДИЗАЙН-СИСТЕМА И ШАПКА (по итогам трёх аудитов).
     Порядок: токены → шапка (сворачивание, якоря, деньги) → таблицы → мелочи.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  
  /* ── 1. ТОКЕНЫ. Ни одного литерального цвета вне этого блока: всё, что рисуется, берёт var().
        Акцент поднят #3b82f6 → #2563eb (было 3.68:1 — кнопка не проходила по контрасту, стало 5.17:1),
        --text3 #6b7280 → #5f6773 (на самом тёмном фоне --surface3 было 4.05:1, стало 4.79:1),
        --border2 больше НИКОГДА не используется как цвет текста (разделитель «·» давал 1.47:1). ── */
  :root{
    --accent:#2563eb; --pri-bg:#2563eb; --pri-bg-h:#1d4ed8;
    --text3:#5f6773; --border2:#b7bec9;
    --violet:#6d28d9; --violet-bg:#ede9fe;
    --pink:#be185d; --teal:#0e7490; --lime:#4d7c0f; --amber:#b45309;
    --indigo:#4338ca; --cyan:#0e7490; --grey-fg:#3c434d;
    /* цвет-метка поставщика: закреплён за поставщиком так же, как буква кода */
    --sup-a:#1d4ed8; --sup-b:#c2410c; --sup-c:#0f766e; --sup-d:#6d28d9; --sup-e:#be185d;
    --sup-f:#0e7490; --sup-g:#4d7c0f; --sup-h:#b45309; --sup-i:#4338ca;
    /* типографическая шкала — в rem, чтобы настройка размера шрифта в браузере работала */
    --fs-1:.6875rem; --fs-2:.8125rem; --fs-3:.9375rem; --fs-4:1.0625rem; --fs-5:1.1875rem;
    --lh-1:1rem; --lh-2:1.25rem; --lh-3:1.5rem;
    /* шкала отступов и радиусов */
    --s-0:2px; --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
    --r-c:6px; --r-b:10px; --r-p:999px;
    --sh-card:0 1px 2px rgba(15,23,42,.06);
    --sh-pop:0 12px 32px rgba(15,23,42,.18);
  }
  /* шрифт больше не прибит к html: 100% = размер, выбранный ЧЕЛОВЕКОМ в браузере */
  
  /* ── 2. ШАПКА ────────────────────────────────────────────────────────────────────────── */
  /* заголовочная строка — РОВНО одна строка на всех вьюпортах: «Действия» не прыгают вниз */
  .title-row{flex-wrap:nowrap;min-height:32px}
  .title-row h1{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto}
  .title-row h1 .h1-dim{color:var(--text3);font-weight:400;padding:0 var(--s-0)}
  .title-row .crumbs{flex-shrink:0;white-space:nowrap}
  .title-row .badge,.title-row .he,.title-row .btn,.title-row .demo{flex-shrink:0}
  .title-row .demo select{max-width:190px}
  /* сворачивание шапки: прячется всё «контекстное», остаётся строка заголовка */
  .hero-sub{display:block}
  /* ОДНА полоса на замену свёрнутому контексту: слева якоря разделов, справа прибитые деньги.
     Две отдельные строки съедали бы 64px — ровно то место, что освободило сворачивание. */
  .hero-min{display:none}
  .hero .anchor-bar{display:none}
  .anchor-bar a.on{color:var(--accent);border-bottom-color:var(--accent)}
  /* прибитая денежная полоса: появляется вместе со сворачиванием, одинаково на обоих экранах */
  .money-mini{display:none;gap:var(--s-3);align-items:center;overflow-x:auto;scrollbar-width:none;
    white-space:nowrap;margin-left:auto;padding-left:var(--s-3);min-width:0}
  .money-mini::-webkit-scrollbar{height:0}
  .money-mini .mm{display:inline-flex;gap:var(--s-1);align-items:baseline;flex-shrink:0;cursor:help}
  .money-mini .mm i{font-style:normal;color:var(--text3)}
  .money-mini .mm b{font-variant-numeric:tabular-nums;color:var(--text)}
  .money-mini .mm b.red{color:var(--red-fg)}
  .money-mini .mm b.grn{color:var(--green-fg)}
  /* строка фактов: имя сделки мелким, красная пилюля «не разнесено» ведёт к красному блоку */
  .factbar .dn{color:var(--text2);font-weight:600;overflow:hidden;text-overflow:ellipsis;max-width:44ch}
  .factbar .sep,.terms .sep{color:var(--text3)}
  .pill-red{border:1px solid var(--red);background:var(--red-bg);color:var(--red-fg);
    border-radius:var(--r-p);padding:var(--s-0) var(--s-2);cursor:pointer;font:inherit;font-weight:700;
    display:inline-flex;align-items:center;gap:var(--s-1);min-height:20px}
  .pill-red:hover{background:var(--red);color:var(--surface)}
  .pill-red b{font-variant-numeric:tabular-nums}
  .redbox.flash{animation:v8flash 1.2s ease-out}
  @keyframes v8flash{0%{box-shadow:0 0 0 4px var(--red-bg)}100%{box-shadow:0 0 0 0 transparent}}
  /* прогресс — два отрезка: сделано и ОСТАТОК красным (по строкам, не по деньгам) */
  .prog{display:flex}
  .prog i{display:block;height:100%;border-radius:0}
  .prog i.done{background:var(--accent);border-radius:var(--r-p) 0 0 var(--r-p)}
  .prog i.left{background:var(--red);border-radius:0 var(--r-p) var(--r-p) 0}
  .prog i.left[style*="width:0"]{display:none}
  
  /* ── 3. ТАБЛИЦЫ ──────────────────────────────────────────────────────────────────────── */
  .tw{position:relative}
  .tw .tscroll{overflow-x:auto;max-height:70vh;overflow-y:auto}
  .tw .tshade{display:none;position:absolute;top:0;right:0;bottom:0;width:28px;pointer-events:none;z-index:4;
    background:linear-gradient(90deg,rgba(15,23,42,0),rgba(15,23,42,.13))}
  .tw.more .tshade{display:block}
  /* ячейка НИКОГДА не вылезает в соседнюю колонку: обрезка в одну строку + полный текст в title */
  table.items td{vertical-align:top;overflow:hidden}
  table.items td .c1{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    overflow-wrap:anywhere;max-width:100%}
  table.items tr.exp td .c1{white-space:normal;overflow:visible;text-overflow:clip}
  table.items td.nm{overflow-wrap:anywhere}
  /* строка отзывается на наведение; кликабельная строка показывает, что она ссылка */
  table.items tbody tr:not(.grp){cursor:pointer}
  table.items tbody tr:not(.grp):hover > td{background:var(--surface2)}
  table.items tbody tr.clk:hover > td{background:var(--blue-bg)}
  table.items tbody tr.clk td.code a.cl,table.items tbody tr.clk td:first-of-type a.cl{color:var(--accent)}
  table.items tbody tr.clk:hover td .cl{text-decoration:underline}
  table.items td a.cl{color:var(--accent);font:inherit}
  /* липкие левые колонки */
  table.items td.stk,table.items th.stk{position:sticky;z-index:3;background:var(--surface)}
  table.items thead th.stk{z-index:6}
  table.items tfoot td.stk{z-index:5;background:var(--surface2)}
  table.items .stk0{left:0}
  table.items .stk1{left:0}
  table.items .stk1.off{left:38px}
  .tw.scrolled table.items .stk1{box-shadow:6px 0 8px -6px rgba(15,23,42,.28)}
  table.items tbody tr:hover > td.stk{background:var(--surface2)}
  table.items tbody tr.clk:hover > td.stk{background:var(--blue-bg)}
  table.items tbody tr.sel > td.stk{background:var(--blue-bg)}
  table.items thead th.stk{background:var(--surface2)}
  table.items th.srt:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  table.items th .sar{color:var(--accent);font-size:var(--fs-1)}
  /* деньги, количества и коды — только табличные цифры */
  table.items td.r,table.items th.r,table.items tfoot td,.crumbs b,.crumbs .cpos,.ur .sum,.ur .q,
  .money-mini .mm b,.kpi .kv{font-variant-numeric:tabular-nums}
  
  /* ── 4. ФОРМЫ И МЕЛОЧИ ───────────────────────────────────────────────────────────────── */
  /* нативный чекбокс заменён своим: одинаковый во всех браузерах, попадание 16px */
  .cbx{display:inline-flex;align-items:center;flex-shrink:0;cursor:pointer;position:relative}
  .cbx input{position:absolute;opacity:0;width:16px;height:16px;margin:0;cursor:pointer}
  .cbx .bx{width:16px;height:16px;border:1px solid var(--border2);border-radius:var(--r-c);
    background:var(--surface);display:inline-block;position:relative}
  .cbx input:checked + .bx{background:var(--accent);border-color:var(--accent)}
  .cbx input:checked + .bx::after{content:'';position:absolute;left:5px;top:1px;width:4px;height:9px;
    border:solid #fff;border-width:0 2px 2px 0;transform:rotate(42deg)}
  .cbx input:focus-visible + .bx{outline:2px solid var(--accent);outline-offset:2px}
  /* пояснение дизайнера больше не абзац в вёрстке, а подсказка у заголовка */
  .hint-i{border:0;background:transparent;color:var(--text3);cursor:help;padding:0 var(--s-1);
    display:inline-flex;align-items:center;min-height:20px}
  .hint-i:hover{color:var(--accent)}
  .ic14{width:14px;height:14px;flex-shrink:0}
  .btn .ic14,.menu .mi .ic14,.ckind .ic14{margin-right:var(--s-0)}
  .menu .mi{display:inline-flex;color:var(--text3)}
  .pchip .pa.none{background:var(--surface3);color:var(--text3)}
  .pchip .pv.none{color:var(--text3);font-style:italic}
  .pchip .pact .ic14,.pchip .pgo .ic14{width:13px;height:13px}
  .ava-s.av-teal{background:var(--teal)}
  .ava-s.av-violet{background:var(--violet)}
  .ava-s.av-pink{background:var(--pink)}
  .pa.av-teal{background:var(--teal)}
  .pa.av-pink{background:var(--pink)}
  /* тип задачи: нейтральный чип + цветная точка (новой заливки палитра не получает) */
  .act-item.task-line .ttype{background:var(--surface2);color:var(--text2)}
  .act-item.task-line .ttype .tdot{width:6px;height:6px;border-radius:var(--r-p);display:inline-block;flex-shrink:0}
  .tdot.t-blue{background:var(--accent)}
  .tdot.t-violet{background:var(--violet)}
  .tdot.t-green{background:var(--green)}
  .tdot.t-pink{background:var(--pink)}
  .act-item.task-line .tteam .ic14{width:12px;height:12px}
  .act-item .ic .ic14{width:12px;height:12px}
  .wz-arr .ic14{width:16px;height:16px}
  /* выпадашка типа задачи: цвет — левой полоской-точкой, а не заливкой всего контрола */
  .tform .ttype-sel{border-left-width:3px;border-left-style:solid}
  .ttype-sel.t-blue{border-left-color:var(--accent)}
  .ttype-sel.t-violet{border-left-color:var(--violet)}
  .ttype-sel.t-green{border-left-color:var(--green)}
  .ttype-sel.t-pink{border-left-color:var(--pink)}
  .ttype-sel.t-amber{border-left-color:var(--orange)}
  .ttype-sel.t-red{border-left-color:var(--red)}
  .ttype-sel.t-cyan{border-left-color:var(--cyan)}
  .tdot.t-amber{background:var(--orange)}
  .tdot.t-red{background:var(--red)}
  .tdot.t-cyan{background:var(--cyan)}
  .late-w{color:var(--red-fg);font-weight:700}
  .badge.amb{background:var(--orange-bg);color:var(--orange-fg)}
  .badge.amb .dot{background:var(--orange)}
  .badge.vio{background:var(--violet-bg);color:var(--violet)}
  .badge.vio .dot{background:var(--violet)}
  .badge.grey{background:var(--surface3);color:var(--grey-fg)}
  .badge.grey .dot{background:var(--text3)}
  .rbac .ic14{color:var(--text3)}
  .redbox .rb-ic{color:var(--red-fg)}
  .selbar .hint.blue{color:var(--blue-fg)}
  .ur.done-note{background:var(--green-bg);color:var(--green-fg);font-weight:600;justify-content:space-between}
  .ur[hidden],.pill-red[hidden]{display:none}
  .redbox.empty-ok{border-color:var(--green)}
  .redbox.empty-ok .rb-t{color:var(--green-fg)}
  .redbox.empty-ok .rb-ic{color:var(--green-fg)}
  .fi .v.muted-val{color:var(--text3);font-weight:400}
  /* «сделал — вижу»: короткое сообщение о совершённом действии.
     ⛔ [TOAST-MOCKUP-SELECTOR-IS-ID] СЕЛЕКТОР — ID СОБСТВЕННОЙ ПЛАШКИ МОКАПА, А НЕ ОБЩИЙ КЛАСС .toast.
     Мокапная плашка живёт по правилу «спрятана, пока не добавили .on» (v8Toast её и ставит, см.
     v8-js.txt: t.id='v8-toast'). У ПРОДУКТА своя механика — sofcon-app.src.js рисует сообщения
     классом .toast внутри #toast-container и класса .on НЕ ставит НИКОГДА (у него анимация
     @keyframes toastIn). Пока здесь стоял голый класс, правило уезжало в @scope(html[data-card-v8])
     — то есть на ВСЕ экраны с новой карточкой — и гасило opacity ЛЮБОГО продуктового сообщения до 0.
     Замерено в живом браузере: продуктовая плашка 286×40 в видимой области, computed opacity = 0.
     Для человека это «система не отвечает»: сервер честно объяснял отказ («Все позиции у одного
     поставщика — делить нечего»), а на экране не появлялось ничего.
     Мокапу класс не нужен: его плашка одна и у неё есть id. Продуктовые сообщения этим правилом
     больше не задеваются ни на одном экране. Сторож: scripts/qa/gate-toast-visible-v8.sh. */
  #v8-toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,12px);z-index:99;
    background:var(--text);color:var(--surface);border-radius:var(--r-b);padding:var(--s-2) var(--s-3);
    box-shadow:var(--sh-pop);opacity:0;pointer-events:none;transition:opacity .15s,transform .15s;max-width:80vw}
  #v8-toast.on{opacity:1;transform:translate(-50%,0)}
  /* тени: ровно две (карточка и поповер), цветного свечения под кнопкой больше нет */
  .cardb,.moneybar,.redbox,details.terms-fold{box-shadow:var(--sh-card)}
  .menu,.tplpop,.mentions,.modal,.colpop{box-shadow:var(--sh-pop)}
  .pchip:hover{box-shadow:none;border-color:var(--accent)}
  .to-new{box-shadow:var(--sh-card)}
  .wz-card{box-shadow:var(--sh-card)}
  .wz-step.active{box-shadow:none;border-color:var(--accent)}
  .wz-step.done{border-color:var(--green);background:var(--green-bg)}
  .kpi .bar{background:var(--surface3)}
  .kpi .bar i{background:var(--accent)}
  .kpi .bar i.sup{background:var(--orange)}
  #sec-money .kpis,.moneybar .kpis{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .empty-state .es-ic .ic14{width:20px;height:20px}
  
  /* ═══ слой: v8-final.txt ═══ */
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     v9 · ПОСЛЕДНИЙ СЛОЙ. Идёт ПОСЛЕ сгенерированных шкал, поэтому здесь и только здесь
     можно уточнить то, что шкала переизложила слишком грубо, и дожать адаптив.
     Правило слоя: никаких «сырых» чисел — только токены из :root.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  
  /* [NO-FONT-SWAP-JUMP] то же объявление шрифта, но display:optional — если Inter не успел к
     первому кадру, страница остаётся на метрически подогнанном Inter-fallback и НЕ дёргается
     позже (swap давал скачок макета на холодном кэше). Файл при этом предзагружается ссылкой
     в <head>, поэтому практически всегда успевает. У манатного фейса display оставлен свапом:
     там 360 байт и ровно один глиф ₼ — потерять его нельзя, а сдвинуть он ничего не может. */
  @font-face{font-family:'InterVariable';src:url('/fonts/InterVariable.woff2') format('woff2');
    font-weight:100 900;font-style:normal;font-display:optional}
  
  /* [TWO-SHADOWS-ONLY] теней ровно две: карточка и поповер. Активный чип фильтра поднимался
     собственной чёрной тенью, композер — верхней «дымкой»; и то и другое отличалось от карточки
     на глаз и ни на что не работало. */
  .fchips .fc.on{box-shadow:var(--sh-card)}
  .compose{box-shadow:none;border-top:1px solid var(--border)}
  
  /* браузерные значения по умолчанию у <button> тоже обязаны лежать в шкале */
  .dock .fchips .fsum{padding-left:var(--s-1)}
  .title-row h1 .h1-dim{font-weight:inherit}
  .compose #send{font-weight:700}
  .sdot{border-radius:var(--r-p)}
  
  /* [NO-LAYOUT-JUMP] content-visibility:auto держит для невидимой карточки ЗАГЛУШКУ в 320px,
     а когда карточка доезжает до экрана — подставляет настоящую высоту. Страница дёргается
     (CLS 0.15-0.60 на замере). Экономия кадра здесь не стоит прыгающего макета: карточек
     на экране единицы, а лента дока и без того короткая. */
  .cardb,#feed .act-item{content-visibility:visible;contain-intrinsic-size:auto}
  
  /* заголовок в ОДНУ строку: демо-переключатель — служебный орган мокапа, подпись ему не нужна
     (смысл в title), иначе на 1440 он съедает место у названия сделки */
  .title-row .demo label{display:none}
  .title-row .demo select{max-width:184px}
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [HEADER-NAME-FIRST] ПУТЬ ОТДЕЛЬНОЙ СТРОКОЙ, ИМЯ ЗАПИСИ — ГЛАВНОЕ.
     Было: «Сделки › Sofcon › Заказ #34001950 › D · часть 4 из 14  Закупка #34001950D ·
     Altecon s.r.o.  ● Logistics» — путь, место в семье, имя и статус в одной линии, все
     одного веса, читается как сплошной поток. Рефы: SLDS Breadcrumbs («шапка записи: крошки
     НАД именем, имя — крупнейший элемент»), Atlassian/Attio record header — путь мелко сверху,
     имя строкой ниже. Теперь: строка пути 11px/серым, строка имени 19px/700.
     Побочная выгода: путь больше не конкурирует за место, поэтому его не приходится прятать
     на 1360-1280 — ссылка наверх видна ВСЕГДА (сторож [PARENT-LINK-ALWAYS-REACHABLE]). */
  .hero > .crumbs{display:flex;align-items:center;gap:var(--s-1);min-width:0;
    font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0 0 var(--s-0)}
  /* [WCAG-1.4.3] БЕЗ opacity: .75 гасила --text3 #6b7280 до #878d96 = 3.34:1 при требуемых
     4.5:1 (axe color-contrast, serious). Приглушённость даём цветом, а не прозрачностью. */
  .hero > .crumbs .c-top{color:var(--text3);opacity:1}
  .hero > .crumbs a.c-up{color:var(--text2);font-weight:600}
  .hero > .crumbs a.c-up:hover{color:var(--accent);text-decoration:underline}
  .hero > .crumbs .cpos{color:var(--text3)}
  
  /* [HEADER-ONE-PRIMARY] органы, уехавшие в меню «Действия», из системы не исчезли: они здесь,
     вне глаз и вне потока. Пункт меню нажимает их программно (см. v8ViewItems). */
  .hdr-stash{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
    white-space:nowrap;pointer-events:none}
  
  /* переключатель в меню: состояние видно галочкой, а не только по памяти */
  .menu .chk-item::before{content:'';display:inline-block;width:14px;margin-right:var(--s-1);
    color:var(--accent);font-weight:700}
  .menu .chk-item.on::before{content:'✓'}
  
  /* прибитая полоса денег: «ещё N чисел» — переход в блок, а не ещё одно число */
  .money-mini .mm-more{border:0;background:transparent;color:var(--accent);cursor:pointer;
    font:inherit;font-size:var(--fs-1);line-height:var(--lh-1);font-weight:600;
    padding:var(--s-0) var(--s-2);border-radius:var(--r-c);white-space:nowrap}
  .money-mini .mm-more:hover{background:var(--blue-bg)}
  
  /* ══ [COLLAPSED-HIDES-CONTENT-TOOLS] у СВЁРНУТОГО блока органы управления СОДЕРЖИМЫМ
     бессмысленны: «Колонки» настраивает таблицу, которой не видно, «+ Добавить»/«+ поле»
     добавляют строку в невидимый список. Оставляем только органы САМОГО блока (перетащить,
     скрыть) — они работают и в свёрнутом виде. Ref: Salesforce «collapsed section shows only
     its header», Atlassian Design «collapsed panel: no content-level actions». ══ */
  .cardb.collapsed .hd .tcols,
  .cardb.collapsed .hd .act,
  .cardb.collapsed .hd [data-addf],
  .cardb.collapsed .hd [data-orient]{display:none!important}
  
  /* заголовок колонки — всегда ОДНА строка (иначе шапка таблицы то в один, то в два ряда);
     полное название колонки живёт в подсказке */
  table.items thead th{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:0}
  table.items thead th .th-rz{overflow:visible}
  
  /* [COUNTER-READS-AS-WORDS] сводка задач написана словами; если строка узкая — она переносится
     на второй ряд, но НИКОГДА не режется на «1/42 · ⚠1» */
  .dock .fchips{flex-wrap:wrap;max-height:none;row-gap:var(--s-0)}
  
  /* денежное число с «из» переносится, а не обрезается многоточием */
  #sec-money .kpi .kv{white-space:normal}
  #sec-money .kpi .kv .of{white-space:nowrap}
  
  /* ── низкое окно (768–820px): шапка обязана уложиться в 18% высоты ── */
  @media (max-height:820px){
    .hero{padding-top:var(--s-0)}
    .pchips{margin:var(--s-0) 0}
    .terms{margin:0 0 var(--s-0)}
    .factbar{margin:0}
    .pchip{padding-top:0;padding-bottom:0}
    .pchip .pa{width:22px;height:22px}
  }
  /* ── узкое окно: чипы в одну прокручиваемую строку, крошки уступают место названию ── */
  @media (max-width:1400px){
    .title-row .crumbs{display:none}
    .pchips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
    .pchip,.chip-add{flex-shrink:0}
  }
  /* [PARENT-LINK-SURVIVES-NARROW] У закупки крошка — ЕДИНСТВЕННЫЙ путь к заказу-голове (полосы
     идентичности больше нет). Прятать её целиком нельзя ни на узком, ни на низком окне: усечение,
     как в SLDS, — скрываем верхние уровни («Сделки › Sofcon»), родитель и текущая часть остаются.
     Слой последний, поэтому побеждает правила выше. */
  @media (max-width:1400px),(max-height:720px){
    .title-row .crumbs.has-parent{display:flex;min-width:0}
    .crumbs.has-parent .c-top{display:none}
    .crumbs.has-parent a.c-up{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  }
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [PAY-TERMS-SAME-AS-LIVE] ОРГАН ВВОДА УСЛОВИЙ ОПЛАТЫ — тот же, что владелец сделал в живой
     системе (pt-side-seg / pt-simple-inp / pt-simple-sum в feature-deal-items). Здесь его
     вёрстка в новом дизайне: пилюли, крупный процент, поле ввода, живая расшифровка.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  #sec-terms .bd{padding:var(--s-3)}
  #sec-terms .pt-simple{display:flex;flex-direction:column;gap:var(--s-2)}
  #sec-terms .pt-simple-top{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap}
  #sec-terms .pt-simple-top .sp{flex:1}
  
  /* пилюли «Аванс / Постоплата»: сегментированный переключатель, активный залит синим */
  .pt-side-seg{display:inline-flex;background:var(--surface2);border-radius:var(--r-p);padding:2px;gap:2px}
  .pt-side-seg-b{border:0;background:transparent;cursor:pointer;font:inherit;font-size:var(--fs-2);
    line-height:var(--lh-2);font-weight:600;color:var(--text2);
    padding:var(--s-1) var(--s-3);border-radius:var(--r-p);white-space:nowrap}
  .pt-side-seg-b:hover{color:var(--text)}
  .pt-side-seg-b.pt-side-seg-on{background:var(--pri-bg);color:#fff;box-shadow:var(--sh-card)}
  .pt-side-seg-b:focus-visible{outline:2px solid var(--blue-bd);outline-offset:1px}
  
  /* крупный процент — то же число, что в поле: глаз ловит результат, не считая */
  .pt-big{font-size:var(--fs-5);line-height:var(--lh-3);font-weight:700;color:var(--accent);
    font-variant-numeric:tabular-nums;min-width:64px}
  
  /* поле ввода: цифрами прямо здесь */
  .pt-num{display:inline-flex;align-items:center;gap:var(--s-2)}
  .pt-num .pt-lb{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);white-space:nowrap}
  .pt-inp-w{display:inline-flex;align-items:center;gap:2px;border:1px solid var(--border2);
    background:var(--surface);border-radius:var(--r-c);padding:0 var(--s-2)}
  .pt-inp-w:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--blue-bg)}
  #pt-inp{width:56px;border:0;outline:0;background:transparent;font:inherit;font-size:var(--fs-3);
    line-height:var(--lh-3);font-weight:700;text-align:right;font-variant-numeric:tabular-nums;padding:var(--s-1) 0}
  .pt-inp-w .pt-pc{color:var(--text3);font-size:var(--fs-2);line-height:var(--lh-2)}
  
  /* ползунок — та же доля, взятая мышью */
  .pt-sld{position:relative;height:8px;border-radius:var(--r-p);background:var(--surface3);cursor:ew-resize}
  .pt-sld:focus-visible{outline:2px solid var(--blue-bd);outline-offset:3px}
  .pt-sld .pt-fill{position:absolute;left:0;top:0;bottom:0;background:var(--pri-bg);border-radius:var(--r-p)}
  .pt-sld .pt-grip{position:absolute;top:50%;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;
    background:var(--surface);border:2px solid var(--pri-bg);box-shadow:var(--sh-card)}
  
  /* ЖИВАЯ РАСШИФРОВКА: меняется на каждое нажатие — ради неё всё и делалось */
  .pt-sum{font-size:var(--fs-3);line-height:var(--lh-3);font-weight:600;color:var(--text)}
  .pt-doc{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);display:flex;
    align-items:center;gap:var(--s-1)}
  .pt-doc b{color:var(--text2);font-weight:600;font-family:var(--mono);font-size:var(--fs-1)}
  
  .pt-ft{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}
  .pt-ft .pt-note{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3)}
  .pt-ft .pt-note{display:none}
  #sec-terms.pt-dirty .pt-ft .pt-note{display:inline}
  
  /* чип-результат в шапке вкладки: «Постоплата 100%» — читается, не открывая блок */
  .pt-chip{font-size:var(--fs-1);line-height:var(--lh-1);font-weight:700;color:var(--blue-fg);
    background:var(--blue-bg);border:1px solid var(--blue-bd);border-radius:var(--r-p);
    padding:0 var(--s-2);white-space:nowrap}
  .pt-chip.dirty{color:var(--orange-fg);background:var(--orange-bg);border-color:var(--orange)}
  
  /* справочные строки под органом ввода */
  #sec-terms .terms-body{margin-top:var(--s-3);border-top:1px solid var(--border);padding-top:var(--s-2)}
  #sec-terms .row2{display:grid;grid-template-columns:minmax(140px,200px) minmax(0,180px) minmax(0,1fr);
    align-items:baseline;gap:var(--s-3);padding:var(--s-1) 0;min-height:24px}
  #sec-terms .row2 .lb{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3)}
  #sec-terms .row2 b{font-size:var(--fs-2);line-height:var(--lh-2);font-weight:600;
    font-variant-numeric:tabular-nums}
  #sec-terms .row2 .nt{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3)}
  #sec-terms .tbl-cap{margin-top:var(--s-2)}
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [EVERY-HUMAN-INPUT-IS-EDITABLE] ЯЧЕЙКА ГОВОРИТ, ЧТО С НЕЙ МОЖНО.
     Правится (td.edc): курсор «текст», карандаш на наведении/фокусе, рамка при наведении.
     Считается (td.calcc): Σ-метка, приглушённый цвет, курсор «нельзя», клик даёт объяснение.
     Разница видна БЕЗ наведения — по Σ-метке, чтобы не пришлось тыкать наугад.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  table.items td.edc{cursor:text}
  table.items td.edc .edv{display:inline-flex;align-items:center;gap:var(--s-1);max-width:100%;
    border:1px solid transparent;border-radius:var(--r-c);padding:0 var(--s-1);margin:0 calc(-1 * var(--s-1));
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  table.items td.edc.r .edv{justify-content:flex-end}
  table.items td.edc .edv .edp{display:none;flex:0 0 auto;color:var(--text3);line-height:0}
  table.items td.edc .edv .edp svg{width:11px;height:11px}
  table.items tr:hover td.edc .edv,table.items td.edc .edv:focus-visible{border-color:var(--border2);background:var(--surface)}
  table.items tr:hover td.edc .edv .edp{display:inline-flex}
  table.items td.edc .edv:focus-visible{outline:2px solid var(--blue-bd);outline-offset:0}
  table.items td.edc .edv:hover{border-color:var(--accent)}
  
  table.items td.calcc{cursor:not-allowed;background:var(--surface2)}
  table.items td.calcc .c1{display:inline-flex;align-items:center;gap:var(--s-1);max-width:100%;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  table.items td.calcc.r .c1{justify-content:flex-end}
  table.items td.calcc .calcs{font-style:normal;color:var(--text3);font-size:var(--fs-1);
    font-weight:700;flex:0 0 auto}
  table.items td.calcc .calcs.lk{line-height:0;display:inline-flex}
  table.items td.calcc .calcs.lk svg{width:11px;height:11px}
  table.items td.calcc:focus-within{outline:2px solid var(--blue-bd);outline-offset:-2px}
  
  /* редактор внутри ячейки: не раздвигает строку */
  table.items td .cell-ed{width:100%;box-sizing:border-box;border:1px solid var(--accent);
    border-radius:var(--r-c);background:var(--surface);font:inherit;font-size:var(--fs-2);
    line-height:var(--lh-2);padding:0 var(--s-1);height:22px;outline:0}
  table.items td .cell-ed.r{text-align:right;font-variant-numeric:tabular-nums}
  
  /* расходы позиции: 4 живых поля deal_items одним окошком */
  .exp-pop{position:fixed;z-index:120;background:var(--surface);border:1px solid var(--border);
    border-radius:var(--r-b);box-shadow:var(--sh-pop);padding:var(--s-3);min-width:248px;
    display:flex;flex-direction:column;gap:var(--s-1)}
  .exp-pop .ep-t{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);
    margin-bottom:var(--s-1)}
  .exp-pop .ep-r{display:flex;align-items:center;justify-content:space-between;gap:var(--s-2)}
  .exp-pop .ep-r span{font-size:var(--fs-2);line-height:var(--lh-2);color:var(--text2)}
  .exp-pop .ep-r input{width:96px;border:1px solid var(--border2);border-radius:var(--r-c);
    background:var(--surface);font:inherit;font-size:var(--fs-2);line-height:var(--lh-2);
    text-align:right;font-variant-numeric:tabular-nums;padding:var(--s-1) var(--s-2)}
  .exp-pop .ep-r input:focus{border-color:var(--accent);outline:0}
  .exp-pop .ep-f{display:flex;justify-content:flex-end;gap:var(--s-2);margin-top:var(--s-2)}
  
  /* ══ [ITEMS-COL-PRIORITY] узкий экран: второстепенные колонки — строкой под своей записью ══════
   * Замер 27.08 на 1280×800: содержимое таблицы 1332px в поле 842px, за краем молча оставались ВСЕ
   * деньги строки (Σ закупки, Маржа строки, Σ продажи), а мёртвая колонка «Ед.» ширину сохраняла.
   * Правило важности живёт в коде (COL_PRI, feature-deal-card-v8-items), здесь — только его вид:
   * скрытая колонка не занимает место, а её подпись и значение печатаются pop-in-строкой (приём
   * SAP Fiori responsive table: «низкоприоритетная колонка схлопывается в строку, а не пропадает»). */
  table.items th.v8-hcol,table.items td.v8-hcol{display:none}
  table.items tr.v8-popin>td{padding:0 var(--s-3) var(--s-2) 14px;border-top:0;
    font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);
    white-space:normal;overflow:visible;vertical-align:top}
  table.items tr.v8-popin>td b{color:var(--text2);font-weight:600}
  table.items tr.v8-popin>td i{color:var(--border2);font-style:normal;padding:0 var(--s-0)}
  table.items tbody tr.v8-popin{cursor:default}
  table.items tbody tr:not(.grp):has(+tr.v8-popin)>td{padding-bottom:var(--s-0)}
  
  /* ═══ слой: v8-scale.txt ═══ */
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     v9 · ШКАЛЫ. Слой СГЕНЕРИРОВАН (v8-gen-scale.py) из sales-css.txt + v8-css.txt и подключён
     последним. Он ничего не изобретает: берёт КАЖДОЕ объявление размера/интерлиньяжа/отступа/
     радиуса и переизлагает его ближайшей ступенью шкалы. Пересобирается вместе с мокапами.
       типографика  11/13/15/17/19px · интерлиньяж 16/20/24px · вес 400/600/700
       отступы      2/4/8/12/16/24px · радиусы 6px контролы, 10px карточки, 999px пилюли
     ══════════════════════════════════════════════════════════════════════════════════════ */
  .hero{padding:4px 16px 0}
  .crumbs{font-size:13px;line-height:20px;gap:4px}
  .title-row{gap:8px}
  .title-row h1{font-size:17px;font-weight:700;line-height:24px}
  .badge{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;gap:4px}
  .btn{font-size:13px;font-weight:600;line-height:20px;padding:4px 12px;gap:4px;border-radius:6px}
  .btn.sm{padding:4px 8px}
  .me{padding:2px 4px;gap:8px}
  .me .ava{font-size:13px;font-weight:700;line-height:20px}
  .me .nm{font-size:13px;font-weight:600;line-height:20px}
  .me .rl{font-size:11px;line-height:16px}
  .meta-row{font-size:13px;line-height:20px}
  .pchips{margin:2px 0 4px;gap:4px}
  .pchip{padding:2px 8px}
  .pchip .pa{font-size:11px;font-weight:700;line-height:16px}
  .pchip .pt{gap:4px}
  .pchip .pl{font-size:11px;line-height:16px}
  .pchip .pv{font-size:13px;font-weight:600;line-height:20px}
  .pchip .pgo{font-size:13px;line-height:20px}
  .pchip .pact{font-size:13px;line-height:20px;padding:2px 2px;border-radius:6px}
  .alert{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;border-radius:6px}
  .kpis{margin:0 -16px}
  .kpi{padding:4px 12px 4px}
  .kpi .kl{font-size:11px;line-height:16px}
  .kpi .kv{font-size:15px;font-weight:700;line-height:20px}
  .kpi .kv .of{font-size:11px;font-weight:400;line-height:16px}
  .anchor-bar{margin:0 -16px}
  .anchor-bar a{font-size:11px;font-weight:700;line-height:16px;padding:8px 8px}
  .anchor-bar .he{font-size:11px;line-height:16px;gap:4px}
  .cardb{border-radius:10px}
  .cardb .hd{padding:8px 12px;gap:8px}
  .cardb .hd h3{font-size:13px;font-weight:700;line-height:20px}
  .cardb .hd .cnt{font-size:11px;font-weight:400;line-height:16px}
  .cardb .hd::after{font-size:11px;line-height:16px}
  .cardb .hd .act{font-size:13px;line-height:20px}
  .cardb .fgrid{gap:0 24px}
  .fi{padding:4px 12px}
  .fi .k{font-size:11px;line-height:16px}
  .fi .k .sig{font-size:11px;line-height:16px}
  .fi .v{font-size:13px;font-weight:600;line-height:20px;padding:2px 8px;border-radius:6px}
  .fi.long{gap:2px}
  .fi.empty .v{font-size:13px;font-weight:400;line-height:20px;padding:2px 8px;border-radius:6px}
  .fi input,.fi select{font-size:13px;font-weight:600;line-height:20px;border-radius:6px}
  .presets .pr{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px}
  table.items{font-size:13px;line-height:20px}
  table.items th{font-size:11px;line-height:16px;padding:4px 8px}
  table.items td{padding:4px 8px}
  .check{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;gap:4px;border-radius:6px}
  .dock .dock-hd{padding:8px 12px 4px;gap:4px}
  .dock .dock-hd b{font-size:11px;font-weight:700;line-height:16px}
  .dock .dock-hd .sub{font-size:11px;line-height:16px}
  .dock .sec-hd{padding:8px 12px 4px;gap:8px}
  .dock .sec-hd h3{font-size:13px;font-weight:700;line-height:20px}
  .dock .sec-hd .cnt{font-size:11px;line-height:16px}
  .tasks-list{padding:0 12px 4px}
  .task{padding:4px 0;gap:8px}
  .task .chk{font-size:11px;line-height:16px;border-radius:6px}
  .task .tx .t{font-size:13px;font-weight:600;line-height:20px}
  .task.done .tx .t{font-weight:400}
  .task .tx .d{font-size:11px;line-height:16px}
  .fchips{margin:4px 12px 2px;gap:2px;border-radius:6px}
  .fchips .fc{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px}
  .act-scroll{padding:2px 12px 8px}
  .act-item{padding:4px 0;gap:8px}
  .act-item .ic{font-size:11px;line-height:16px}
  .act-item .who{font-size:13px;line-height:20px}
  .act-item .who .tm{font-size:11px;line-height:16px}
  .act-item .msg{font-size:13px;line-height:20px}
  .compose{padding:8px 12px 8px}
  .compose .row{gap:4px}
  .compose textarea{font-size:13px;line-height:20px;padding:8px 12px}
  .compose #send{font-size:15px;line-height:20px}
  details.fold summary{font-size:11px;font-weight:700;line-height:16px;padding:4px 12px;gap:4px}
  details.fold summary::before{font-size:11px;line-height:16px}
  .sec-tools button{font-size:11px;line-height:16px;padding:2px 8px}
  #add-sec{font-size:13px;font-weight:600;line-height:20px;padding:8px;border-radius:10px}
  .modal{padding:16px 16px;border-radius:10px}
  .modal h4{font-size:15px;line-height:20px;margin:0 0 8px}
  .modal input[type=text]{font-size:13px;line-height:20px;padding:8px 12px;border-radius:6px}
  .type-grid{gap:4px}
  .type-grid button{font-size:11px;font-weight:700;line-height:16px;padding:8px 4px;border-radius:6px}
  .fi.hit{border-radius:6px}
  .drag-h{font-size:13px;line-height:20px}
  .drop-ph{border-radius:6px}
  .drop-phf{border-radius:6px}
  .fi.dragging{border-radius:6px}
  .admin-hint{font-size:11px;font-weight:700;line-height:16px;padding:4px 8px}
  .cols-ctl{gap:8px}
  .cols-ctl .lbl{font-size:11px;font-weight:700;line-height:16px}
  .cols-seg{border-radius:6px}
  .cols-seg button{font-size:11px;font-weight:700;line-height:16px;padding:0 8px}
  .cols-eff{font-size:11px;font-weight:700;line-height:16px}
  .hf-x{font-size:11px;line-height:16px}
  .colpop{padding:8px 12px;border-radius:10px}
  .colpop b{font-size:11px;line-height:16px}
  .colpop label{font-size:13px;line-height:20px;padding:2px 2px;gap:8px}
  .colpop .mut{font-size:11px;line-height:16px}
  .task .tx .d{gap:4px}
  .task .ava-s{font-size:11px;font-weight:700;line-height:16px}
  .task-res{font-size:11px;line-height:16px}
  .act-item.task-line{padding:8px 8px;margin:2px 0}
  .act-item.task-line.done .who b{font-weight:400}
  .act-item.task-line .chk{font-size:11px;line-height:16px;border-radius:6px}
  .fchips .cnt{font-size:11px;line-height:16px}
  .hfields{margin:0 0 4px;gap:4px}
  .hfields .fi{padding:4px 8px;gap:4px}
  .hfields .fi .k{font-size:11px;line-height:16px}
  .hfields .fi .v{font-size:13px;font-weight:600;line-height:20px}
  .hfields .fi.empty .v{font-size:11px;line-height:16px}
  .hfields .fi input,.hfields .fi select{font-size:13px;line-height:20px}
  .fi textarea{font-size:13px;font-weight:400;line-height:20px;padding:4px 8px;border-radius:6px}
  .title-row h1{line-height:24px}
  .compose textarea{font-size:13px;line-height:20px}
  .msg .due{font-size:11px;line-height:16px}
  .kpi .kv.txt{font-size:15px;line-height:20px}
  .kpi .kv .of{font-size:11px;font-weight:400;line-height:16px}
  .title-row .he{font-size:11px;line-height:16px;gap:4px}
  .kbadge{font-size:11px;font-weight:700;line-height:16px;padding:2px 4px;gap:2px}
  .fi-x{font-size:11px;line-height:16px}
  .sec-tools [data-orient]{font-size:13px;line-height:20px}
  .hero{padding:4px 16px 0}
  .title-row{margin:0 0 2px;gap:8px}
  .crumbs .c-top{gap:4px}
  .factbar{font-size:13px;line-height:20px;margin:2px 0 2px;gap:8px}
  .prog-cap{font-size:11px;line-height:16px;margin:2px 0 2px}
  .terms{font-size:13px;line-height:20px;margin:0 0 4px}
  .terms .tl{font-size:11px;line-height:16px}
  .tset{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;border-radius:6px}
  .terms a.edit{font-size:11px;font-weight:700;line-height:16px}
  #sec-money .kpi{padding:8px 12px 8px}
  #sec-money .kpi .kv{font-size:17px;line-height:24px}
  .moneybar{border-radius:10px}
  .moneybar .kpi{padding:8px 12px 8px}
  .moneybar .kpi .kv{font-size:17px;line-height:24px}
  .money-note{font-size:11px;line-height:16px;padding:0 12px 8px}
  .money-text{font-size:13px;font-weight:600;line-height:20px;padding:12px 12px}
  .redbox{border-radius:10px}
  .redbox .rb-hd{padding:8px 12px 2px}
  .redbox .rb-t{font-size:13px;font-weight:700;line-height:20px}
  .redbox .rb-s{font-size:11px;line-height:16px}
  .redbox .rb-d{font-size:11px;line-height:16px;padding:0 12px 4px}
  .ur{font-size:13px;line-height:20px;padding:4px 12px;gap:8px}
  .selbar{padding:8px 12px}
  .selbar .cnt2{font-size:13px;font-weight:700;line-height:20px}
  .selbar input[type=text]{font-size:13px;line-height:20px;padding:4px 8px;border-radius:6px}
  .splitbar{padding:8px 12px;gap:8px}
  .splitbar .hint{font-size:11px;line-height:16px}
  table.items th.selc,table.items td.selc{padding:4px 4px 4px 12px}
  table.items tr.grp td{font-size:11px;font-weight:700;line-height:16px}
  table.items th .sar{font-size:11px;line-height:16px}
  .tbl-cap{font-size:11px;line-height:16px;padding:8px 12px}
  details.terms-fold{border-radius:10px}
  details.terms-fold > summary{font-size:13px;font-weight:700;line-height:20px;padding:8px 12px;gap:8px}
  details.terms-fold > summary::before{font-size:11px;line-height:16px}
  .terms-body{font-size:13px;line-height:20px;padding:8px 12px}
  .terms-body .row2{padding:2px 0;gap:8px}
  .terms-body .lb{font-size:11px;line-height:16px}
  .rbac{font-size:13px;line-height:20px;padding:8px 12px;gap:8px;border-radius:10px}
  .menu{padding:4px;gap:2px;border-radius:10px}
  .menu button{font-size:13px;font-weight:600;line-height:20px;padding:8px 8px;border-radius:6px}
  .menu .mt{font-size:11px;font-weight:700;line-height:16px;padding:4px 8px 2px}
  .tabs-pool{font-size:11px;line-height:16px;padding:8px 12px;gap:8px;border-radius:10px}
  .tabs-pool button{font-size:11px;font-weight:700;line-height:16px;padding:2px 12px}
  .hd-confirm{font-size:11px;font-weight:700;line-height:16px;gap:4px}
  .hd-confirm button{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;border-radius:6px}
  .pchip-x{font-size:11px;line-height:16px}
  .pchips .drop-phc{border-radius:6px}
  .chip-add{font-size:11px;font-weight:700;line-height:16px;padding:4px 8px}
  .to-new{font-size:11px;font-weight:700;line-height:16px;padding:4px 12px;gap:4px}
  .dock .fchips{margin:4px 8px 2px}
  .dock .fchips .fc{font-size:11px;font-weight:700;line-height:16px;padding:2px 4px}
  .dock .fchips .fc i{font-size:11px;font-weight:700;line-height:16px;border-radius:6px}
  .dock .fchips .fsum{font-size:11px;line-height:16px}
  .dock .fchips.tight{gap:2px}
  .dock .fchips.tight .fc{gap:2px}
  .dock .fchips.tight .fc i{padding:0 2px}
  .cardb.horiz .bd > .fgrid{gap:0 16px}
  .cardb.horiz .bd > .fgrid > .fi{padding:4px 12px 4px}
  .cardb.horiz .fi .k{font-size:11px;line-height:16px}
  .cardb.horiz .fi .v{line-height:20px;padding:2px 4px}
  .cardb.horiz .fi.empty .v{padding:2px 8px}
  .cardb.horiz .fi .inh{font-size:11px;font-weight:700;line-height:16px;border-radius:6px}
  .demo{font-size:11px;line-height:16px;gap:4px}
  .demo select{font-size:11px;font-weight:700;line-height:16px;padding:2px 4px;border-radius:6px}
  .wz{padding:12px 12px}
  .wz-arr{font-size:15px;line-height:20px}
  .wz-step{padding:8px 12px;gap:8px;border-radius:10px}
  .wz-step .wz-n{font-size:15px;font-weight:700;line-height:20px}
  .wz-step .wz-t{font-size:13px;font-weight:700;line-height:20px}
  .wz-step .wz-d{font-size:11px;line-height:16px}
  .wz-step .wz-act{gap:4px}
  .wz-step .wz-lb{font-size:11px;line-height:16px}
  .wz-step select{font-size:13px;line-height:20px;padding:4px 8px;border-radius:6px}
  .wz-step.done .wz-n::after{font-size:13px;line-height:20px}
  .empty-state{padding:24px 16px}
  .empty-state .es-ic{font-size:17px;line-height:24px;border-radius:10px}
  .empty-state .es-t{font-size:13px;font-weight:700;line-height:20px}
  .empty-state .es-d{font-size:13px;line-height:20px}
  .empty-state .es-act{gap:8px}
  .pv-rule{font-size:11px;line-height:16px;padding:8px 12px}
  .pv-foot{padding:8px 12px}
  table.items select.supsel{font-size:13px;line-height:20px;padding:2px 4px;border-radius:6px}
  .tform{padding:8px 8px}
  .tform .tf-grid{gap:4px 8px}
  .tform label{font-size:11px;font-weight:700;line-height:16px}
  .tform select,.tform input{font-size:11px;font-weight:700;line-height:16px;padding:2px 4px;border-radius:6px}
  .tform .tf-quick button{font-size:11px;font-weight:700;line-height:16px}
  .tform .tf-note{font-size:11px;line-height:16px}
  .act-item.task-line .ttype{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px}
  .act-item.task-line .tteam{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px}
  .act-item.task-line .claim{font-size:11px;font-weight:700;line-height:16px;padding:2px 8px;border-radius:6px}
  .act-item.task-line .tdur{font-size:11px;line-height:16px}
  .tres{gap:4px}
  .tres textarea{font-size:13px;line-height:20px;padding:4px 8px;border-radius:6px}
  .tres .rw{gap:4px}
  .tres .err{font-size:11px;font-weight:700;line-height:16px}
  .tplpop{border-radius:10px}
  .tplpop .tp-s input{font-size:13px;line-height:20px;padding:4px 8px;border-radius:6px}
  .tplpop .tp-c{padding:4px 8px;gap:2px}
  .tplpop .tp-c button{font-size:11px;font-weight:700;line-height:16px}
  .tplpop .tp-i{padding:4px 8px;border-radius:6px}
  .tplpop .tp-i b{font-size:13px;font-weight:700;line-height:20px}
  .tplpop .tp-i span{font-size:11px;line-height:16px}
  .tplpop .tp-i i{font-size:11px;font-weight:700;line-height:16px;border-radius:6px}
  .tplpop .tp-e{font-size:13px;line-height:20px;padding:12px}
  .mentions button{font-size:13px;font-weight:600;line-height:20px;padding:4px 8px;gap:8px;border-radius:6px}
  @media (max-width:1345px){
    .dock{border-radius:10px}
  }
  @media (max-height:820px){
    .hero{padding:4px 16px 0}
    .title-row h1{font-size:17px;line-height:24px}
    .kpi{padding:4px 12px 4px}
    .kpi .kv{font-size:15px;line-height:20px}
    .pchips{margin:2px 0 4px}
    .hfields{margin:0 0 4px}
    .moneybar .kpi{padding:4px 12px 4px}
    .moneybar .kpi .kv{font-size:15px;line-height:20px}
    .prog-cap{margin:2px 0 2px}
  }
  @media (max-height:720px){
    .compose{padding:4px 8px 4px}
    .fchips{margin:2px 12px 0}
  }
  @media (max-width:1400px){
    .pchip .pa{font-size:11px;line-height:16px}
    .hero{padding:4px 12px 0}
    .title-row h1{font-size:17px;line-height:24px}
    .kpis{margin:0 -12px}
    .kpi{padding:2px 12px 4px}
    .kpi .kv{font-size:15px;line-height:20px}
    .moneybar .kpi .kv{font-size:15px;line-height:20px}
    .title-row .btn{padding:4px 8px}
    .title-row .he{font-size:11px;line-height:16px}
  }
  /* сокращение font: выше пишет «inherit» вместо семейства — семейство приходит от body */
  
  /* ═══ слой: v8-dock-css.txt ═══ */
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [DOCK-COLLAPSIBLE] · ПРАВАЯ ПАНЕЛЬ «ЗАДАЧИ И ХРОНИКА» СВОРАЧИВАЕТСЯ
     Слой идёт ПОСЛЕДНИМ (после шкал и v8-final), поэтому здесь и только здесь можно
     переопределить ширину/поток дока, не трогая общие sales-css/v8-css.
  
     Как у рефов: SAP Fiori Flexible Column Layout и Oracle Redwood «side panel» —
     боковая панель сворачивается кнопкой в шапке, тело ПЕРЕСЧИТЫВАЕТ раскладку
     (число колонок), а на месте панели остаётся узкий корешок (rail) со счётчиком,
     чтобы человек не забыл, что там задачи.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  :root{
    --dock-w:clamp(320px,26vw,460px);   /* ширина открытой панели (как было в sales-css) */
    --spine-w:44px;                     /* корешок закрытой панели — ровно 44px (цель попадания) */
    --dock-anim:.24s;
  }
  @media (max-width:1345px){ :root{ --dock-w:clamp(300px,26vw,400px) } }
  
  /* .wrap — система координат для оверлея и обрезка уезжающей панели */
  
  /* ── панель: уезжает вправо отрицательным полем (тело растёт, содержимое НЕ сминается) ── */
  .dock{width:var(--dock-w);margin-right:0;
    transition:margin-right var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease}
  
  /* ── КОРЕШОК: 44px, вертикальная подпись, счётчик, красная точка при просрочке ── */
  .dock-spine{display:none;flex:0 0 var(--spine-w);width:var(--spine-w);
    position:relative;z-index:2;box-sizing:border-box;
    background:var(--surface);border:0;border-left:1px solid var(--border);
    cursor:pointer;padding:var(--s-2) 0;color:var(--text3);
    flex-direction:column;align-items:center;gap:var(--s-2);
    font:700 var(--fs-1)/var(--lh-1) 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif}
  .dock-spine:hover{background:var(--surface2);color:var(--accent)}
  .dock-spine:focus-visible{outline:2px solid var(--blue-bd);outline-offset:-2px}
  .dock-spine .ic14{width:16px;height:16px;flex-shrink:0}
  .dock-spine .lbl{writing-mode:vertical-rl;text-orientation:mixed;white-space:nowrap;
    letter-spacing:.6px;text-transform:uppercase;overflow:hidden;text-overflow:ellipsis;min-height:0}
  .dock-spine .n{background:var(--surface3);color:var(--text2);border-radius:var(--r-p);
    padding:0 var(--s-1);font-variant-numeric:tabular-nums;flex-shrink:0}
  .dock-spine.has-late .n{background:var(--red-bg);color:var(--red-fg)}
  .dock-spine .rdot{width:7px;height:7px;border-radius:50%;background:var(--red);flex-shrink:0;display:none}
  .dock-spine.has-late .rdot{display:block}
  
  /* ── КНОПКА В ШАПКЕ: иконка + счётчик открытых, красная точка при просрочке ── */
  .title-row .dock-btn{flex-shrink:0;gap:var(--s-1);padding-left:var(--s-2);padding-right:var(--s-2)}
  .dock-btn .n{font-variant-numeric:tabular-nums;font-weight:700}
  .dock-btn .rdot{width:7px;height:7px;border-radius:50%;background:var(--red);flex-shrink:0;display:none}
  .dock-btn.has-late .rdot{display:inline-block}
  .dock-btn.has-late .n{color:var(--red-fg)}
  .dock-btn[aria-expanded="true"]{background:var(--blue-bg);border-color:var(--blue-bd);color:var(--blue-fg)}
  
  /* ── ОВЕРЛЕЙ на очень узких: панель ложится ПОВЕРХ тела, тело ширину не отдаёт ── */
  @media (max-width:1152px){
    /* корешок виден ВСЕГДА (и при открытой панели) — тело не прыгает на 44px при открытии */
    .dock-spine{display:flex}
    .dock{position:absolute;top:0;right:var(--spine-w);bottom:0;z-index:40;margin-right:0;
      box-shadow:var(--sh-pop);
      transition:transform var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease}
    #dock-scrim{position:absolute;inset:0;z-index:35;background:rgba(15,23,42,.28);border:0;padding:0}
  }
  /* затемнение существует ТОЛЬКО в режиме оверлея */
  #dock-scrim{display:none}
  
  /* ── композер дока на узкой панели: «Шаблоны» ПЕРЕНОСИТСЯ, а не обрезается краем панели
        (на 300px строка кнопок требовала 301px и «Шаблоны» уезжали под границу) ── */
  .compose .row.kinds{flex-wrap:wrap;row-gap:var(--s-1)}
  
  /* ── адаптив: на узком окне кнопка дока остаётся, а место ей отдаёт демо-селектор ── */
  @media (max-width:1152px){
    /* демо-переключатель — служебный орган мокапа: место кнопкам он отдаёт первым */
    .title-row .demo select{max-width:132px}
  }
  .title-row .he{white-space:nowrap}
  /* счётчик пустых полей «(43)» НЕ прячем даже на 1024: место у него отбирает заголовок,
     который и так живёт в подсказке и в крошках — а число скрытых полей нигде больше не написано */
  
  /* ── печать/уменьшенная анимация: без движения ── */
  @media (prefers-reduced-motion:reduce){
    .dock{transition:none}
  }
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [FEED-NEEDS-SEARCH] строка поиска по ленте — ОТДЕЛЬНОЙ строкой под вкладками-счётчиками.
     Вкладки оставлены намеренно: они показывают количества (8 · 2 · 1 · 5), чего выпадающий
     список «Все типы ▾» не умеет. Панель узкая (300px), в одну строку это не влезает без тесноты.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  .dock .fsearch{display:flex;align-items:center;gap:var(--s-1);margin:var(--s-1) 10px var(--s-1);
    border:1px solid var(--border);background:var(--surface2);border-radius:var(--r-c);
    padding:0 var(--s-2);min-height:26px}
  .dock .fsearch:focus-within{border-color:var(--accent);background:var(--surface);
    box-shadow:0 0 0 3px var(--blue-bg)}
  .dock .fsearch .fq-ic{width:13px;height:13px;color:var(--text3);flex:0 0 auto}
  .dock .fsearch input{flex:1;min-width:0;border:0;outline:0;background:transparent;font:inherit;
    font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text);padding:var(--s-1) 0}
  .dock .fsearch input::-webkit-search-cancel-button{display:none}
  .dock .fsearch .fq-n{font-size:var(--fs-1);line-height:var(--lh-1);color:var(--text3);
    white-space:nowrap;flex:0 0 auto;font-variant-numeric:tabular-nums}
  .dock .fsearch .fq-x{border:0;background:transparent;cursor:pointer;color:var(--text3);
    padding:0;line-height:0;flex:0 0 auto}
  .dock .fsearch .fq-x:hover{color:var(--red-fg)}
  .dock .fsearch .fq-x svg{width:12px;height:12px}
  #feed .act-item.q-off{display:none}
  #feed mark.fq-hit{background:#fde68a;color:inherit;border-radius:3px;padding:0 1px}
  .fq-empty{padding:var(--s-4) var(--s-2);text-align:center;color:var(--text3);
    font-size:var(--fs-2);line-height:var(--lh-2)}
  .fq-empty b{display:block;color:var(--text2);font-size:var(--fs-2)}
  .fq-empty .fq-e2{font-size:var(--fs-1);line-height:var(--lh-1);margin-top:var(--s-1)}
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     [OPEN-TASK-STAYS-IN-SIGHT] закреплённая задача липнет к верху ленты.
     sticky ПЕРВЫМ ребёнком прокручиваемой области: карточка занимает настоящее место, поэтому
     первую запись хроники не перекрывает. Фон непрозрачный — иначе сквозь неё едет история.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  #feed-pin{position:sticky;top:0;z-index:6;background:var(--surface);
    margin:0 calc(-1 * var(--s-3)) var(--s-1);padding:0 var(--s-3) var(--s-1);
    border-bottom:1px solid var(--border);box-shadow:0 6px 10px -10px rgba(15,23,42,.45)}
  #feed-pin[hidden]{display:none}
  #feed-pin .pin-lbl{font-size:var(--fs-1);line-height:var(--lh-1);font-weight:700;
    text-transform:uppercase;letter-spacing:.4px;color:var(--text3);padding:var(--s-1) 0 0}
  #feed-pin .pin-lbl.late{color:var(--red-fg)}
  #feed-pin .act-item{border-left:3px solid var(--border2);padding-left:var(--s-2);
    border-radius:0 var(--r-c) var(--r-c) 0}
  #feed-pin .act-item.late{border-left-color:var(--red);background:var(--red-bg)}
  #feed-pin .pin-more{border:0;background:transparent;color:var(--accent);cursor:pointer;font:inherit;
    font-size:var(--fs-1);line-height:var(--lh-1);font-weight:700;padding:var(--s-1) 0;text-align:left}
  #feed-pin .pin-more:hover{text-decoration:underline}
  /* панель свёрнута — липнуть нечему (её вообще не видно); правило держит инвариант явно */
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     ⛔ [FEED-NO-COMPOSE-FAB-IN-DOCK] ПЛАВАЮЩЕЙ КНОПКИ ✎ В ВИДЕ ПО МОКАПУ НЕТ.
     Владелец (20.08): «синяя кнопка перекрывает записи». Так и есть: #deal-compose-fab —
     круг 52px в правом нижнем углу с z-index:60, и на панели ~460px он ложится ровно на
     последнюю запись ленты (замер: «💱 Валюта закупки: … • A⟨кнопка⟩EUR» — кнопка съедала
     «ZN →»).
     Это ДУБЛЬ ОРГАНА, а не украшение: в эталоне (v8-purchase.html) плавающей кнопки нет
     вовсе, ввод один — композер внизу панели (.compose), и он у нас живой: [CARD-V8-DOCK]
     wireDockCompose отдаёт текст живому #dbb-note-ta и window.dbbSubmit, а чип «Задача»
     раскрывает ту же живую форму ПРЯМО В КОМПОЗЕРЕ ([CARD-V8-TASK-IN-COMPOSER] ниже). То есть
     путь создания и примечания, и задачи остаётся на месте — убирается ВТОРАЯ кнопка к тому же
     органу (docs/MOCKUP-TRANSFER-RULES.md п.3 «живые органы вместо копий», п.5 «мёртвого не
     показываем»).
     Почему !important: кнопка приходит из статической разметки с инлайновым display:flex —
     без него правило вида не действует. Область @scope(html[data-card-v8]) держит правку
     ТОЛЬКО в новом виде: старый вид и зеркальные сделки свою кнопку сохраняют.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  #deal-compose-fab{display:none!important}
  
  /* ══════════════════════════════════════════════════════════════════════════════════════
     ⛔ [CARD-V8-TASK-IN-COMPOSER] ФОРМА ЗАДАЧИ — ЧАСТЬ КОМПОЗЕРА, А НЕ ВТОРОЕ ОКНО.
     Владелец (21.08): «нажал на кнопку задача и окно улетело куда-то. и вообще почему оно
     отдельное». Разбор и корень — в шапке wireDockCompose (feature-deal-card-v8.src.js).
     Коротко: всплывающее #deal-compose-panel прибито снизу (bottom:84px) к месту убранной
     круглой кнопки ✎ и лежит в системе координат ленты, которая под этим видом ПРОКРУЧИВАЕТСЯ
     (.act-scroll{overflow-y:auto}) — окно росло вверх и обрезалось краем, а его высоту задавала
     память браузера (sc_dbb_ta_height), а не панель. Замер: 403×835 при доступных 758.
     Живой орган ввода (#deal-bottom-box) теперь ПЕРЕЕЗЖАЕТ внутрь .compose, поэтому:
       · плавающего слоя нет вовсе — обрезать и «улетать» нечему;
       · ширина = ширина панели, высота ограничена самим композером;
       · height:auto!important и max-height бьют ИНЛАЙНОВЫЕ height/max-height:none, которые
         ставит восстановление сохранённого размера (sofcon-app.src.js:_applyDbbHeight) —
         иначе одно давнее перетаскивание ручки навсегда ломало форму на всех сделках;
       · вкладки самой формы («Примечание»/«Задача» внутри #deal-bottom-box) скрыты: их работу
         уже делают чипы композера, две пары одинаковых переключателей рядом — дубль органа.
     Как у рефов: amoCRM — примечание и задача это вкладки ОДНОГО поля ввода в ленте;
     Salesforce — «New Task» это quick action в той же панели. Отдельного окна ввода нет ни у
     одного из них.
     ══════════════════════════════════════════════════════════════════════════════════════ */
  .compose[data-cmode] > .row:not(.kinds){display:none}
  .compose > #deal-bottom-box{
    height:auto!important;max-height:min(52vh,420px);overflow-y:auto;overflow-x:hidden;
    display:flex;flex-direction:column;flex-shrink:1;min-height:0;
    margin:var(--s-1) 0 0;border:0;border-top:1px solid var(--border);border-radius:0;
    background:transparent;box-shadow:none}
  /* поля формы не имеют права быть выше композера: cap перебивает и inline height, и
     inline max-height:none из восстановления сохранённого размера */
  .compose > #deal-bottom-box textarea{max-height:132px!important;min-height:56px;box-sizing:border-box}
  .compose > #deal-bottom-box #dbb-note-area,
  .compose > #deal-bottom-box #dbb-task-area{padding:var(--s-2) 0 0!important}
  /* вкладки живого органа — дубль чипов композера; быстрые действия (файл/шаблоны) остаются.
     !important: обе строки разметки несут инлайновый display:flex/justify-content (карточка
     собрана статическим HTML), без него правило вида не действует — проверено скриншотом. */
  .compose > #deal-bottom-box .dbb-tab-bar > div:first-child{display:none!important}
  .compose > #deal-bottom-box .dbb-tab-bar{justify-content:flex-end!important}
  .compose > #deal-bottom-box #dbb-note-quickactions{padding-right:0!important}
  /* Главное действие формы обязано быть на виду ВСЕГДА. Форма скроллится внутри себя (низкое окно,
     узкая панель — строки переносятся), и «Поставить задачу»/«Добавить» уезжали под нижний край:
     замер на 1100×900 — кнопка y=848 при дне панели 854. Подвал прилипает к низу прокрутки — тот же
     приём, что у диалогов SAP Fiori/Oracle Redwood (footer с главным действием всегда виден). */
  .compose > #deal-bottom-box #dbb-task-area > div:last-child,
  .compose > #deal-bottom-box .dbb-note-ft{position:sticky;bottom:0;z-index:2;
    background:var(--surface);padding-bottom:var(--s-1)}
  /* низкое окно — поле ввода уступает место органам формы (текст всё равно прокручивается) */
  @media (max-height:860px){ .compose > #deal-bottom-box textarea{max-height:96px!important} }
  /* чип-переключатель композера сообщает состояние (aria-pressed) и красится как чипы фильтров */
  .compose .ckind[aria-pressed="true"]{background:var(--blue-bg);border-color:var(--blue-bd);color:var(--blue-fg)}
  
  /* ═══ слой: v8-settle-css.txt ═══ */
  
  /* ─── [SETTLE-TAB] Вкладка «РАСЧЁТЫ»: кто кому сколько должен по цепочке ─────────────────────────
     Подключается ПОСЛЕДНИМ слоем: только свои селекторы, ничего чужого не переопределяет.
     Стиль — тот же, что у остальных вкладок: без обводок вокруг полей, серый фон, числа справа
     табличными цифрами, прочерк вместо нуля там, где не посчитано. */
  
  /* Цепочка сторон одной полосой: клиент → мы → посредник → поставщик */
  #sec-settle .chain{display:flex;gap:0;align-items:stretch;flex-wrap:wrap;padding:10px 12px 2px}
  #sec-settle .chain .node{flex:1 1 150px;min-width:0;padding:7px 10px;border-radius:8px;background:var(--surface2);position:relative}
  #sec-settle .chain .node + .node{margin-left:16px}
  /* стрелка между узлами — направление движения денег, а не украшение */
  #sec-settle .chain .node + .node::before{content:'';position:absolute;left:-13px;top:50%;width:10px;height:1px;background:var(--border)}
  #sec-settle .chain .node + .node::after{content:'';position:absolute;left:-7px;top:50%;transform:translateY(-50%);
    border:4px solid transparent;border-left-color:var(--border)}
  #sec-settle .chain .nm{font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #sec-settle .chain .amt{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;margin-top:2px}
  #sec-settle .chain .sub{font-size:11px;color:var(--text3);font-variant-numeric:tabular-nums;margin-top:1px}
  #sec-settle .chain .node.us{background:var(--surface3);outline:1px solid var(--border)}
  #sec-settle .chain .amt.due{color:var(--orange-fg)}
  #sec-settle .chain .amt.zero{color:var(--text3);font-weight:400}
  
  /* Фильтры — одной строкой, как у дока: сторона · состояние · срок */
  #sec-settle .sfilt{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:6px 12px 8px}
  #sec-settle .sfilt .chip{font-size:11px;padding:3px 9px;border-radius:999px;border:1px solid var(--border);
    background:transparent;color:var(--text2);cursor:pointer;white-space:nowrap}
  #sec-settle .sfilt .chip[aria-pressed="true"]{background:var(--blue-bg);border-color:var(--accent);color:var(--accent)}
  #sec-settle .sfilt .sp{flex:1}
  
  /* Таблица обязательств. Ширины — классами: инлайновые стили нельзя перебить медиа-правилом,
     а на узких экранах колонки обязаны ужиматься. */
  #sec-settle .w-money{width:108px}
  #sec-settle .w-state{width:104px}
  #sec-settle .w-act{width:118px}
  #sec-settle .w-due{width:92px}
  @media (max-width:1560px){
    #sec-settle .w-money{width:96px}
    #sec-settle .w-state{width:auto}
    #sec-settle .w-act{width:104px}
  }
  
  #sec-settle table{width:100%;border-collapse:collapse;font-size:13px}
  #sec-settle thead th{position:sticky;top:0;background:var(--surface);z-index:1;text-align:left;font-weight:500;
    font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:.03em;padding:6px 8px;
    border-bottom:1px solid var(--border);white-space:nowrap}
  #sec-settle tbody td{padding:5px 8px;line-height:1.4;border-bottom:1px solid var(--border);vertical-align:top}
  #sec-settle tbody tr:hover{background:var(--surface2)}
  #sec-settle .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
  #sec-settle .dash{color:var(--text3)}
  #sec-settle .party{white-space:normal}
  #sec-settle .st-note{color:var(--text3);font-size:11px}
  #sec-settle td.nowrap{white-space:nowrap}
  /* класс подписи применяется ТОЛЬКО к span внутри ячейки: на самом td он ломал table-cell */
  #sec-settle td.st-note{display:table-cell}
  /* состояние обязательства читается формой, а не только цветом */
  #sec-settle .st{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:2px 7px;border-radius:999px;white-space:nowrap}
  #sec-settle .st.open{background:var(--surface3);color:var(--text2)}
  #sec-settle .st.part{background:var(--orange-bg);color:var(--orange-fg)}
  #sec-settle .st.paid{background:var(--green-bg);color:var(--green-fg)}
  #sec-settle .st.late{background:var(--red-bg);color:var(--red-fg)}
  #sec-settle .st .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:0 0 auto}
  /* Полосы прогресса тут НЕТ намеренно: рядом с колонкой чисел тонкая линия читается как
     подчёркивание суммы (проверено на скриншоте). Долю оплаты говорит сам статус — числом. */
  #sec-settle tbody tr.sel{background:var(--blue-bg)}
  /* Кнопки строки распирали ячейку: строки с остатком были 71px против 30px у закрытых, и таблица
     выглядела рваной (замер высот ячеек: 30,71). Держим их в одной высоте со строкой. */
  #sec-settle .rowact{opacity:0;transition:opacity .12s;display:flex;gap:4px;align-items:center;height:20px}
  #sec-settle .rowact .btn{padding:1px 7px;font-size:11px;line-height:18px;height:20px}
  #sec-settle tbody tr:hover .rowact,#sec-settle tbody tr:focus-within .rowact{opacity:1}
  #sec-settle .foot{display:flex;gap:8px;align-items:center;padding:8px 12px;border-top:1px solid var(--border);flex-wrap:wrap}
  #sec-settle .foot .sp{flex:1}
  #sec-settle .foot .tot{font-variant-numeric:tabular-nums;font-size:13px;color:var(--text2)}
  #sec-settle .foot .tot b{font-size:13px}
  /* пояснение, когда итог свести нельзя */
  #sec-settle .nosum{font-size:11px;color:var(--orange-fg);padding:0 12px 8px}
  
  /* Диалог разбиения остатка */
  #splitpay .rows{display:flex;flex-direction:column;gap:6px;margin:10px 0}
  #splitpay .r{display:flex;gap:6px;align-items:center}
  #splitpay .r input[type=date]{width:140px}
  #splitpay .r input[type=number]{width:110px;text-align:right;font-variant-numeric:tabular-nums}
  #splitpay .r .rm{color:var(--text3);cursor:pointer;padding:2px 6px;border-radius:4px}
  #splitpay .r .rm:hover{background:var(--surface3);color:var(--red-fg)}
  #splitpay .chk{font-size:13px;font-variant-numeric:tabular-nums;padding:6px 0}
  #splitpay .chk.bad{color:var(--red-fg)}
  #splitpay .chk.good{color:var(--green-fg)}
  #splitpay .why{width:100%;margin-top:4px}
  
  /* Узкие экраны: отдельная колонка «Условие» уезжает подписью под сторону. Данные НЕ теряются —
     иначе это было бы «спрятали, чтобы влезло». Порог 1360 подобран по замеру: на 1280 таблица
     резалась на 87px, на 1024 — на 54px. */
  #sec-settle .terms-inline{display:none}
  /* Замер шириной: колонка «Состояние» брала 239px из-за длинной подписи «просрочен · 20 дн. ·
     оплачено 78%» в одну строку — из-за неё таблица резалась даже на 1440. Разрешаем подписи
     переноситься: смысл сохраняется, ширина падает. Числа и даты по-прежнему не рвутся. */
  @media (max-width:1560px){
    #sec-settle .st{white-space:normal}
    #sec-settle thead th[style*="width:110px"],#sec-settle thead th[style*="width:104px"]{width:auto}
  }
  @media (max-width:1360px){
    #sec-settle .c-terms{display:none}
    #sec-settle .terms-inline{display:inline}
    #sec-settle .party{white-space:normal;min-width:150px}
    #sec-settle .terms-inline{white-space:normal}
    #sec-settle .party .st-note{white-space:normal}
    /* плотнее, но не мельче читаемого: тех же 33px не хватало на 1280 после сворачивания колонки */
    #sec-settle tbody td,#sec-settle thead th{padding:5px 6px}
    #sec-settle .st{padding:2px 5px}
    #sec-settle .st.late{font-size:11px}
    /* действия — иконками с подписью в title: слова «+ платёж / разбить» забирали 130px */
    #sec-settle .rowact .btn{padding:2px 6px;font-size:11px}
  }
  @media (max-width:900px){
    #sec-settle .chain .node{flex:1 1 100%}
    #sec-settle .chain .node + .node{margin-left:0;margin-top:14px}
    #sec-settle .chain .node + .node::before{left:50%;top:-8px;width:1px;height:6px}
    #sec-settle .chain .node + .node::after{left:50%;top:-2px;transform:translateX(-50%);
      border-left-color:transparent;border-top-color:var(--border)}
  }
  
  /* ─── [CARD-V8-HERO] Шапка живой карточки: путь → имя → стороны ────────────────────────────────
     Разметку рисует feature-deal-card-v8.src.js; здесь только вид. Значения — из общих токенов,
     своих цветов не заводим ([DESIGN-V8-TOKENS-USED]). */
  /* Рукописные стили шапки (#v8-hero …) УДАЛЕНЫ 18.08: шапка теперь клон эталона
     (CardV8Tpl hero.purchase/hero.order + pchips), и её стили приезжают слоями самого мокапа
     (.hero/.crumbs/.title-row/.badge/.pchip). Свои правила поверх перебивали эталон и давали
     25 расхождений в сверке вычисленных стилей. */
  /* Старая полоса идентичности и строка «кто работает» при новом виде не нужны: путь и стороны
     переехали в шапку выше, а дубли — это то, на что владелец указал прямо. */
  #v6-head > div:has(> .v6-who){display:none}
  .v6-who{display:none}
  
  /* ─── [CARD-V8-MONEY] Показатели денег в подаче эталона ────────────────────────────────────────
     Данные не трогаем: их считает сервер и рисует карточка. Меняем ТОЛЬКО подачу — в эталоне это
     полоса равнозначных показателей с общей линией, а не три отдельные плитки с рамками.
     Мост по классам живой карточки (.v6-kpi), а не переписывание разметки: чем меньше кода трогаем,
     тем меньше поверхность для поломки. */
  #v6-head .v6-kpis,
  #v6-head [class*="kpi"]:has(> .v6-kpi){
    display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
    margin:0;border:1px solid var(--border);border-radius:var(--r-card);background:var(--surface);overflow:hidden}
  .v6-kpi{padding:8px 14px 10px;border-right:1px solid var(--border);min-width:0;background:var(--surface)}
  .v6-kpi:last-child{border-right:0}
  .v6-kpi-l{font-size:11px;line-height:16px;color:var(--text3);
    text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .v6-kpi-v{font-size:17px;line-height:24px;font-weight:700;letter-spacing:-.01em;
    margin-top:2px;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* «не посчитано» — это состояние, а не сумма: тише числа и без жирности, чтобы не читалось цифрой */
  .v6-kpi-v .v6-mut{font-size:13px;line-height:20px;font-weight:400;color:var(--text3)}
  
  /* ─── [CARD-V8-NO-DOUBLE-HEAD] Старая шапка при новом виде не показывается ─────────────────────
     Владелец, увидев первый перенос: «как она у тебя перенесена, если у тебя вверху старая шапка».
     Он прав: новая шапка добавилась ПОД старой, и имя записи с этапом читались дважды. В эталоне
     заголовок один. Прячем старую строку заголовка и её органы — их содержимое уже переехало:
     имя и этап в новую шапку, «назад» есть в пути (крошки), кнопки вида не нужны вовсе (см. ниже). */
  #v6-head > div:first-child:has(#v6-hist-btn),
  .deal-topbar,
  #_fdPageTitle,
  .page-head:has(#_fdPageTitle){display:none}
  /* Кнопка «Вид: классика» остаётся — это единственный способ вернуться к привычному экрану. */
  #v6-classic-btn{display:inline-flex}
  
  /* Блок денег нового вида: разметка взята из мокапа, поэтому классы те же (.cardb/.hd/.kpis/.kpi).
     Здесь только то, чего в слоях эталона нет: состояние «не посчитано» и скрытие старых плиток. */
  #v8-money .kv-none{font-size:13px;line-height:20px;font-weight:400;color:var(--text3)}
  #v8-money{margin:0 0 10px}
  /* Старые плитки денег при новом виде не нужны — их числа показаны выше в эталонной полосе. */
  .v6-kpis,
  #v6-head > .v6-kpi,
  div:has(> .v6-kpi):not(#v8-money):not(.kpis){display:none}
  
  /* ── Дубли старого вида при включённом новом (замер агента 18.08: имя записи дважды, top 13 и 129;
     на экране заказа два заголовка, top 32 и 79). Видов должно быть два — классика и мокап, а не их
     смесь. Скрываем ТОЛЬКО дубли: то, что новый вид уже показывает сам. ── */
  /* Имя записи в старой шапке приложения: в новом виде оно в #v8-hero h1. Кнопки «Назад»/переименовать
     остаются — им новый вид замены пока не дал. */
  #page-deal #deal-num{display:none}
  /* Заголовок экрана заказа от старого вида: новый рисует #v8-order-hero со своим h1. Скрываем только
     когда новый герой реально на странице — иначе экран остался бы вовсе без заголовка. */
  :scope:has(#v8-order-hero) #_fdPageTitle{display:none}
  /* Полоса «закупка · один поставщик · Поставщик: …»: всё это в новом виде показано чипами шапки. */
  #page-deal #v6-child-strip{display:none}
  /* Деньги заказа: при новом виде рукописную полосу заменяет эталонный блок #sec-money-order
     (feature-deal-card-v8), данные — тот же ответ сервера. Прячем только при активном виде. */
  /* !important законен ровно здесь: у рукописной полосы display задан ИНЛАЙНОМ в строке разметки
     (style="display:flex…"), и никакая специфичность его не перебьёт. Полоса — часть старого вида,
     который уходит целиком (видов останется два: классика и мокап). */
  #page-order ._ordMoneyRow{display:none !important}
  #sec-money-order{margin:0 0 10px}
  
  /* ═══ [CARD-V8-SECTIONS] Секции полей строятся КОДОМ МОКАПА (feature-deal-card-v8.src.js):
     оболочка секции и каждое поле — клоны вырезанного шаблона (card-v8-templates.js: section),
     живым внутрь вставляется ТОЛЬКО орган редактирования ядра (.cf-val — его обработчики, права,
     реалтайм). Первая попытка стилизовать разметку ядра «по мотивам» эталона отвергнута владельцем:
     «ты по картинке опять переносишь?» — стилей секции здесь поэтому НЕТ, они приезжают слоями
     самого мокапа. Осталось лишь два служебных правила показа. */
  /* Исходные секции ядра при виде мокапа скрыты — их содержимое живёт в эталонных клонах. */
  #page-deal #deal-sections > .cf-sec{display:none}
  /* ⛔ [CARD-V8-NO-HOLLOW-TWIN] ПРАВИЛО ПОКАЗА ПРИБИВАЕТСЯ К ПРИЗНАКУ УЗЛА, А НЕ К ЕГО МЕСТУ.
     Строка выше адресует ПРЯМОГО РЕБЁНКА #deal-sections. Любой модуль, который ПЕРЕСТАВИТ секции
     ядра в свою обёртку, тем самым выключает её — и опустевшие секции (органы .cf-val уже уехали в
     эталонные клоны) выходят на экран ПУСТЫШКОЙ: подписи есть, значений нет.
     Ровно это и случилось с бенто-видом (feature-deal-bento: host.textContent='' → .cf-sec
     переезжают в #deal-bento/#dbn-extra). Замер на живой карточке 27.08, окно 1680×1000:
     ПЕРВЫМИ на странице шли 5 бенто-блоков, y=129…1614 (≈1450px, полтора экрана), 56 подписей и
     РОВНО 0 узлов .cf-val; настоящие вкладки полей начинались только с y=2980. Владелец правил
     ИМЕННО этот двойник и говорил «поля не изменяются» — он менял пустую копию.
     Признак «секция ядра, чьё содержимое забрал вид» = наличие живых строк поля .cf-row[data-fid]:
     ровно по нему модуль вида и отбирает доноров (feature-deal-card-v8: coreSecs). Место в дереве
     в правиле НЕ участвует — следующий переставщик дефект не воскресит.
     ⛔ НЕ ЗАДЕВАЕТ соседей: у блока «💱 Финансы» (#fx-card-sec) и «Заказ целиком» (#order-sum-sec)
     строки .cf-row идут БЕЗ data-fid (они не поля раскладки) — они и остаются видимыми, как жили
     внутри своих эталонных оболочек. */
  #page-deal .cf-sec:has(.cf-row[data-fid]){display:none}
  /* Орган переключения бенто-вида при виде мокапа не показываем: вид карточки здесь один
     ([CARD-ONE-VIEW-OWNS-SECTIONS] в feature-deal-bento), и кнопка, которая ничего не переключает,
     хуже отсутствующей. Тот же приём уже применён каркасом v6 (#page-deal.v6-on #dbn-toolbar). */
  #dbn-toolbar{display:none}
  /* Живой орган редактирования внутри эталонного поля наследует его типографику. */
  .fi .v .cf-inp{font:inherit;border:0;background:transparent;padding:0;width:100%}
  /* [CARD-V8-RELATED] Живая таблица семьи внутри эталонной оболочки: её собственный заголовок и
     кнопка колонок скрыты — эталонная шапка блока уже несёт и название, и кнопку. */
  #v8-related .v6-rel-tools .v6-rel-title{display:none}
  #v8-related .v6-rel-tools #v6-rel-cols{visibility:hidden;position:absolute}
  #v8-related .v6-rel-tools{min-height:0;margin:0}
  #v8-related{margin-top:10px}
  /* [CARD-V8-FX] Блок «💱 Финансы» (курс и его ФИКСАЦИЯ) внутри эталонной оболочки #v8-fx.
     Тот же приём, что у #v8-related выше: живой узел ядра #fx-card-sec ПЕРЕЕЗЖАЕТ в оболочку целиком,
     копии органа нет — иначе на карточке было бы две кнопки «Зафиксировать», и обе живые.
     Здесь снимаем только ЕГО собственную рамку и ЕГО заголовок: эталонная шапка блока уже несёт и
     значок, и название, и валюту показа — иначе вышла бы карточка внутри карточки с подписью дважды.
     ЗАЧЕМ ВООБЩЕ: правило каркаса v6 гасило #fx-card-sec на ОБЕИХ поверхностях сразу (класс
     [V6-HIDES-ONLY-ITS-OWN-VIEW]), и до фиксации курса ([FX-LOCK-UI-ENTRY]) на новой карточке было
     не добраться — движок есть, человеку не дотянуться.
     Селекторы бьют ТОЛЬКО внутри #v8-fx: в классике блок выглядит как раньше, байт в байт. */
  #v8-fx{margin-top:10px}
  #v8-fx #fx-card-sec{display:block;border:0;background:none;box-shadow:none;margin:0;padding:0}
  #v8-fx #fx-card-sec > .cf-sec-hd{display:none}
  #v8-fx #fx-card-sec > .cf-sec-body{display:block;padding:0}
  /* [CARD-V8-REL-TBL] Таблица «Связанных» теперь рисуется ДВИЖКОМ ЭТАЛОНА в #rel-box
     (feature-deal-card-v8-related.src.js: модель rel.engine + items.engine, живые данные семьи).
     Орган #v6-related ОСТАЁТСЯ в оболочке скрытым — НЕ удалять: по нему живёт счётчик блока,
     и при откате вида он возвращается домой (data-v8-home). Скрыт только внутри #v8-related —
     в классике селектор не совпадает и v6-таблица работает как раньше. */
  #v8-related #v6-related{display:none}
  
  /* ── Щиты каскада для клонов эталона. Значения — КОПИИ слоёв мокапа (файл:строка указана),
     повышена только специфичность: глобальные правила приложения (a{color}, свои line-height)
     перебивали эталон внутри области вида. Ничего «по мотивам» здесь нет. ── */
  /* sales-css.txt:64 .pchip{color:inherit}; body мокапа 13px/20px */
  #v8-pchips a.pchip, #v8-pchips .pchip{color:inherit;line-height:20px}
  /* v8-scale.txt:16 .badge{font-weight:700}; перенос обычный, как в эталоне */
  .hero .title-row .badge{font-weight:700;white-space:normal}
  /* sales-css.txt: .crumbs 11px/16px */
  .hero .crumbs .cpos{line-height:16px}
  /* Значение эталона v8-final:55 (a.c-up{color:var(--text2)}). Замером winner-а установлено: его
     перебивает глобальное правило приложения a:not(.btn):not([role=button])… (специфичность 0,4,1) —
     id поднимает щит выше без изменения значения. */
  #v8-hero > .crumbs a.c-up{color:var(--text2)}
  /* Значение эталона v8-scale:16 (.badge{font-weight:700}). Перебивает app-overrides.css:1113
     (font-weight:var(--fw-semibold) !important) — ответить можно только тем же приоритетом. */
  .hero .title-row .badge{font-weight:700 !important}
  
  /* ═══ [CARD-V8-DOCK] Каркас двух колонок — как .wrap мокапа (sales-css:103: flex, док справа
     шириной var(--dock-w)). У продукта колонки уже есть (#deal-body > .deal-left + #deal-right),
     меняется только раскладка при виде мокапа; правила самого дока (.dock/.dock-hd/.fsearch/
     .act-scroll) приезжают слоями эталона. ── */
  #page-deal #deal-body{display:flex;gap:12px;align-items:stretch}
  #page-deal .deal-left{flex:1;min-width:0}
  /* ⛔ [CARD-V8-FRAME-OWNED-BY-VIEW] ШИРИНУ ЛЕВОЙ КОЛОНКИ ЗАДАЁТ ВИД, И БОЛЬШЕ НИКТО.
     ─────────────────────────────────────────────────────────────────────────────────────────
     ДЕФЕКТ. Примерно в ПОЛОВИНЕ открытий карточки панель задач вставала ЗА ПРАВЫМ КРАЕМ окна
     (замер scratchpad/dock-race-probe.mjs: #v8-dock left 1692…2129 при окне 1680; на 1440 —
     1452…1826), и человек её просто не видел. Тянешь край окна — уезжала ВСЕГДА, при любом
     размере, хотя открытие в этом же размере давало правильную раскладку.
     КОРЕНЬ — ВТОРОЙ ХОЗЯИН РАСКЛАДКИ. Классическая карточка делит #deal-body ползунком
     (#deal-resizer) и «подгоняет» левую колонку В ПИКСЕЛЯХ: _fitDealLeft (sofcon-app.src.js,
     [DEAL-LEFT-FIT]) пишет ИНЛАЙНОМ «width:(окно−450)px; flex:0 0 auto», чтобы старой правой
     колонке осталось ≥380px. Он зовётся на DOMContentLoaded, на своём же старте и на КАЖДОМ
     resize (через 120 мс). Под видом v8 правой колонки нет вовсе (#deal-right{display:none}),
     ленту держит панель со своей шириной var(--dock-w) — подгонять нечего, но подгонщик об
     этом не знает.
     ПОЧЕМУ ИСХОД РАЗНЫЙ. Пишет он только когда левая колонка ШИРЕ его расчётного предела.
     Успел до сборки панели — колонка ещё во всю ширину (1624 при окне 1680) → пишет инлайн;
     успел после — колонка уже 1175 < 1230 → не пишет ничего. Отсюда и «через раз».
     ПОЧЕМУ ИНЛАЙН УБИВАЛ РАСКЛАДКУ ЦЕЛИКОМ. Инлайновая «width» проигрывала чужому
     «width:100% !important» (#page-deal.v6-on .deal-left, .deal-body.deal-items-focus .deal-left),
     а вот «flex:0 0 auto» проходил — колонка переставала сжиматься и брала ВСЕ 100%, выдавливая
     панель наружу целиком. Замер это и показал: inline «width:1230px; flex:0 0 auto» → колонка
     1624px, панель 1692…2129.
     ЛЕЧЕНИЕ — НЕ ЖДАТЬ И НЕ ПЕРЕСЧИТЫВАТЬ, А ЛИШИТЬ ЧУЖОГО ПИСАРЯ ПРАВА ГОЛОСА. Каркас вида
     объявляется важным: важное правило таблицы стилей сильнее ЛЮБОГО инлайна (каскад CSS), и
     исход перестаёт зависеть от того, кто успел раньше. Заодно вид перестаёт зависеть от
     чужого «width:100% !important» слоя v6 — до этой правки без него левая колонка упиралась в
     «.deal-left{max-width:60%}» и рядом с панелью зияла пустота.
     ПЕРЕСЧЁТА ПРИ ИЗМЕНЕНИИ ОКНА НЕ ТРЕБУЕТСЯ ВОВСЕ: колонка — резиновая (flex:1 1 0%), панель —
     var(--dock-w)=clamp(320px,26vw,460px). Обе величины пересчитывает сам браузер на каждом
     кадре, БЕЗ единой записи в DOM — важно для [CARD-V8-NO-JITTER] (замер покоя обязан остаться
     нулевым, а ResizeObserver с записью стилей его бы поднял).
     Специфичность (2 id + класс) выбрана так, чтобы перебить оба чужих важных правила:
     «#page-deal.v6-on .deal-left» (1 id + 2 класса) и «.deal-body.deal-items-focus .deal-left»
     (3 класса). Значения — те же, что строкой выше, добавлен только приоритет.
     На ≤1152 (зона оверлея, media-блок [CARD-V8-DOCK-OVERLAY] ниже) панель уходит из потока
     (position:absolute), и левая колонка при flex:1 занимает всю ширину — ровно то же, чего
     добивалось стековое правило приложения на ≤1080. Поведение узкого окна не меняется. */
  #page-deal #deal-body > .deal-left{
    flex:1 1 0% !important;width:auto !important;min-width:0 !important;max-width:none !important}
  #v8-dock{width:var(--dock-w);flex:0 0 var(--dock-w);align-self:stretch;
    position:sticky;top:0;max-height:100vh;display:flex;flex-direction:column}
  /* пустой дом органа и старая кнопка «История» при виде мокапа не нужны: лента всегда на экране */
  #page-deal #deal-right{display:none}
  #v6-hist-btn{display:none}
  /* Ползунок ширины колонок (#deal-resizer) делил ЛЕВУЮ и ПРАВУЮ колонки классической карточки.
     Правой колонки под видом нет (строка выше), ширина левой задаётся видом ([CARD-V8-FRAME-OWNED-BY-VIEW]) —
     тянуть его теперь не за чем и незачем: он бы только писал в память ключ sc_deal_left_w.
     Правило переноса §5 «мёртвого не показываем»: орган без живого исполнителя не показывается.
     (Слой v6 прячет его тем же способом — feature-deal-card-v6.src.js:861 «#page-deal.v6-on
     #deal-resizer{display:none}»; вид v8 включается и БЕЗ v6, поэтому щит нужен свой.) */
  #page-deal #deal-resizer{display:none}
  /* живой орган внутри дока: тянется на всю высоту, его лента скроллится сама */
  #v8-dock .act-scroll{flex:1;min-height:0;overflow-y:auto}
  #v8-dock #deal-right-main{display:flex;flex-direction:column;min-height:0}
  
  /* ═══ [CARD-V8-ORDER-BLOCKS] Экран заказа: рукописные блоки заменены клонами эталона v8-order.html
     (feature-order-v8.src.js; шаблоны factbar.order / prog.order / terms.order / unalloc.order /
     parts.order из card-v8-templates.js). Рукописные узлы НЕ удаляются: их органы (галочки позиций,
     ввод поставщика, кнопки движков) остаются живыми — клоны делегируют им события. Прячем только при
     активном виде. !important законен: display у рукописных строк задан ИНЛАЙНОМ в строке разметки. */
  /* строка состояния «N закупок · M поставщиков · не разнесено…» → #factbar (факт-строка эталона) */
  #page-order ._ordStateRow{display:none !important}
  /* полоса «Разнесено N%» → #prog (полоса прогресса эталона) */
  #page-order ._ordProgRow{display:none !important}
  /* строка условий Инкотермс/Поставка/Оплата → .st-note (строка условий эталона в hero-sub) */
  #page-order ._ordTermsRow{display:none !important}
  /* красный блок «Не разнесено» → #sec-unalloc (redbox эталона); его живой орган #_fdQtyBox
     (форма «отделить часть количества») перемещён внутрь клона и остаётся видимым */
  #page-order ._ordRemBox{display:none !important}
  /* рукописная шапка «Части заказа» → шапка карточки #sec-parts; сами строки частей НЕ прячутся —
     они перемещаются в тело #parts-box клона как живые органы */
  #page-order ._ordPartsHead{display:none !important}
  /* клоны — прямые дети #page-order (как #sec-money-order): те же поля страницы */
  #page-order #sec-unalloc,
  #page-order #sec-parts{margin:0 0 10px}
  /* факт-строка/прогресс/условия живут в шапке заказа (#v8-order-hero) — как hero-sub мокапа */
  #v8-order-hero .hero-sub{margin-top:4px}
  /* Внутри дока живой поиск скрыт: эталонное поле .fsearch уже делегирует setFeedSearch — два
     одинаковых поля читались бы как разные поиски. Живой фильтр «Все типы» остаётся. */
  #v8-dock .feed-search{display:none}
  
  /* ═══ [CARD-V8-ITEMS] Таблица товаров — клон эталонного #sec-items (feature-deal-card-v8-items).
     Стили таблицы (table.items, .tw/.tscroll/.tshade, липкие .stk, edc/calcc) приезжают слоями
     самого мокапа. Здесь только отступ блока на живых страницах: значение то же, что у соседних
     эталонных клонов (#sec-money-order{margin:0 0 10px} — этот же файл, блок [CARD-V8-MONEY]) —
     поднята только адресация на два наших контейнера. */
  #v6-head #sec-items,
  #page-order #sec-items{margin:0 0 10px}
  /* #page-order у приложения — flex-колонка с overflow:auto. Без запрета сжатия она УЖИМАЕТ
     карточки до доли высоты (замерено пробой: #sec-money-order 33px при теле 46px — виден один
     заголовок; #sec-unalloc 107px при строках на 193px — список резался на первой строке).
     Карточка блока — не резиновая: её высота — её содержимое. */
  #page-order > .cardb,
  #page-order > .redbox,
  #page-order > .hero{flex:0 0 auto}
  /* Полоса денег ЗАКАЗА живёт под id #sec-money-order (эталонный #sec-money на этом экране занят
     правилами мокапа для карточки). Отрицательные поля общей .kpis (v8-scale:33) внутри карточки
     не нужны — первое число резалось слева (замечено скрином после починки сжатия). Значения —
     КОПИЯ эталонных правил #sec-money (v8-css.txt:39-41, 559), поменян только id. */
  #sec-money-order .kpis{margin:0;border-top:0;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  #sec-money-order .kpi{padding:7px 14px 8px}
  #sec-money-order .kpi .kv{font-size:17px}
  /* Значения эталона v8-scale:43-44 (.hd h3 13/20, .cnt 11/16) — глобальные правила приложения
     давали 19px; поднята только специфичность. */
  .cardb .hd h3{font-size:13px;line-height:20px}
  .cardb .hd .cnt{font-size:11px;line-height:16px}
  
  /* ═══ [SETTLE-TAB]+[CARD-V8-TERMS-CARD] Отступы клонов #sec-settle (экран заказа) и #sec-terms
     (карточка закупки) на живых страницах. Значения — КОПИИ соседних правил ЭТОГО файла:
     «#page-order #sec-unalloc, #page-order #sec-parts{margin:0 0 10px}» (блок [CARD-V8-ORDER-BLOCKS]
     выше) и «#v8-related{margin-top:10px}» (блок [CARD-V8-RELATED] выше) — поменяна только адресация
     на новые блоки. Сами стили #sec-settle/#sec-terms приезжают слоями эталона (этот файл сверху и
     v8-final.txt), здесь ничего «по мотивам» нет. */
  #page-order #sec-settle{margin:0 0 10px}
  #page-deal #sec-terms{margin-top:10px}
  /* Значения эталона v8-dock-css:96 (.dock .fsearch input — «голое» поле: без рамки, прозрачный
     фон, наследный шрифт). Глобальный стиль полей приложения навешивал рамку/радиус/белый фон —
     поднята только специфичность, значения не изменены. */
  #v8-dock .fsearch input{border:0;outline:0;background:transparent;font:inherit;
    border-radius:0;padding:0;box-shadow:none;height:auto}
  /* Базовая межстрочная эталона: body мокапа 13px/20px (sales-css body). Приложение даёт 19px —
     контейнеры вида возвращают наследование эталона; значения не меняются, только точка входа. */
  .cardb, .hero, .dock{line-height:20px}
  /* Поле поиска дока: точные значения эталона v8-dock-css:96-97 (fs-1/lh-1, padding s-1 0). */
  #v8-dock .fsearch input{font-size:var(--fs-1);line-height:var(--lh-1);padding:var(--s-1) 0}
  /* Кнопки области вида: значения эталона v8-scale:17 (.btn 13/20, padding 4px 12px) и v8-scale:269
     (.title-row .btn padding 4px 8px). Приложение задаёт свои паддинги/центровку с !important
     (app-overrides .btn) — отвечаем тем же приоритетом, значения эталонные. */
  .cardb .btn, .hero .btn{
    padding:4px 12px !important;white-space:normal;justify-content:normal;line-height:20px}
  /* точечно, как в эталоне: узкая — только кнопка дока (v8-dock-css:46 padding-left/right s-2=8px)
     и малые кнопки .btn.sm (v8-scale:18 4px 8px); «Действия» (.btn.pri) остаётся 4px 12px. */
  .hero .title-row .dock-btn{padding-left:var(--s-2) !important;padding-right:var(--s-2) !important}
  .cardb .btn.sm{padding:4px 8px !important}
  /* Живая таблица семьи внутри эталонной оболочки: размер текста эталона (v8-scale table.items
     13px/20px — связанные в мокапе тем же кеглем). Орган живой, кегль — эталона. */
  #v8-related table{font-size:13px;line-height:20px}
  /* Полоса денег ЗАКАЗА: поздние правила самого v8-order.html (позиции 78132/78170/90760 —
     #sec-money .kpi{padding:8px 12px 8px}, .kv{17px/24px, white-space:normal}) — в общих слоях их
     нет, они живут только в эталоне заказа. Живой блок зовётся #sec-money-order. */
  #sec-money-order .kpi{padding:8px 12px 8px}
  #sec-money-order .kpi .kv{font-size:17px;line-height:24px;white-space:normal}
  /* Скрытие дока кнопкой — АНИМАЦИЯ ЭТАЛОНА (v8-dock-css:23-24: уезд margin-right за край с
     гашением opacity, --dock-anim .24s cubic-bezier(.4,0,.2,1)). Прежний display:none прятал
     мгновенно — владелец: «история выезжает с другой анимацией». Класс живёт на #deal-body
     (body-селекторы каркаса сборщик режет). Контейнеру — обрезка, чтобы уезжающий док не давал
     горизонтальной прокрутки. */
  #deal-body{overflow-x:clip}
  /* ⛔ [CARD-V8-DOCK-CLOSED-IS-HIDDEN] ЗАКРЫТАЯ ПАНЕЛЬ ЗАКРЫТА ПО-НАСТОЯЩЕМУ, А НЕ ПРИПАРКОВАНА ЗА ЭКРАНОМ.
     ДЕФЕКТ (4 строки долга адаптива «Ж НЕ ПЕРЕЛОЖИЛОСЬ ПРИ ИЗМЕНЕНИИ ОКНА», закупка и заказ @1152):
     человек сужает окно с 1680 до 1152 — панель задач и лента оказываются в 1152…1452, то есть ЗА
     правым краем окна; при ОТКРЫТИИ в окне той же ширины они на месте (808…1108).
     ДИАГНОЗ БАЗЫ («раскладка считается один раз на открытии») ЗАМЕРОМ НЕ ПОДТВЕРДИЛСЯ: при сужении
     раскладка пересчитывается сама — панель переходит в оверлей (position:absolute, ширина 300,
     корешок 1108…1152, тело ширину не отдаёт). Уезжает она по другой причине: на первом пересечении
     порога ≤1152 панель ЗАКРЫВАЕТСЯ ([CARD-V8-DOCK-RESIZE-ON-CROSSING], чтобы не накрыть работу
     затемнением), а закрытое состояние выражено ТОЛЬКО уездом + прозрачностью — transform
     translateX(100% + корешок), opacity:0 (замер: transform matrix(1,0,0,1,344,0), opacity 0).
     КОРЕНЬ, ОН ЖЕ КЛАСС: ПРОЗРАЧНЫЙ УЗЕЛ — ЖИВОЙ УЗЕЛ. Человек его не видит, но он занимает место за
     краем окна, ловит Tab, читается экранным диктором и меряется как блок страницы. Закрытие при
     пересечении границы ставит класс dock-off напрямую, минуя setOpen, — значит панели не достаётся
     даже inert/aria-hidden, и «скрытая» лента остаётся в дереве доступности.
     ЛЕЧЕНИЕ — КАСКАДОМ, БЕЗ НАБЛЮДАТЕЛЯ (пересчёт ширин из JS писал бы в DOM на каждом кадре и поднял
     бы дрожание, [CARD-V8-NO-JITTER]): закрытая панель получает visibility:hidden. Это способ рефов
     для выездных панелей: Bootstrap .offcanvas держит закрытую панель visibility:hidden и возвращает
     видимость только показом, Material navigation drawer тем же способом убирает закрытую панель из
     дерева доступности. Анимация уезда сохранена: скрытие ОТЛОЖЕНО на длительность уезда
     (visibility 0s linear var(--dock-anim)), а открытие снимает его мгновенно (базовое правило,
     visibility 0s без задержки) — иначе панель выезжала бы невидимой.
     Правило закрытого состояния идёт ПОСЛЕ базового и специфичнее его (2 id + класс). */
  #v8-dock{visibility:visible;
    transition:margin-right var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s}
  #deal-body.dock-off #v8-dock{margin-right:calc(-1 * var(--dock-w));opacity:0;pointer-events:none;
    visibility:hidden;
    transition:margin-right var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s linear var(--dock-anim)}
  
  /* ═══ [CARD-V8-ORDER-FIELDS] Секции полей заказа, RBAC-плашка и полка .grid3 — клоны эталона
     v8-order.html (feature-order-v8.src.js; шаблоны section / rbac.order / grid3.order). Рукописная
     сетка «ПОЛЯ ЗАКАЗА» (_ordHeadFieldsHtml) НЕ удаляется: её данные (_fdLastHead) питают живой
     редактор поля — прячем только показ при активном виде, по образцу ._ordMoneyRow выше.
     (!important не нужен: display у рукописной сетки не задан инлайном.) */
  #page-order ._ordHeadFields{display:none}
  /* Плашка и полка — прямые дети #page-order (как #sec-money-order): тот же запрет сжатия
     flex-колонкой и тот же отступ, что у соседних клонов (значения — копии правил
     [CARD-V8-ORDER-BLOCKS]/[CARD-V8-ITEMS] этого файла, поменяна только адресация). */
  #page-order > .rbac,
  #page-order > #v8-order-secs{flex:0 0 auto}
  #page-order #sec-rbac,
  #page-order #v8-order-secs .cardb,
  #page-order #v8-order-secs .grid3{margin:0 0 10px}
  /* Правила эталона sales-css:287-288 (body:not(.admin) .grid3.collapse1{…}; body:not(.admin)
     .stack.is-empty{display:none}) — сборщик режет body-селекторы каркаса (та же судьба, что у
     dock-off выше). Режима настройки (body.admin) на этом экране нет — действует ветка «вне
     настройки»: пустая колонка скрыта, одинокая колонка не делит ширину. Значения эталонные,
     поменяна только адресация. Без правила пустая полка держала 48px дыры (замерено пробой). */
  #page-order .grid3.collapse1{grid-template-columns:minmax(0,1fr)}
  #page-order .stack.is-empty{display:none}
  
  /* ═══ [CARD-V8-HEROMIN] Липкая шапка закупки + свёрнутое состояние (полоса якорей и мини-денег).
     1) Слот шапки: в эталоне .hero стоит НАД прокруткой (.body-scroll) и виден всегда; у продукта
        карточку прокручивает .deal-left-scroll, поэтому шапка кладётся в слот #v8-hero-slot первым
        ребёнком прокрутки и ЛИПНЕТ. Значения: top:0 — как у липкой .anchor-bar эталона
        (sales-css: position:sticky;top:0;z-index:30), z-index тот же 30. */
  #v8-hero-slot{position:sticky;top:0;z-index:30}
  /* 2) Состояние «свёрнуто». Правила — КОПИИ эталонных (v8-css.txt:401-418 → v8-final.txt:58 →
        v8-scale.txt:242, в порядке слоёв), поменян только ВХОД: эталонное body.hdr-min сборщик
        слоёв законно отбрасывает как правило каркаса (body …), поэтому вход записан классом
        .hdr-min — живой код вешает его на тот же body, что и эталон (v8-js: сворачивание). */
  .hdr-min .hero-sub{display:none}
  .hdr-min .hero{padding-bottom:0}
  .hdr-min .hero-min{display:flex;align-items:stretch;min-height:36px;
    border-top:1px solid var(--border);margin:0 -20px;padding:0 var(--s-2)}
  .hdr-min .hero .anchor-bar{display:flex;margin:0;border-top:0;box-shadow:none;
    background:transparent;flex-shrink:0}
  .hdr-min .hero .anchor-bar a{display:inline-flex;align-items:center}
  .hdr-min .money-mini{display:flex}
  .hdr-min .money-mini[data-empty]{display:none}
  .hdr-min .hero > .crumbs{display:none}   /* v8-final:58: прокрутили — путь уступает место содержимому */
  .hdr-min .hero-min{margin:0 -16px}       /* v8-scale:242 */
  /* 2а) [STICKY-STRIP-MONEY-WINS] ЖИВЫХ ЯКОРЕЙ БОЛЬШЕ, ЧЕМ В ДЕМО, И ОНИ ЕЛИ ЧИСЛО.
        Замер 19.08 (окно 1024, экран заказа): полоса якорей 416px + мини-деньги 612px = 1028 при
        ширине шапки 936 — последняя кнопка «ещё 1 число» уходила за край на 100px и читалась как
        обрубок «еш». В эталоне того же размера (шапка 968) якорей 279px, всё влезало: у демо
        четыре раздела с короткими подписями, у живого — пять, включая «НЕ РАЗНЕСЕНО».
        Причина, значит, не в стиле числа (у .mm-more уже nowrap) и не в ширине шапки, а в том,
        КТО уступает место: эталон прибил якоря (flex-shrink:0), а прокрутку отдал деньгам
        (.money-mini{min-width:0;overflow-x:auto}) — на его четырёх якорях это никогда не срабатывало.
        На живом списке разделов приоритет обязан быть обратным: ДЕНЬГИ целые, якоря сжимаются и
        прокручиваются СВОИМ штатным механизмом эталона (sales-css:389-391 — тонкий скроллбар).
        Когда места хватает, обе полосы стоят как раньше — правило включается только при нехватке.
        Ср. SAP Fiori «snapped header»: KPI держат размер, навигация уходит в прокрутку. */
  .hdr-min .hero-min .anchor-bar{flex-shrink:1;min-width:0;overflow-x:auto}
  .hdr-min .hero-min .money-mini{flex-shrink:0}
  /* ═══ [CARD-V8-MONEY-ABOVE-FOLD] ДЕНЬГИ ВИДНЫ СРАЗУ, А НЕ ПОСЛЕ ДВУХ ЭКРАНОВ ПРОКРУТКИ.
     ЗАМЕР 27.08 на живой карточке (окно 1680×1000): первое число сделки появлялось на y=1965 при
     высоте окна карточки 954 — то есть за 2,06 экрана прокрутки; в шапке не было НИ ОДНОГО числа.
     Полоса #money-mini для этого уже написана (v8MoneyMini собирает её из ТОГО ЖЕ #money-strip —
     второго источника чисел не заводим), но включалась только классом .hdr-min, то есть ПОСЛЕ
     прокрутки — ровно тогда, когда человек уже сам добрался до денег.
     Как у рефов: Salesforce Highlights Panel и SAP Fiori Object Page держат ключевые числа в шапке
     ДО СГИБА и не отдают их прокрутке. Поэтому вход .hdr-min для САМОЙ ПОЛОСЫ снимаем: она стоит в
     липкой шапке (#v8-hero-slot выше) с первого кадра и остаётся при прокрутке.
     ⛔ ЧТО НЕ МЕНЯЕТСЯ. Якоря разделов по-прежнему приходят только со свёрнутой шапкой (правило
     .hdr-min .hero .anchor-bar выше): до сгиба разделы и так видны, а в полной шапке их полоса —
     лишний ряд. Прибитых чисел по-прежнему НЕ ВСЕ, а помеченные data-mini ([STICKY-STRIP-SHOWS-FEW]:
     у закупки — Продажа строк, Маржа, Долг поставщику; у заказа — Всего, Маржа, Не разнесено).
     Полоса без чисел не рисуется вовсе: data-empty ставит сам сборщик, когда денежного блока нет
     (нет доступа, суммы не посчитаны) — пустого ряда на месте денег не появляется. */
  .hero-min{display:flex;align-items:stretch;min-height:36px;
    border-top:1px solid var(--border);margin:0 -16px;padding:0 var(--s-2)}
  .money-mini{display:flex}
  .money-mini[data-empty]{display:none}
  /* Полная шапка ещё не свёрнута, якорей в полосе нет — ряд держат только числа; когда и их нет,
     полоса схлопывается в ноль и границы над пустотой не рисует. */
  .hero-min:not(:has(.mm)){display:none}
  /* 3) Прицел якоря: эталон даёт .cardb[id]{scroll-margin-top:44px} — зазор под липкую полосу 36px
        (+8 воздуха). У продукта липнет ВСЯ свёрнутая шапка: строка заголовка 44px (v8-css: «сжимается
        до 44px») + полоса 36px = 80, +8 воздуха эталона = 88. Живые узлы якорей — те же 4 раздела. */
  #sec-money, #sec-items,
  #v8-related, #v8-sections{scroll-margin-top:88px}
  /* Корешок дока: правила эталона v8-dock-css:27-43 привязаны к body.dock-off — переадресация на
     наш контейнер колонок (body-селекторы каркаса сборщик режет). Значения не меняются. */
  #deal-body .dock-spine{display:none}
  #deal-body.dock-off .dock-spine{display:flex}
  
  /* ═══ [CARD-V8-DOCK-OVERLAY] Оверлей дока на узком окне + скрим — слой эталона v8-dock-css.txt:55-67
     (MP v8-purchase.html css:1601-1613, [DOCK-COLLAPSIBLE]): на ≤1152px (OVERLAY_W эталона) открытая
     панель ложится ПОВЕРХ тела (тело ширину не отдаёт), под ней затемнение #dock-scrim (клик/Esc
     закрывают — обработчики в feature-deal-card-v8.src.js). Значения эталонные (right:var(--spine-w),
     z-index 40/35, тень --sh-pop, rgba(15,23,42,.28), transform translateX(100% + spine)), поменяна
     ТОЛЬКО адресация: body.dock-off эталона (каркас — сборщик режет body-правила) → #deal-body.dock-off,
     .dock → #v8-dock (id перебивает #v8-dock{position:sticky} слоя [CARD-V8-DOCK] выше), скрим —
     клон шаблона dock.scrim. Система координат оверлея — сам #deal-body (как .wrap мокапа,
     v8-dock-css:20 position:relative; обрезку overflow-x:clip даёт [CARD-V8-DOCK-ANIM] выше). */
  #dock-scrim{display:none}   /* затемнение существует ТОЛЬКО в режиме оверлея */
  @media (max-width:1152px){
    #deal-body{position:relative}
    /* корешок виден ВСЕГДА (и при открытой панели) — тело не прыгает на 44px при открытии */
    #deal-body .dock-spine{display:flex}
    #v8-dock{position:absolute;top:0;right:var(--spine-w);bottom:0;z-index:40;
      margin-right:0;max-height:none;box-shadow:var(--sh-pop);visibility:visible;
      transition:transform var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s}
    /* закрытый оверлей — тоже НАСТОЯЩЕЕ скрытие ([CARD-V8-DOCK-CLOSED-IS-HIDDEN] выше): именно здесь
       уехавшая панель и вставала за правым краем окна (1152…1452 при ширине 1152) */
    #deal-body.dock-off #v8-dock{margin-right:0;
      transform:translateX(calc(100% + var(--spine-w)));opacity:0;visibility:hidden;
      transition:transform var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s linear var(--dock-anim)}
    /* ⛔ [HERO-NOT-UNDER-DOCK-OVERLAY] ШАПКА НЕ УХОДИТ ПОД ОВЕРЛЕЙ ПАНЕЛИ.
       У эталона .hero — СОСЕДКА области с панелью, накрыть её оверлей физически не может. У нас
       шапка живёт ВНУТРИ #deal-body, то есть внутри системы координат оверлея, и на ширинах ≤1152
       панель (z-index:40) со скримом (35) ложились прямо на неё. Замер суда 19.08: в центре кнопки
       панели elementFromPoint возвращал input#feed-q — поле поиска ленты; живой клик мышью ничего
       не делал. Владелец: «кнопка не работает».
       Поднимаем шапку НАД оверлеем — это и есть эталонный порядок слоёв, только выраженный
       z-index'ом, раз уж узел вложен. Скрим по-прежнему накрывает тело: закрыть панель кликом мимо
       можно, а органы шапки остаются достижимы, как в мокапе.
       ⚠ Поднимать надо СЛОТ, а не только саму шапку: #v8-hero-slot — липкий (position:sticky) и с
       собственным z-index:30, то есть он СОЗДАЁТ контекст наложения, внутри которого любой z-index
       шапки бессилен против панели снаружи. Проверено замером: с z-index только на #v8-hero кнопка
       оставалась перекрыта полем поиска ленты (elementFromPoint → input#feed-q). */
    #v8-hero-slot{z-index:45}
    #v8-hero{position:relative;z-index:45}
    #dock-scrim{position:absolute;inset:0;z-index:35;
      background:rgba(15,23,42,.28);border:0;padding:0}
    #deal-body:not(.dock-off) #dock-scrim{display:block}
    /* ⛔ [CARD-V8-SCRIM-ON-ORDER] ТО ЖЕ ЗАТЕМНЕНИЕ НА ЭКРАНЕ ЗАКАЗА. Правило показа было привязано
       к #deal-body — контейнеру КАРТОЧКИ, а заказ живёт в #main-content: панель ложилась поверх
       работы БЕЗ затемнения, и клик мимо неё ничего не закрывал (замер адаптива 19.08). У эталона
       признак модального режима не зависит от того, чей это экран, поэтому адресуем оба
       контейнера одинаково. Система координат — тот же контейнер, что у панели заказа.
       ⚠ Только ПРЯМОЙ потомок: карточка закупки тоже лежит внутри #main-content, и потомок через
       пробел показывал её затемнение всегда (класс dock-off висит на #deal-body, у #main-content
       его нет — условие :not() было истинным даже при свёрнутой панели, скрим перекрывал кнопку и
       панель нельзя было ОТКРЫТЬ). Скрим каждой поверхности — прямой ребёнок своего контейнера. */
    #main-content{position:relative}
    #main-content:not(.dock-off) > #dock-scrim{display:block}
  }
  
  /* ═══ [CARD-V8-DOCK-RAIL-RIGHT] КОЛОНКА КАРТОЧКИ ОСТАЁТСЯ СТРОКОЙ — иначе корешок и панель
     уезжают вниз и влево, и оверлей выше работает вхолостую.
     ПРИЧИНА (замер, а не догадка): каркас приложения переводит контейнер колонок в СТОЛБЕЦ —
     app-overrides.css:737-747 «@media (max-width:1279px){ #page-deal .deal-body{display:flex!important;
     flex-direction:column!important;gap:var(--sp-3)} }». Живая закупка #34001950D, высота окна 900:
       · 1200 — панель уходила ПОД содержимое (x 88..408, h 320 вместо 805), корешок вставал у
         ЛЕВОГО края (88..132), кнопка шапки панель не открывала;
       · 1024/900 — корешок опять слева (88..132), а справа от оверлея оставалась пустая полоса 44px,
         ровно та, на которую он рассчитан (#v8-dock{right:var(--spine-w)} в блоке выше);
         содержимое при этом уезжало под корешок на все 44px.
     ЭТАЛОН: колонка карточки — ВСЕГДА строка (.wrap = flex-row «тело + панель + корешок»,
     v8-purchase.html css:1560-1575 [DOCK-COLLAPSIBLE]), поэтому корешок стоит у правого края на
     любой ширине — замер эталона: 1200 → 1156..1200, 1152 → 1108..1152, 1024 → 980..1024.
     Возвращаем строку ТОЛЬКО виду v8 и только там, где её отнял каркас. !important — потому что
     правило каркаса тоже !important (при виде мокапа старая раскладка уходит, перебивать законно).
     Зазор 12px — значение слоя [CARD-V8-DOCK] выше, каркас подменял его своим --sp-3.
     Медиа-запрос стоит ПОСЛЕ блока оверлея намеренно: он не спорит с ним, а даёт ему поток, в
     котором корешок оказывается справа сам, без второго позиционирования. */
  @media (max-width:1279px){
    #page-deal #deal-body{flex-direction:row!important;gap:12px!important}
  }
  
  /* ═══ [CARD-V8-DOCK-W-NARROW] ШИРИНА ПАНЕЛИ НА УЗКОМ ОКНЕ — ЗНАЧЕНИЕ ЭТАЛОНА (300, не 320).
     ПОЧЕМУ ПРАВИЛО ЭТАЛОНА НЕ ДОЕЗЖАЛО НИКОГДА: у мокапа порог живёт на :root — v8-dock-css.txt:15
     «@media (max-width:1345px){ :root{--dock-w:clamp(300px,26vw,400px)} }», — а собранный стиль вида
     целиком лежит в @scope (html[data-card-v8]), и правило с :root ВНУТРИ области к самому корню
     области НЕ применяется. Проверено отдельным опытом, а не рассуждением: страница с
     «:root{--v:1px}» снаружи и «@scope (html[data-x]){ :root{--v:2px} @media …{ :root{--v:3px} } }»
     внутри отдаёт computed 1px. Значит --dock-w приходил ТОЛЬКО из design-v8-tokens.css:48 (базовый
     clamp(320px,26vw,460px)), а порог 1345 не срабатывал ни разу: замер живой закупки на 1024 —
     панель 320px против 300px у эталона (замер эталона на той же ширине: 680..980).
     Повторяем эталонное значение на узлах ВНУТРИ области — хостах обеих поверхностей (#deal-body у
     карточки, #main-content у экрана заказа): переменная наследуется вниз к #v8-dock/#v8-order-dock
     и к отступу страницы. Значение и порог эталонные, своего тут нет. Шире 1345 значение прежнее. */
  @media (max-width:1345px){
    #deal-body,
    #main-content{--dock-w:clamp(300px,26vw,400px)}
  }
  
  /* ═══ [CARD-V8-FIELD-CONTROLS] Живые органы полей внутри эталонных .fi — вид ЭТАЛОНА.
     Владелец: «сделки некорректно отображают вёрстку полей, выпадающих списков». В эталоне значение
     поля — ТЕКСТ (.fi .v: 600 13px, выравнивание, ховер surface3), а рамка появляется только у
     редактора (.fi input/select: border blue-bd + outline blue-bg — v8-css:153, sales:139).
     Наши органы — живые контролы ядра, видимые постоянно; здесь им даётся покойный вид «текста
     эталона», а фокус включает эталонный вид редактора. Значения — копии эталонных правил. ── */
  .fi .cf-val .cf-inp,
  .fi .cf-val input,
  .fi .cf-val select,
  .fi .cf-val textarea{
    font:600 13px/20px 'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif;
    color:var(--text);border:0 !important;outline:0;background-color:transparent;border-radius:7px;
    padding:2px 7px;width:100%;min-width:0;height:auto;box-shadow:none !important;appearance:none !important;
    -webkit-appearance:none !important;cursor:pointer;transition:background .12s}
    /* !important здесь — ответ на !important-рамки полей самого приложения (app-overrides);
       значения — эталонные, приоритет лишь уравнен */
  .fi .cf-val .cf-inp:hover,
  .fi .cf-val input:hover,
  .fi .cf-val select:hover{background:var(--surface3)}
  /* фокус = редактор эталона (v8-css:153: рамка blue-bd, свечение blue-bg, высота 28) */
  .fi .cf-val input:focus,
  .fi .cf-val select:focus,
  .fi .cf-val textarea:focus,
  .fi .cf-val .cf-inp:focus{
    border:1px solid var(--blue-bd) !important;outline:2px solid var(--blue-bg);background:var(--surface);
    height:28px;padding:2px 8px;cursor:text}
  /* стрелка селекта — тонкий шеврон эталонных иконок (ic14), а не системная толстая */
  .fi .cf-val select{
    background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 6px center;background-size:14px;padding-right:24px !important}
  /* !important на образе стрелки: шорткат background:transparent из стилей ядра (.cf-sel) сбрасывал
     background-image в initial и системная стрелка исчезала вовсе */
  .fi .cf-val select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important}
  /* пустое значение — стиль пустого поля эталона (v8-css .fi.empty .v: курсив, пунктир) */
  .fi .cf-val input::placeholder{color:var(--text3);font-weight:400;font-style:italic}
  
  /* ── [CARD-V8-FIELD-ROW-ONE-LINE] Строка поля — В ОДНУ СТРОКУ, как в эталоне. ────────────────
     Владелец 19.08: «поля во вкладках огромные и не как в мокапах». Замер на его сделке
     34001950F-2, ширина 1440 (scratchpad/fields-size/measure.mjs): эталонное .fi во вкладке
     = 49px (подпись 16 + значение 24 + отступы 8 + линия 1), живое = 73px у правимого поля,
     53px у поля-результата и 110px у пустого — в полтора-два с половиной раза выше.
     Три корня, и все три — от того, что внутри .v лежит ЖИВОЙ орган, а не текст эталона:
       1) .cf-val — БЛОЧНЫЙ див, а карандаш .pen — инлайновый: карандаш становился ВТОРОЙ
          строкой значения (+20px каждому ПРАВИМОМУ полю). Проверяется вычитанием: у полей
          «только просмотр» карандаш снят кодом, и они были ровно на 20px ниже (53 против 73).
          Кладём содержимое .v в один ряд — как текст с инлайновым карандашом в эталоне.
       2) орган ядра нёс свой вертикальный отступ (2px сверху и снизу) ПОВЕРХ отступов .v:
          значение выходило 28px вместо эталонных 24. Снимаем вертикальный отступ у органа,
          горизонтальный оставляем эталонный (в эталоне у редактора padding:2px 8px, но там
          редактор ЗАМЕНЯЕТ значение, а у нас живёт внутри него).
       3) многострочному полю ядро ставит ИНЛАЙНОВУЮ высоту (style="height:54px"), а инлайн
          бьёт таблицу стилей — пустое поле разрасталось до 110px. Пока поле не в фокусе,
          держим эталонную строку; в фокусе инлайновая высота ядра возвращается сама — печатать
          длинный текст в одну строку неудобно, а эталон в момент правки тоже показывает
          редактор, а не значение.
     Отступы, шрифт и цвет самих .k/.v здесь НЕ трогаются — они уже эталонные и сверяются
     scripts/qa/card-v8-style-parity.mjs; правится только живой орган внутри значения. ── */
  /* Подпись поля прижата ВЛЕВО, как в эталоне. В мокапе это умолчание страницы и правила для .k
     нет вовсе; у нашего приложения на самом <body> стоит text-align:center, и перенесённое дословно
     правило .fi .k получило чужое выравнивание — подписи вставали ПО ЦЕНТРУ колонки (значение .v
     выравнивание объявляет само, поэтому расхождение было видно только на подписях). Возвращаем
     полю окружение эталона, а не переписываем эталонное правило. */
  .fi{text-align:start}
    /* именно start, а не left: у эталона это умолчание и браузер печатает вычисленным «start» —
       сверка стилей сравнивает строки, и «left» дало бы ложное расхождение на одинаковой картинке */
  .fi .v{display:flex;align-items:center;column-gap:2px}
  .cardb.horiz .fi.empty .v{display:inline-flex}
  .fi .v > .cf-val{display:flex;align-items:center;column-gap:6px;flex:1 1 auto;min-width:0}
    /* .cf-val тоже ряд, а не блок с текстом: инлайн-блочный орган внутри блока стоит на базовой
       линии, и под ним остаётся «подвал» под хвосты букв (пустое многострочное поле давало 31px
       значения вместо эталонных 26). В ряду орган — элемент ряда, лишней строки нет. Ряд, а не
       блок-элемент, потому что у части полей ядро кладёт в значение ДВА органа (сумма + валюта). */
  .fi .v > .pen{flex:0 0 auto;display:inline-flex;align-items:center}
  .fi .cf-val .cf-inp,
  .fi .cf-val input,
  .fi .cf-val select,
  .fi .cf-val textarea{padding-top:0;padding-bottom:0;line-height:20px;min-height:0}
  /* высоту ядра (инлайновый style="height:…") перебиваем только у НЕ активного поля */
  .fi .cf-val textarea:not(:focus){height:20px !important;min-height:0;resize:none;
    overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
  
  /* ── [CARD-V8-ITEMS] пустое состояние таблицы товаров: эталон против легаси-обвязки. ──────────
     app-overrides.css (FIX 16 + v199.306) наряжает ЛЮБОЙ .empty-state продукта: пунктирная рамка,
     отступы-margin и ::before-значок «inbox». Эталонный блок мокапа носит ТО ЖЕ имя класса, но
     свой вид: значок «коробка» в .es-ic, без рамки. На живой карточке легаси-обвязка наслаивалась
     (два значка + пунктир — поймано скриншотом agent7-items-empty). Глушим её только внутри
     секции товаров; !important — против безусловных правил app-overrides. */
  #sec-items .empty-state{
    border:none !important;background:transparent !important;margin:0 !important;
    padding:26px 16px !important}
  #sec-items .empty-state::before{content:none !important}
  
  /* ═══ [CARD-V8-TABS-SETUP]+[CARD-V8-ACTIONS] Правила эталона, привязанные к body мокапа.
     Сборщик вырезает селекторы, НАЧИНАЮЩИЕСЯ с body (каркас мокапа в продукт не едет), поэтому
     копии эталонных правил приведены к классам БЕЗ префикса body — живой код вешает те же классы
     на тот же body, что и эталон (прецедент: .hdr-min выше). Значения — байт в байт из
     sales-css.txt:152,247-453 и v8-css.txt (режим настройки), кроме помеченных адаптаций. ── */
  /* тумблер «скрывать пустые» (sales-css:152) */
  .hide-empty .fi.empty{display:none}
  /* [CARD-V8-FRESH-FIELD-VISIBLE] адаптация (в эталоне создание поля живёт в модалке, у которой
     этой коллизии нет): поле, ТОЛЬКО ЧТО созданное прямо во вкладке, пусто по определению — и
     «скрывать пустые» (включено по умолчанию) спрятало бы его в тот же миг, то есть человек нажал
     бы «Создать поле» и не увидел РОВНО НИЧЕГО. Исключение снимается само, как только в поле
     ввели значение (метку ведёт _v8FiState). Настройку человека не меняем. */
  .hide-empty .fi.empty.v8-fresh{display:grid}
  .hide-empty .cardb.horiz .bd > .fgrid > .fi.empty.v8-fresh{display:grid}
  /* ⛔ [CARD-V8-NOTHING-VANISHES-SILENTLY] РАЗОВЫЙ ПОКАЗ ПУСТЫХ ПОЛЕЙ ОДНОЙ ВКЛАДКИ.
     Замер 27.08: вкладка SEND CO показывала «· 0 из 6» и НИ ОДНОГО поля — все шесть пусты, а режим
     «скрывать пустые» включён по умолчанию. Круг замкнут: чтобы заполнить, надо увидеть; не видно,
     потому что пусто (всего так спрятано 50 полей карточки). Орган «+ Ещё N полей (пустые)» вешает
     на вкладку класс .v8-show-empty — ЛИЧНАЯ настройка человека при этом не меняется, как «Show
     More» у SAP Fiori и «View All» у Salesforce. Оба селектора нужны: второй бьёт правило
     горизонтальной вкладки, которое сильнее по специфичности. */
  .hide-empty .cardb.v8-show-empty .fi.empty{display:grid}
  .hide-empty .cardb.horiz.v8-show-empty .bd > .fgrid > .fi.empty{display:grid}
  /* Подвал вкладки: орган возврата пустых + перечень закрытого матрицей доступа. Стоит СНАРУЖИ
     .fgrid (в горизонтальной вкладке сетка идёт колонками — чужой ребёнок встал бы колонкой). */
  .cardb .bd > .v8-fmore{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
    padding:6px 12px;border-top:1px solid var(--surface2);font-size:11px;line-height:16px;color:var(--text3)}
  .cardb .bd > .v8-fmore .v8-more-btn{display:inline-flex;align-items:center;gap:5px;min-height:24px;
    padding:2px 9px;border:1px solid var(--border-ctl);border-radius:var(--r-ctl);background:var(--surface);
    color:var(--accent-text);font:inherit;cursor:pointer;white-space:nowrap}
  .cardb .bd > .v8-fmore .v8-more-btn:hover{background:var(--surface2)}
  .cardb .bd > .v8-fmore .v8-more-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .cardb .bd > .v8-fmore .v8-locked{color:var(--text3);min-width:0;overflow:hidden;text-overflow:ellipsis}
  /* режим настройки: рамки, инструменты, крестики (sales-css:247-453) */
  .admin .cardb[data-sec-id]{outline:2px dashed rgba(59,130,246,.4);outline-offset:2px}
  .admin .sec-tools{display:inline-flex}
  .admin .cardb .hd{cursor:grab}
  .admin .fi{cursor:grab;user-select:none}
  .admin .fi:active{cursor:grabbing}
  .admin .fi .v{cursor:grab}
  .admin .admin-hint{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
  .admin .hfields .fi{position:relative;overflow:visible}
  .admin .hfields{outline:2px dashed rgba(59,130,246,.4);outline-offset:2px;border-radius:10px}
  .admin .hf-add{display:inline-flex!important;align-self:center}
  .admin .fi{position:relative;overflow:visible}
  .admin .fi .fi-x{display:inline-flex;opacity:0}
  .admin .fi:hover .fi-x,.admin .fi .fi-x:focus-visible{opacity:1}
  /* [FIELD-MENU-IN-CARD] АДАПТАЦИЯ (в эталоне правка МЕТАДАННЫХ поля живёт только в отдельном
     экране настроек; требование владельца — «менять состав и тип полей ПРЯМО В СДЕЛКЕ», реф
     Salesforce «Edit Page» / amoCRM «Настроить»). Значок «⋯» висит на ПОДПИСИ (.k), а не на
     значении: у значения свой хозяин — правка значения ([ONE-CLICK-ONE-OWNER]). Проявляется по
     наведению/фокусу — той же механикой, что крестик скрытия выше, чтобы не зашумлять карточку.
     Режимом настройки НЕ гейтится: право на структуру — это право, а не режим просмотра. */
  .fi .k .fkm{display:none;align-items:center;justify-content:center;margin-left:4px;padding:0;
    width:16px;height:14px;border:0;border-radius:4px;background:transparent;color:var(--text3);
    font-size:12px;line-height:1;cursor:pointer;opacity:0;transition:opacity .12s}
  .fi .k > .fkm{display:inline-flex}
  .fi:hover .k .fkm,.fi .k .fkm:focus-visible{opacity:1}
  .fi .k .fkm:hover{background:var(--surface3);color:var(--text)}
  /* сенсорный экран наведения не знает — иначе настройка поля недостижима с планшета */
  @media (hover:none){.fi .k .fkm{opacity:.65}}
  /* АДАПТАЦИЯ: в живой карточке значение поля — настоящий контрол ядра (.cf-val); в режиме
     настройки поле ПЕРЕТАСКИВАЕТСЯ, а не редактируется (эталон js:2167 глушит клик) — контрол
     на время режима не ловит мышь, иначе drag начинался бы с выпадающего списка. */
  .admin .fi .cf-val{pointer-events:none}
  /* АДАПТАЦИЯ «вкладок в ряду»: у живой карточки закупки вкладки лежат НЕ в .grid3 эталона, а
     прямым потоком #v8-sections (все горизонтальные). Пер-юзер настройка 1..6 раскладывает их
     сеткой (--sec-cols ставит applyColsV8 — перенесённый applyCols); 'auto' = поток как сейчас.
     Газетные колонки внутри вкладки пересчитывает эталонный applyHoriz по новой ширине. */
  #v8-sections[data-cols]{display:grid;grid-template-columns:repeat(var(--sec-cols,1),minmax(0,1fr));
    gap:12px;align-items:start}
  #v8-sections[data-cols] > .cardb{margin:0}
  /* АДАПТАЦИЯ закрепа: строки живой ленты (.feed-task-row) в #feed-pin получают ту же левую
     планку, что .act-item эталона (v8-dock-css:124-126); свой вид строки не меняется. */
  #feed-pin .feed-task-row{border-left:3px solid var(--border2);margin-left:0;margin-right:0}
  #feed-pin .feed-task-row[data-task-overdue="1"]{border-left-color:var(--red)}
  /* кнопка «↓ к новым» живёт в доке продукта — позиционный контекст ему задаёт вид v8.
     ⛔ ТОЛЬКО на широком окне: на ≤1152 док — оверлей (position:absolute, media-блок ВЫШЕ),
     а правило в хвосте файла с той же специфичностью молча побеждало бы его (поймано регрессом
     agent6-dock: pos=relative вместо absolute). */
  @media (min-width:1153px){
    #v8-dock{position:relative}
  }
  
  /* ═══ [CARD-V8-ADAPTIVE-FIX] По карте адаптива (аудит 18.08). Все значения — из эталонов. ══════ */
  /* Деньги: у эталона значение плитки ПЕРЕНОСИТСЯ (v8-purchase.html:1407 #sec-money .kpi .kv
     {white-space:normal}) — у нас работал nowrap базового слоя и «10 395,60 / 34 652,00 ₼»
     обрезалось на 25px, молча теряя разряды. Правило применяем и к блоку заказа. */
  #sec-money .kpi .kv,
  #sec-money-order .kpi .kv{white-space:normal;overflow:visible;text-overflow:clip}
  /* Лента правок: длинные записи «Поля изменены: …» рисуются одной строкой и режутся контейнером
     (обрезки до +5185px). Перенос по словам — как у текста сообщения эталона (.act-item .msg
     {overflow-wrap:anywhere}, v8-dock-css). */
  #v8-dock .feed-item, #v8-dock .feed-row,
  #v8-dock #deal-feed span, #v8-dock #deal-feed div{
    overflow-wrap:anywhere;white-space:normal}
  /* Корешок свёрнутого дока: у эталона он во всю высоту колонки (v8-dock-css:27 — flex-колонка
     контейнера), у нас схлопывался до 208px на узких. */
  #deal-body.dock-off .dock-spine{align-self:stretch;min-height:100%}
  /* Панель кнопок промежуточного вида («История», «Настроить страницу», «Вид: классика») при виде
     мокапа не нужна: её пункты переехали в меню «Действия» эталона ([CARD-VIEWS-ARE-TWO]).
     Она же съедала высоту над героем — из-за неё газетная сетка давала на колонку меньше эталона. */
  #v6-head > div:first-child:has(#v6-cfg-btn),
  #v6-head > div:first-child:has(#v6-classic-btn){display:none}
  /* Дробное значение («оплачено / начислено»): перенос обязан быть возможен и ВНУТРИ .of — иначе
     строка остаётся одной, и normal у родителя ничего не даёт (замер: обрезка 25px сохранялась). */
  /* Стиля для .of здесь НЕТ намеренно: у эталона он nowrap, а перенос обеспечивает пробел МЕЖДУ
     числителем и знаменателем в разметке (см. [CARD-V8-MONEY]). Костыль white-space:normal убран —
     он ломал паритет и лечил следствие вместо причины. */
  
  /* ═══ [CARD-V8-ANIM-PARITY] Аудит анимаций 19.08: три перехода эталона до живой карточки не
     доезжали. Ни одного НОВОГО значения тут нет — только эталонные, с поднятой адресацией. ─────── */
  
  /* 1) ЧИПЫ УЧАСТНИКОВ. Эталон: v8-purchase.html:73-75 (= sales-css.txt:64)
        «.pchip{…transition:border-color .12s,box-shadow .12s}» + «.pchip:hover{border-color:var(--accent)}».
        Живой чип — ссылка <a class="pchip">, и её перехватывает правило приложения
        app-overrides.css:271-275 «a:not(.btn):not([role="button"]):not(.deal-tab):not(.an-tab)
        {transition:color var(--duration-fast)}» — специфичность (0,4,1) против (0,1,0) у .pchip.
        Замер живой карточки: transition-property=color вместо border-color,box-shadow → рамка при
        наведении ПРЫГАЛА. Отвечаем той же формой селектора (0,5,1), значения — эталонные. */
  a.pchip:not(.btn):not([role="button"]):not(.deal-tab):not(.an-tab){
    transition:border-color .12s,box-shadow .12s}
  
  /* 2) УМЕНЬШЕННАЯ АНИМАЦИЯ. Эталон: v8-dock-css.txt:81-83 (= v8-purchase.html:1629-1631)
        «@media (prefers-reduced-motion:reduce){ .dock{transition:none} }». У продукта панель
        адресуется по id (#v8-dock, блоки [CARD-V8-DOCK-ANIM]/[CARD-V8-DOCK-OVERLAY] выше), и
        классовое правило эталона (0,1,0) по id-правилам (1,0,0) не проходит НИКОГДА. Замер:
        transition-duration живого дока при reduce = 1e-05s, то есть его гасило ГЛОБАЛЬНОЕ правило
        приложения (app-overrides.css:899-905 «*{transition-duration:.01ms!important}»), а правило
        вида молчало. Повторяем эталон на живой адресации; блок стоит ПОСЛЕ обоих id-правил. */
  @media (prefers-reduced-motion:reduce){
    #v8-dock{transition:none}
  }
  
  /* 3) ПОДСВЕТКА СВЕЖЕЙ ЗАПИСИ ЛЕНТЫ. Эталон: v8-css.txt:154-155 (= v8-purchase.html:633-634)
        «.act-item.fresh{animation:v8fresh 1.6s ease-out}» — после отправки записи эталон помечает
        последнюю строку ленты. У продукта строки ленты рисует живой орган (feature-deal-feed) и
        класса .act-item у них нет — правило эталона не доставало ни до одной живой строки (замер:
        animation-name=none на строке с классом fresh). Адресация — прямые дети живой ленты внутри
        эталонного дока; значения (имя кадров, 1.6s, ease-out) эталонные. Класс ставит перенесённый
        код эталона (feature-deal-card-v8.src.js, блок [CARD-V8-FEED-FRESH]). */
  #v8-dock #deal-feed > .fresh{animation:v8fresh 1.6s ease-out}
  
  /* ═══ [CARD-V8-SELECT-CHEVRON] Шеврон выпадающего списка — ОДИН, справа. ═══════════════════════
     Аудит полей 19.08 (браузер): на карточке мокапа КАЖДЫЙ выпадающий список рисовал ЛЕНТУ
     шевронов поверх значения — «Тимлид» выглядел рядом из шести галочек, «Логистика» — именем,
     перечёркнутым галочками. Замер computed: background-repeat=repeat, position=0% 0%, size=auto.
     Корень: правило [CARD-V8-FIELD-CONTROLS] выше ставит !important только образу
     (background-image), а размещение (repeat/position/size) — обычным весом. Приложение же красит
     ЛЮБОЙ select ШОРТКАТОМ (app-overrides.css:105 `select:not(.v2-select)…{background:var(--surface)}`,
     вес 0-3-1 против нашего 0-2-1) — шорткат сбрасывает размещение в начальное (repeat, 0 0, auto),
     а наш !important-образ остаётся. Значения размещения — те же, что в правиле эталона выше;
     добавлен только приоритет, чтобы шорткат приложения их не сбивал. Заодно фон списка держим
     прозрачным (в эталоне значение поля — текст на подложке карточки, не белая плашка). */
  .fi .cf-val select{
    background-repeat:no-repeat !important;background-position:right 6px center !important;
    background-size:14px !important;background-color:transparent !important}
  /* поле-результат движка: курсор и ховер как у .fi.ro эталона (v8-css: cursor:default, ховер без
     подсветки) — живой орган внутри .v получал «палец» и подсветку ввода от правил органов выше */
  .fi.ro .cf-val .cf-inp,
  .fi.ro .cf-val input,
  .fi.ro .cf-val select{cursor:default}
  .fi.ro .cf-val .cf-inp:hover,
  .fi.ro .cf-val input:hover,
  .fi.ro .cf-val select:hover{background:transparent}
  
  /* ═══ [CARD-V8-TYPOGRAPHY-PARITY] Аудит типографики 19.08: узел за узлом против эталона ══════
     Метод: обход ВСЕХ видимых текстовых узлов мокапа и живой карточки, сверка вычисленных
     шрифтовых свойств по сигнатуре узла (tag+id+классы) + контекст предков, реально применённый
     фейс через CDP CSS.getPlatformFontsForNode, обрезки (scrollWidth>clientWidth) и переносы.
     Все значения ниже — ЗНАЧЕНИЯ ЭТАЛОНА, источник указан файлом и строкой. */
  
  /* 1. БАЗА ТИПОГРАФИКИ КАРТОЧКИ.
     источник: public/mockups/v8-purchase.html:868 — body{font-size:var(--fs-2);line-height:var(--lh-2)}
     (тот же слой: design/mockup-layers/v8-css.txt:389). Сборщик build-card-v8-css.sh намеренно
     ВЫРЕЗАЕТ правила, начинающиеся с body (каркас мокапа в продукт не едет), — вместе с каркасом
     терялась и база: в живой карточке строка 18,85px против 20px в эталоне. Второе: продукт вешает
     на body letter-spacing:-.01em (public/sofcon_crm_v199_53.html:227), которого у эталона нет
     (v8-purchase.html:34 html,body{font:13px/1.45 …} → межбуквенный обычный) — минус 0,13px на
     каждой паре букв во ВСЁМ тексте карточки. Кладём базу эталона на контейнеры карточки: дальше
     страницы сделки и экрана заказа правило не уходит. */
  .deal-wrap,
  #page-order{font-size:var(--fs-2);line-height:var(--lh-2);letter-spacing:normal}
  
  /* 2. ТАБЛИЧНЫЕ ЦИФРЫ ТОЛЬКО ТАМ, ГДЕ ИХ ДАЁТ ЭТАЛОН.
     источник: public/mockups/v8-purchase.html:186 — table.items td.r{font-variant-numeric:tabular-nums}
     и :95 .kpi .kv{…tabular-nums} — то есть эталон включает моноширинные цифры ТОЧЕЧНО.
     Продукт (public/apple-design-tokens.css:85) вешает font-variant-numeric:tabular-nums и
     font-feature-settings:'tnum' на КАЖДУЮ table, и они наследуются в шапки, названия товаров и
     ссылки — 22 узла закупки и 12 узлов заказа расходились с эталоном. Возвращаем базу эталона
     на саму таблицу; точечные правила эталона выше по весу и продолжают действовать. */
  .deal-wrap table,
  #page-order table{font-variant-numeric:normal;font-feature-settings:normal}
  
  /* 3. КНОПКИ ПЕРЕНОСЯТСЯ, КАК В ЭТАЛОНЕ.
     источник: public/mockups/v8-purchase.html:60 — .btn{…} свойства white-space НЕ содержит,
     значит normal. Продукт (public/app-overrides.css:40) ставит .btn{white-space:nowrap}: подпись
     «Разбить на закупки» и чипы композера в живой держались одной строкой и упирались в край. */
  .deal-wrap .btn,
  #page-order .btn{white-space:normal}
  
  /* 4. ПЛИТКА ДЕНЕГ — многоточие эталона, а не обрезка.
     источник: public/mockups/v8-purchase.html:95 — .kpi .kv{…overflow:hidden;text-overflow:ellipsis}
     и :1407 — #sec-money .kpi .kv{white-space:normal} (переносится, но overflow/ellipsis базового
     правила эталон НЕ отменяет). В слое адаптива к правилу эталона были дописаны overflow:visible
     и text-overflow:clip, которых у эталона нет. */
  #sec-money .kpi .kv,
  #sec-money-order .kpi .kv{overflow:hidden;text-overflow:ellipsis}
  
  /* 5. БЕЙДЖ ПОКАЗЫВАЕТСЯ ЦЕЛИКОМ.
     источник: public/mockups/v8-purchase.html:56 — .badge{font-size:11px;font-weight:600;…} — ни
     max-width, ни overflow, ни text-overflow. Продукт (public/components-v2.css:714) режет бейдж:
     max-width:200px;overflow:hidden;text-overflow:ellipsis. */
  .deal-wrap .badge,
  #page-order .badge{max-width:none;overflow:visible;text-overflow:clip}
  
  /* 6. ССЫЛКА В ТАБЛИЦЕ — начертанием ячейки.
     источник: public/mockups/v8-purchase.html:938 — table.items td a.cl{color:var(--accent);font:inherit}
     (font:inherit → font-weight 400 от ячейки). Продукт (public/app-overrides.css:1110)
     td a[href^="#/deal/"]{font-weight:var(--fw-medium)!important} делал ссылки полужирными —
     14 ссылок таблицы связанных сделок. !important перебивается только !important. */
  table.items td a.cl{font-weight:inherit!important}
  
  /* 7. КОМПОЗЕР — стек шрифта эталона.
     источник: design/mockup-layers/v8-final.txt (.compose textarea{font:12px/1.45 'SofconManat',
     'InterVariable','Inter-fallback',-apple-system,sans-serif}); в живой его перебивал продуктовый
     textarea:not(.v2-textarea):not(…){font-family:var(--font-sans)} (public/app-overrides.css:104):
     вес селектора выше из-за :not(). Рисунок совпадал (InterVariable), объявление — нет. */
  .compose textarea{
    font-family:'SofconManat','InterVariable','Inter-fallback',-apple-system,sans-serif!important}
  
  /* 8. ПОЛЕ ПРОЦЕНТА В УСЛОВИЯХ ОПЛАТЫ.
     источник: public/mockups/v8-purchase.html:1464 — #pt-inp{…background:transparent;font:inherit;
     font-size:var(--fs-3)…}: цвет эталон не назначает, остаётся системный fieldtext (чёрный).
     Продукт красит все input в var(--text) (#111827) — public/app-overrides.css:96. */
  #pt-inp{color:fieldtext}
  
  /* 9. ЛЕНТА: ЗАПИСИ ПЕРЕНОСЯТСЯ, А НЕ РЕЖУТСЯ.
     Правило переноса ленты уже стояло выше в этом слое, но НЕ ДЕЙСТВОВАЛО: орган ленты пишет
     overflow:hidden;text-overflow:ellipsis;white-space:nowrap ИНЛАЙНОМ
     (public/feature-deal-feed.src.js:784 и :895), а инлайн бьёт любой селектор без !important.
     Замер до правки: 25 записей ленты за краем, худшая на +5292px («Поля изменены: …»).
     источник: public/mockups/v8-purchase.html — текст сообщения ленты .act-item .msg переносится
     (white-space:normal, замер эталона: 2 строки), обрезок в ленте эталона НЕТ ни одной.
     Целимся по инлайновому признаку обрезки, чтобы не задеть отметки времени и разделители дней,
     которым nowrap положен; браузер сериализует инлайн-стиль с пробелом после двоеточия, а
     разметка через innerHTML — без него, поэтому оба написания. */
  #v8-dock #deal-feed [style*="text-overflow: ellipsis"],
  #v8-dock #deal-feed [style*="text-overflow:ellipsis"]{
    white-space:normal!important;text-overflow:clip!important}
  
  /* ══ СВЕРКА ВЁРСТКИ КАРТОЧКИ ЗАКУПКИ БЛОК ЗА БЛОКОМ (19.08) ══════════════════════════════════
     Ниже — расхождения, найденные замером ГЕОМЕТРИИ живой карточки #/deal/sofcon/34001950D против
     эталона public/mockups/v8-purchase.html в одном окне 1680×1000. Каждое правило повторяет
     значение эталона (файл:строка) и поднимает только специфичность. */
  
  /* 10. КНОПКИ РАСТУТ ПО СОДЕРЖИМОМУ, КАК В ЭТАЛОНЕ.
     источник: public/mockups/v8-purchase.html:60 и :1056 — у .btn НЕТ объявления height, высота
     складывается из содержимого: строка 20px + padding 4+4 + рамки 2 = 30px (замер эталона:
     «Действия» 114×30, «Колонки» 93×30, чипы композера 123×30). Продукт задаёт
     .btn{height:var(--button-height)} (public/app-overrides.css:31), плюс вставляемый скриптом
     .btn{height:32px} — живые кнопки стояли 32px: шапки блоков 49px против эталонных 47px,
     полоса композера 93px против 89px, «Сохранить» в условиях 32px против 30px. */
  .deal-wrap .btn,
  #page-order .btn{height:auto}
  
  /* 11. ИКОНКА В КНОПКЕ — РАЗМЕРА ЭТАЛОНА.
     источник: public/mockups/v8-purchase.html:971 — .ic14{width:14px;height:14px}; :128 —
     .cardb .hd svg{width:13px;height:13px} (в шапке блока иконка мельче). Продукт ставит 16px
     двумя правилами: public/app-overrides.css:625 (.btn svg) и :673 (#page-deal .btn svg).
     Второе содержит ID, а ID перебивает любое число классов — поэтому щит эталона тоже
     адресуется через ID страницы. Замер до правки: «Действия» 16×16 вместо 14×14,
     «Колонки» 16×16 вместо 13×13. */
  #page-deal .deal-wrap .btn svg,
  #page-order .btn svg{width:14px;height:14px}
  #page-deal .deal-wrap .cardb .hd svg,
  #page-order .cardb .hd svg{width:13px;height:13px}
  
  /* 12. УСЛОВИЯ ОПЛАТЫ: КЛОН ЭТАЛОНА, А НЕ СТАРЫЙ ВИДЖЕТ.
     Имена классов эталонного блока и старого виджета условий совпадают (.pt-simple/.pt-sld/.pt-ft),
     поэтому стили виджета попадали на клон: public/app-overrides.css:1342 .pt-simple{padding:2px
     30px 12px 14px}, вставляемый скриптом набор public/feature-deal-items.src.js:2288
     .pt-ft{padding:9px 14px;border-top:1px solid} и :2316 .pt-sld{width:min(230px,100%);
     overflow:hidden;border:1px solid}. Замер до правки: ползунок 230×8 вместо полной ширины
     1122×8 и с рамкой, строка кнопки 51px вместо 30px и сдвинута на 14px, блок 187px вместо 152px.
     Значения ниже — начальные, то есть ровно то, чего эталон НЕ объявляет
     (public/mockups/v8-purchase.html:1441 .pt-simple, :1469 .pt-sld, :1481 .pt-ft). */
  #sec-terms .pt-simple{padding:0}
  #sec-terms .pt-sld{width:auto;border:0;overflow:visible}
  #sec-terms .pt-ft{padding:0;border-top:0}
  
  /* ═══ [CARD-V8-ORDER-LAYOUT] Сплошная сверка ВЁРСТКИ ЭКРАНА ЗАКАЗА с эталоном v8-order.html
     (19.08). Ниже только то, что замер ВЫЧИСЛЕННЫХ стилей на живом #/order/34001950 и #/order/34001957
     показал разошедшимся; у каждого значения адрес в эталоне. Значений «на глаз» здесь нет.
  
     1. ШАГ И ВОЗДУХ МЕЖДУ БЛОКАМИ.
     Источник: design/mockup-layers/sales-css.txt:105 — .body{min-width:0;display:flex;
     flex-direction:column;gap:12px;padding-bottom:24px} и :104 — .body-scroll{…padding:12px}.
     Живой #page-order — та же flex-колонка (замерено: display:flex, flex-direction:column), но шаг
     ей задан НЕ БЫЛ: каждый клон нёс собственный margin:0 0 10px. Замер: 10px против 12px эталона на
     каждом шве, а у #sec-wizard и #sec-preview правила не было вовсе — на неразбитом заказе
     #34001957 мастер и предпросмотр слипались с соседями вплотную (0px). Шаг задаём КОНТЕЙНЕРУ, как
     в эталоне; боковой воздух .body-scroll (12px) — полями блоков, потому что шапка в эталоне лежит
     ВНЕ .body-scroll и остаётся во всю ширину. Низ: 12px прокрутки + 24px .body = 36px. */
  #page-order{row-gap:12px;padding-bottom:36px}
  #page-order > #sec-money-order,
  #page-order > #sec-wizard,
  #page-order > #sec-preview,
  #page-order > #sec-unalloc,
  #page-order > #sec-items,
  #page-order > #sec-parts,
  #page-order > #sec-settle,
  #page-order > #sec-rbac,
  #page-order > #v8-order-secs{margin:0 12px}
  /* Секции полей заказа лежат в своей обёртке #v8-order-secs; у эталона они прямые дети .body и
     получают её шаг — повторяем шаг ВНУТРИ обёртки, поштучные поля снимаем. */
  #page-order #v8-order-secs{display:flex;flex-direction:column;row-gap:12px}
  #page-order #v8-order-secs .cardb,
  #page-order #v8-order-secs .grid3{margin:0}
  
  /* 2. ШАПКА ЗАКАЗА ПРИ ПРОКРУТКЕ. Тот же приём, что у закупки ([CARD-V8-HEROMIN], этот файл:369):
     в эталоне .hero стоит НАД прокруткой (.body-scroll) и виден всегда — sales-css.txt:41
     .hero{…flex-shrink:0}; у экрана заказа прокручивается сам #page-order, и шапка уезжала ЦЕЛИКОМ.
     Замерено: при scrollTop 800 верх #v8-order-hero −731px, то есть свёрнутая полоса #hero-min
     (якоря разделов + мини-деньги) недостижима вовсе, хотя body.hdr-min выставляется исправно.
     Значения — те же, что у слота закупки (top:0, z-index:30 = липкая .anchor-bar эталона,
     sales-css.txt:94). Прицел якорей — эталонный .cardb[id]{scroll-margin-top} с поправкой на
     свёрнутую шапку продукта (44+36+8=88), как строкой 386 этого файла для закупки. */
  #page-order > #v8-order-hero{position:sticky;top:0;z-index:30}
  #sec-money-order, #page-order #sec-unalloc,
  #page-order #sec-parts, #page-order #sec-settle,
  #page-order #v8-order-secs{scroll-margin-top:88px}
  
  /* 3. ВЫСОТА КНОПОК. Источник: v8-scale.txt:17 .btn{font-size:13px;font-weight:600;line-height:20px;
     padding:4px 12px;gap:4px;border-radius:6px} + sales-css.txt:50 .btn{border:1px solid …} → высота
     30px; свойства height у эталонной .btn НЕТ ВООБЩЕ. Продукт задаёт .btn{height:var(--button-height)}
     = 32px (public/sofcon_crm_v199_53.html:335). Замер: «Колонки» 92×32 против 93×30 эталона,
     «Разбить на закупки» 179×32 против 171×30 — и из-за этого вся шапка карточки товаров 49px
     против 47px эталона. Правило :319 вернуло паддинги, но не высоту, и покрывало только
     .cardb/.hero — красный блок «Не разнесено» это .redbox, его кнопки остались с паддингом
     продукта (0 16px !important). */
  #page-order .btn{height:auto}
  #page-order .redbox .btn{padding:4px 12px !important;white-space:normal;
    justify-content:normal;line-height:20px}
  #page-order .redbox .btn.sm{padding:4px 8px !important}
  
  /* 4. СТАРАЯ ШАПКА СТРАНИЦЫ ЗАКАЗА — правило есть, но НЕ ДЕЙСТВУЕТ.
     [CARD-V8-NO-DOUBLE-HEAD] (этот файл:159) объявил .page-head:has(#_fdPageTitle){display:none} —
     и оно молчало: display у полосы задан ИНЛАЙНОМ (public/feature-kanban-card.src.js:1028
     style="display:flex;…"), а инлайн бьёт любую специфичность. Замерено на живом экране: полоса
     «← Назад к воронке» видима (1592×57) и висит В КОНЦЕ страницы — ниже всех блоков вида, потому
     что клоны эталона вставляются ПЕРЕД ней. В эталоне такой полосы нет: путь показывают крошки
     шапки. Отвечаем !important — как соседние правила этого файла для инлайновых строк заказа. */
  :scope:has(#v8-order-hero) .page-head:has(#_fdPageTitle){display:none !important}
  
  /* 13. КНОПКИ ДОКА — ПАДДИНГИ ЭТАЛОНА.
     Правило выше по файлу («Кнопки области вида») чинило .cardb и .hero, но док в него не входил,
     и чипы композера стояли с продуктовым padding:0 12px !important (public/app-overrides.css:32):
     «Примечание» 130×24 против эталонных 123×30. источник: public/mockups/v8-purchase.html:1056
     .btn{padding:4px 12px} и :1057 .btn.sm{padding:4px 8px}; «→» (#send) размера не меняет — у него
     свои height/width эталона (:241 .compose #send{height:34px;width:38px}). */
  .dock .btn{padding:4px 12px !important;white-space:normal;
    justify-content:normal;line-height:20px}
  .dock .btn.sm{padding:4px 8px !important}
  
  /* 14. ПОЛЕ КОМПОЗЕРА — СКРУГЛЕНИЕ ЭТАЛОНА.
     источник: public/mockups/v8-purchase.html:238 — .compose textarea{border:1px solid var(--border);
     border-radius:10px}. Продукт скругляет все textarea по своему радиусу (замер: 6px). */
  #v8-dock .compose textarea{border-radius:10px}
  
  /* 5. ДУБЛЬ «Клиент: … Ответственный: …» ВНИЗУ ЭКРАНА. Ту же пару показывают чипы шапки
     (#v8-pchips: «Клиент» и «Ответственный»), а строка старого вида (public/feature-kanban-card.
     src.js:1177) осталась видимой в хвосте страницы — замерено 1556×20 внутри #_fdPageBody.
     Соседние строки того же рендера скрыты по классу (._ordStateRow/._ordProgRow/._ordTermsRow…,
     этот файл:252-263); у этой класса НЕТ вовсе, поэтому якорь структурный: единственный прямой
     div-потомок #_fdWrap без класса и без id, у которого ПРЯМОЙ ребёнок — подпись .u-text-3
     («Клиент:»). Второй такой div (плашка «🔒 Ещё N частей вам не видны», :1314) под условие не
     подходит: у него прямые дети — span[aria-hidden] и div. Скрываем ТОЛЬКО когда чипы реально
     построены — иначе экран остался бы вовсе без имени клиента (fail-closed). */
  :scope:has(#v8-pchips) #page-order #_fdWrap > div:not([class]):not([id]):has(> span.u-text-3){display:none}
  
  /* 15. РИТМ БЛОКОВ: 12px МЕЖДУ КАРТОЧКАМИ И 12px ОТ КРАЁВ — КАК В ЭТАЛОНЕ.
     источник: public/mockups/v8-purchase.html:115 — .body{display:flex;flex-direction:column;
     gap:12px;padding-bottom:24px} и :114 — .body-scroll{padding:12px}. Замер живой ДО правки:
     «Деньги» кончались на 388, «Товары» начинались на 388 (щели нет вовсе); пять вкладок полей шли
     встык (835/951/1179/1407/2488); «Связанные» отходили на 22px, «Условия» на 10px — четыре разных
     расстояния вместо одного. По краям блоки лежали впритык (x=88, w=1143), в эталоне они отступают
     на 12px от границ прокручиваемой области.
     Раскладка эталона (flex+gap) здесь не годится: в живом контейнере есть пустые нулевые узлы
     старого вида (#v6-groups/#v6-empty-row/#v6-other/#v6-extra) — flex-gap дал бы щель и им.
     Поэтому тот же ритм даётся полями блоков (соседние поля схлопываются в 12px, а не в 24px).
     Специфичность поднята #page-deal: прежние правила отступов адресованы двумя ID.
  
     ⛔ ЭТО ПРАВИЛО ДО БРАУЗЕРА НЕ ДОХОДИЛО (найдено 20.08). Ниже стоял абзац-пояснение, у которого
     комментарий был ЗАКРЫТ строкой выше, а сам текст остался ВНЕ комментария и заканчивался вторым
     «звёздочка-слэш». Для разборщика CSS это испорченный селектор, а испорченный селектор съедает
     СЛЕДУЮЩИЙ ЗА НИМ БЛОК ЦЕЛИКОМ — то есть саму строку #deal-sections{padding…}. Файл при этом
     читался правильно, и grep по нему врал. Доказано двумя методами: в файле правило есть, в CSSOM
     браузера его нет вовсе (scripts/qa/browser-css-rule-probe.mjs: «#deal-sections» → одно чужое
     правило .cf-sec, нашего нет), соседнее #v6-head{margin:0} на месте — съеден ровно один блок.
     Вывод общий, а не про эту строку: пояснение в слое обязано лежать ВНУТРИ комментария целиком.
  
     БОКОВЫЕ 12px ТЕПЕРЬ ВВОДЯТСЯ — прежний отказ опирался на замер, который устарел. В нём стояло:
     «левая колонка живой карточки 1143px против 1187px у эталона; с боковыми отступами блок 1119px,
     и полоса денег (сетка на 6 плиток) перестаёт помещаться в ряд». Замер 20.08 в том же окне
     1680×1000: живая колонка 1175px, эталонная 1148px — то есть теперь живая ШИРЕ эталонной на 27px,
     а не уже. Проверено мутацией стиля прямо в браузере (PROBE_CSS у scripts/qa/browser-order-nodes-probe.mjs):
     с боковыми 12px полоса денег остаётся В ОДИН РЯД (6 колонок по 191,53px против 191,03px эталона),
     а высота ячейки становится РОВНО эталонной — 84px против прежних 81px. Причина тех 3px была не в
     отступах .kpi (они совпадают, 8/8, и «простые» плитки совпадают до пикселя — 41px внутри), а в
     ЛИШНЕЙ ШИРИНЕ колонки: на 195,5px подпись «Оплата клиента ↑ из заказа» умещалась в одну строку
     (16px), в эталоне на 191px она переносится (36px) и задаёт высоту всей полосы. */
  #page-deal #deal-sections{padding:12px 12px 36px}
  #page-deal #v6-head{margin:0}
  #page-deal #v6-head > .cardb,
  #page-deal #v8-sections > .cardb,
  #page-deal #v8-related,
  #page-deal #sec-terms{margin:0 0 12px}
  /* пустые контейнеры старого вида между вкладками и «Связанными» несут свои отступы (10px и два
     по 12px) и в сумме давали 34px щели вместо 12px — в новом виде они пусты, отступы им не нужны */
  #page-deal #v6-groups,
  #page-deal #v6-empty-row,
  #page-deal #v6-other,
  #page-deal #v6-extra{margin:0}
  
  /* ═══ [CARD-V8-ORDER-TERMS] Карточка «УСЛОВИЯ ОПЛАТЫ КЛИЕНТА» на ЭКРАНЕ ЗАКАЗА (#page-order
     #sec-terms — клон terms.orderClient, feature-order-v8.src.js). Тёзка на карточке закупки уже
     стилизован блоком [CARD-V8-TERMS-CARD] выше (этот файл:713-715) — те правила адресованы
     #sec-terms без страницы и достаются обоим; здесь только то, чего у экрана заказа не было.
  
     1. РИТМ И ПРИЦЕЛ ЯКОРЯ — как у соседних блоков заказа. источник значений: этот файл:730-738 и
     :755-757 (блок [CARD-V8-ORDER-LAYOUT]: поля 0 12px при row-gap:12px контейнера и
     scroll-margin-top:88px под свёрнутую шапку). Новый блок обязан попасть в тот же ритм, иначе он
     один прилипал бы к краям страницы. */
  #page-order > #sec-terms{margin:0 12px}
  #page-order #sec-terms{scroll-margin-top:88px}
  
  /* 2. ЖИВОЙ ОРГАН УСЛОВИЙ ВНУТРИ КАРТОЧКИ. Внутрь клона ПЕРЕМЕЩАЕТСЯ живой <details> старого вида
     (public/feature-kanban-card.src.js:1415) — он несёт СВОИ инлайн-стили (margin-top:10px у
     details, font-size:13px у summary и padding:6px 0 у #_fdTerms), а инлайн бьёт любую
     специфичность, поэтому !important законен (тот же довод, что у правил заказа выше, :252-262).
     Значение — ДЕЙСТВУЮЩЕЕ у эталона: 12px стоит в ПЕРВОМ слое, а поздний v8-scale:166 переопределяет
     .pt-doc на var(--fs-1) (11px) — берём победителя, иначе получаем размер вне продуктовой шкалы
     {11,13,15,17,19} и краснеет [TYPO-SCALE-CSS]. Верхний отступ снимаем: ритм внутри карточки
     задаёт сама .bd (v8-order.html .cardb .bd), а не орган. */
  #page-order #sec-terms > .bd > details{margin-top:8px !important}
  #page-order #sec-terms > .bd > details > summary{font-size:var(--fs-1) !important;line-height:var(--lh-1) !important}
  #page-order #sec-terms #_fdTerms{font-size:var(--fs-1) !important;line-height:var(--lh-1) !important}
  
  /* [ORDER-HERO-NOTE-TYPO] ПРАВИЛО СНЯТО 19.08. Финальная приёмка сообщила, что строка условий в
     шапке заказа «поехала» (13px/чёрная вместо 11px/серой), и я перенёс сюда значения из правила
     #sec-settle. Машинная сверка стилей это отвергла: у ЭТАЛОНА в шапке она именно 13px/20px и
     цвет --text (11px/серый — только внутри расчётов). Урок: авторитет — сверка вычисленных
     стилей, а не глазомер отчёта; своё правило лечило то, чего не было. */
  
  /* ═══ [CARD-V8-ORDER-PARTS] «ЧАСТИ ЗАКАЗА» — таблица движком эталона в #parts-box
     (feature-order-parts-v8.src.js: модель parts.engine + движок items.engine, строки из живого
     /split-group). Живой список продукта (._ordPartStage/._ordPartRow, его рисует
     public/feature-kanban-card.src.js:1345-1400) НЕ удаляется: ядро экрана заказа перемещает его
     органы внутрь #parts-box, по его чекбоксам ._fdRetChk живёт возврат части в заказ, и при откате
     вида ядро возвращает их домой по слотам. Поэтому список ПРЯЧЕТСЯ — ровно так же, как скрыт
     орган #v6-related внутри оболочки «Связанных» (этот файл:212, правило [CARD-V8-REL-TBL]).
     Прячем КАРМАН органов целиком: у строк списка display задан ИНЛАЙНОМ (display:flex), а
     скрытый родитель снимает вопрос о приоритете — детям правило уже не нужно. Скрыт только
     внутри блока частей: в классическом виде селектор не совпадает и список работает как раньше. */
  #page-order #sec-parts [data-v8-parts-organs]{display:none}
  
  /* ═══ [CARD-V8-ORDER-DOCK] ДОК НА ЭКРАНЕ ЗАКАЗА — та же панель, что на карточке ════════════════
     Разметка — тот же клон CardV8Tpl.dock, лента — тот же живой орган (#deal-right-main) с данными
     ГОЛОВЫ заказа (feature-order-dock-v8.src.js). Ниже — ТОЛЬКО раскладка колонки: сама панель
     (.dock/.dock-hd/.fchips/.fsearch/.act-scroll/.act-item) красится слоями эталона по классам.
  
     ПОЧЕМУ ПАНЕЛЬ ЛЕЖИТ РЯДОМ СО СТРАНИЦЕЙ, А НЕ ВНУТРИ НЕЁ: экран заказа перерисовывается целиком
     через innerHTML (_openFamilyDrawer, public/feature-kanban-card.src.js:1024) — живой орган ленты
     внутри #page-order сносило бы вместе с разметкой страницы. Поэтому док — сосед страниц в
     #main-content, а система координат ему — сам #main-content (как .wrap мокапа,
     v8-dock-css:19 «.wrap{position:relative;overflow:hidden}»).
     Ширина и уезд за край — значения эталона v8-dock-css:12 (--dock-w) и :22-24 (margin-right
     отрицательным полем + гашение opacity с --dock-anim). Класс dock-off у нас живёт на хосте
     колонок (у карточки это #deal-body, здесь #main-content) — каркасные правила body мокапа
     сборщик законно режет. */
  #main-content:has(> #v8-order-dock){position:relative}
  #main-content:has(> #v8-order-dock) > #page-order{padding-right:var(--dock-w)}
  #main-content.dock-off:has(> #v8-order-dock) > #page-order{padding-right:0}
  #v8-order-dock{position:absolute;top:0;right:0;bottom:0;z-index:30;
    width:var(--dock-w);display:flex;flex-direction:column;margin-right:0;visibility:visible;
    transition:margin-right var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s}
  /* закрытая панель заказа скрыта по-настоящему — тот же корень и то же лечение, что у панели
     карточки ([CARD-V8-DOCK-CLOSED-IS-HIDDEN]): без этого закрытая панель заказа стояла за правым
     краем окна (замер адаптива: order @1152 — 1152…1452) и оставалась в дереве доступности */
  #main-content.dock-off #v8-order-dock{margin-right:calc(-1 * var(--dock-w));
    opacity:0;pointer-events:none;visibility:hidden;
    transition:margin-right var(--dock-anim) cubic-bezier(.4,0,.2,1),opacity .18s ease,visibility 0s linear var(--dock-anim)}
  /* живой орган внутри дока заказа — те же правила, что у дока карточки (этот файл, [CARD-V8-DOCK]) */
  #v8-order-dock .act-scroll{flex:1;min-height:0;overflow-y:auto}
  #v8-order-dock #deal-right-main{display:flex;flex-direction:column;min-height:0}
  #v8-order-dock .feed-search{display:none}
  #v8-order-dock #deal-feed [style*="text-overflow: ellipsis"],
  #v8-order-dock #deal-feed [style*="text-overflow:ellipsis"]{
    white-space:normal!important;text-overflow:clip!important}
  @media (prefers-reduced-motion:reduce){
    #v8-order-dock{transition:none}
  }
  /* ═══ [CARD-V8-ORDER-DOCK-OVERLAY] На узком окне ТЕЛО ШИРИНУ НЕ ОТДАЁТ — правило эталона
     v8-dock-css.txt:54-63 (v8-purchase.html/v8-order.html css:1602-1613): «≤1152px панель работает
     ОВЕРЛЕЕМ поверх тела (тело ширину не отдаёт)». Порог 1152 = OVERLAY_W эталона, взят как есть.
     Панель заказа и так вне потока (position:absolute выше), но страница резервировала ей место
     отступом padding-right:var(--dock-w) — замер живого экрана заказа fafff6e5 на 1024: страница
     сжималась до 936−320=616px, тогда как эталон на той же ширине держит тело целым и кладёт
     панель сверху. Отступ снимается ТОЛЬКО в оверлейной зоне; шире 1152 место панели по-прежнему
     резервируется (эталон там тоже сжимает тело). Медиа-запрос стоит ПОСЛЕ базового правила
     отступа — иначе он был бы мёртвым. */
  @media (max-width:1152px){
    #main-content:has(> #v8-order-dock) > #page-order{padding-right:0}
  }
  
  /* ═══ [CARD-V8-FEED-ITEM] ЗАПИСЬ ЖИВОЙ ЛЕНТЫ, ПРИВЕДЁННАЯ К РАЗМЕТКЕ ЭТАЛОНА ═════════════════
     Строки ленты теперь несут имена эталона (.act-item > .ic/.bx/.who/.tm/.msg, .fc-old/.fc-new) —
     их красят слои мокапа. Здесь — только то, что нужно живому окружению:
     1) ЛЕНТА ЖИВЁТ В КОНТЕЙНЕРЕ ПРОДУКТА. Отступы записи у эталона даёт .act-scroll
        (v8-dock-css:57 «padding:2px 14px 8px»), а у нас внутри .act-scroll лежит живой орган со
        своим карманом #deal-feed — поля до края панели не доезжали. Повторяем значение эталона на
        живом кармане, чтобы запись стояла ровно там же, где в мокапе.
     2) У ЗАПИСИ НЕТ СВОЕГО ФОНА И РАМКИ. Живой орган красит примечание янтарной плашкой инлайном
        (public/feature-deal-feed.src.js:884 background/border/border-left) — при разметке эталона
        этот фон остаётся поверх .act-item. Инлайн бьётся только !important (тот же довод, что у
        правил заказа выше). Значения — из эталона: у .act-item фона и рамки нет вовсе
        (public/mockups/v8-purchase.html:223 «.act-item{display:flex;gap:9px;padding:6px 0}»). */
  .dock .act-scroll > #deal-right-main > #deal-feed{padding:2px 14px 8px}
  .act-item[data-v8-item]{background:none !important;border:0 !important;
    border-radius:0 !important;margin:0 !important}
  
  /* ═══ [ORDER-PAY-REGISTRY-V8] Живая таблица обязательств в блоке «РАСЧЁТЫ ПО ЦЕПОЧКЕ».
     У демо-модели мокапа было четыре состояния строки (ожидает/частично/закрыт/просрочен) — их
     чипы уже описаны выше этим же файлом. Живой реестр знает ещё ДВА, и оба — терминальные решения
     человека, а не расчёт: «замещён разбиением» и «отменён». Показывать их классом .open («ожидает»)
     значило бы соврать о состоянии, поэтому им дан свой класс, а ЗНАЧЕНИЯ взяты БЕЗ ИЗМЕНЕНИЙ у
     нейтрального чипа эталона — источник: public/mockups/v8-order.html:1736 (#sec-settle .st.open).
     Своих цветов не придумано: закрытая строка обязана выглядеть так же спокойно, как ожидающая. */
  #sec-settle .st.superseded,
  #sec-settle .st.cancelled{background:var(--surface3);color:var(--text2)}
  
  /* ═══ [CARD-V8-FIELD-CLAMP-EXPAND] МНОГОСТРОЧНАЯ КЛЕТКА СЖАТА ДО ОДНОЙ СТРОКИ, ПОЛНЫЙ ВИД — ПО КЛИКУ.
     ПОЧЕМУ ТАК, А НЕ «двухэтажной строкой по переполнению» из мокапа. Механизм эталона (relayoutFields:
     scrollWidth > clientWidth → класс .long) перенесён дословно и работает верно, но на ЖИВЫХ данных
     срабатывает у всех полей подряд, и строка прыгает с 48px до 109px — то есть возвращает жалобу
     владельца «поля во вкладках огромные». В мокапе этого не видно: там демо-значения короткие.
     Замер 19.08 на #34001950F-2: реально ОБРЕЗАННЫХ значений — 0, ни один текст не теряется; зато
     денежные клетки несут по четыре строки сразу (сумма, «0% от бюджета закупки», «предоплата по
     валютам», «0,00 USD = 0,00») и дают 89-109px против эталонных 49 — ритм формы ломают они.
     РЕШЕНИЕ ВЗЯТО У РЕФОВ (владелец 19.08: «делай как у рефов»). SAP Fiori, Wrapping and Truncation:
     длинное содержимое СЖИМАЕТСЯ, а полный текст показывается «expandable text» — раскрытием на месте,
     причём подсказка при наведении для этого ЯВНО не годится («do not use a tooltip to show the full
     text»), нужен способ увидеть всё ОДНИМ действием. Oracle JET форм-лейаут тоже даёт выбор
     «обрезать или переносить», а не переносит всё подряд.
     Итог: клетка держит одну строку (ритм 49px сохраняется), у сжатой появляется многоточие, клик по
     значению разворачивает её в ЭТАЛОННЫЙ двухэтажный вид (.fi.long — правило мокапа, не наша
     выдумка), повторный клик сворачивает. Разворачивать умеют только НЕредактируемые клетки: у
     правимых полей полный текст и так открывает редактор — то самое «одно действие». */
  /* Одна строка ЕСТЕСТВЕННОЙ высоты: line-clamp считает строки текста, а не пиксели, поэтому
     строка поля остаётся ровно эталонной (49px). Жёсткий max-height в em сжимал её до 44-45px —
     ритм ломался в другую сторону (замер 19.08). */
  .fi.clamped > .v{
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;
    overflow:hidden;position:relative}
  .fi.clamped > .v::after{
    content:'…';position:absolute;right:0;bottom:0;padding-left:10px;
    background:linear-gradient(90deg,transparent,var(--surface-card) 40%);color:var(--text3)}
  .fi.clamped.can-expand > .v{cursor:zoom-in}
  .fi.long.can-expand > .v{cursor:zoom-out}
  
  /* ═══ [V8-NO-LEGACY-TOPBAR] ЧУЖОЙ ПОЛОСЫ НАД ЭТАЛОННОЙ ШАПКОЙ БОЛЬШЕ НЕТ. ═══════════════════
     ЗАМЕР ДО ПРАВКИ: эталонная шапка мокапа начинается с Y=0, живая — с Y=87. Разницу давала
     полоса предыдущего вида: `.deal-hd` (кнопка «← Назад к воронке» 12px/500, номер записи,
     плашка этапа «Logistics ▾» с карандашом переименования) высотой 49px и `.deal-tabs`
     («Основное · Документы · Файлы · Письма · Товары 9») высотой 38px.
     ПОЧЕМУ ОНА ЛИШНЯЯ — ПО КОДУ ЭТАЛОНА, А НЕ НА ГЛАЗ. Состав страницы в public/mockups/
     v8-purchase.html: hero (crumb-line, hero-sub, hero-min) → sec-money → sec-items → sec-rel →
     sec-terms → sec-payment/sec-logistic/sec-info/sec-system → dock → feed → modal. Ни «Назад к
     воронке», ни «Основное», ни «Файлы», ни «Письма» в коде эталона не встречаются ни разу.
     ⛔ НИ ОДНА ФУНКЦИЯ НЕ ПОТЕРЯНА — все органы полосы получили живой адрес ДО скрытия:
       · «← Назад к воронке» → КРОШКИ шапки: «Сделки» и имя воронки стали живыми ссылками на
         доску (это путь наверх эталона; кнопка была вторым показом того же);
       · номер записи        → заголовок шапки (h1) — уже гасился правилом #page-deal #deal-num;
       · плашка этапа        → ЖИВОЙ #deal-stage-select переехал УЗЛОМ на место плашки .badge;
       · «(N дн.)» и теги    → переехали туда же, в .title-row шапки;
       · карандаш имени      → пункт «Переименовать» меню «Действия» (нажимает ту же кнопку);
       · вкладки разделов    → группа «Разделы» меню «Действия» (нажимает те же вкладки).
     ⛔ ЗЕРКАЛА НЕ ЗАДЕТЫ: весь файл действует только при html[data-card-v8], а на зеркальной
     воронке этот признак не ставится никогда ([MIRROR-KEEPS-CLASSIC]) — там полоса остаётся. */
  #page-deal .deal-hd{display:none}
  #page-deal .deal-tabs{display:none}
  /* ⛔ ВЫХОД ИЗ РАЗДЕЛА ОБЯЗАН БЫТЬ ВИДЕН. Разделы «Документы»/«Файлы»/«Письма» показываются
     ВМЕСТО тела карточки — вместе с телом уезжает и шапка, а с ней кнопка «Действия», которой
     человек в раздел ушёл. Поэтому пока открыт НЕ «Основное», полоса вкладок показывается: она
     и есть живой путь назад. На «Основном» (99% времени) её нет, и шапка стоит первой. */
  #page-deal .deal-left:has(> .deal-tab-content.active:not(#dtab-main)) .deal-tabs{display:flex}
  
  /* Живой селектор этапа носит вид эталонной плашки. Значения не выдуманы — это .badge мокапа:
     sales-css.txt:46 (border-radius:999px; display:inline-flex; align-items:center) +
     v8-scale.txt:16 (font-size:11px; font-weight:700; line-height:16px; padding:2px 8px; gap:4px) +
     v8-css.txt:528 (.badge.vio{background:var(--violet-bg);color:var(--violet)}).
     Стрелка «▾» — от живого органа: она честно говорит, что этап здесь МЕНЯЮТ (в мокапе плашка
     не редактируется, поэтому её там нет). */
  #page-deal .hero .title-row .stage-select{position:relative;display:inline-flex;flex-shrink:0}
  #page-deal .hero .title-row .stage-sel-btn{
    height:auto;padding:2px 8px;gap:4px;border:0;border-radius:999px;
    font-size:11px;font-weight:700;line-height:16px;letter-spacing:normal;
    background:var(--violet-bg);color:var(--violet);cursor:pointer;
    display:inline-flex;align-items:center;font-variant-numeric:tabular-nums}
  #page-deal .hero .title-row .stage-sel-btn:hover{background:var(--violet-bg);opacity:.85}
  /* «(N дн.)» и теги — второстепенные факты той же строки: тон подписи эталона (--text3, 11px) */
  #page-deal .hero .title-row #deal-stage-days{
    font-size:11px;line-height:16px;color:var(--text3);flex-shrink:0}
  #page-deal .hero .title-row #deal-tags{
    display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap;margin-left:0;min-width:0}
  #page-deal .hero .title-row #deal-tags .deal-tag{
    font-size:11px;line-height:16px;color:var(--text2);background:var(--surface3);
    border-radius:999px;padding:2px 8px;cursor:pointer}
  #page-deal .hero .title-row #deal-tags .deal-tag-input{
    font-size:11px;line-height:16px;color:var(--text3);background:transparent;border:0;
    width:64px;padding:2px 4px;font-family:inherit}
  
  /* Крошка-ссылка выглядит РОВНО как текст крошки эталона (цвет наследуется от .c-top), а
     подчёркивание появляется только под курсором — приём самого мокапа для .c-up (v8-purchase:493).
     ⛔ ЯКОРЕМ БЕРЁМ id ШАПКИ, а не «.hero .crumbs»: общее правило ссылок продукта
     (app-overrides.css:271 `a:not(.btn):not([role=button]):not(.deal-tab):not(.an-tab)`) весит
     четыре класса и молча красило крошку в синий — путь наверх переставал быть похож на эталон
     (замер 19.08: «Сделки» и «Sofcon» синие вместо --text3). Тот же приём уже применён к крошке
     «Заказ» выше в этом файле. */
  #v8-hero .crumbs a.c-nav,
  #v8-order-hero .crumbs a.c-nav{color:inherit;text-decoration:none}
  #v8-hero .crumbs a.c-nav:hover,
  #v8-order-hero .crumbs a.c-nav:hover{color:var(--accent);text-decoration:underline}
  
  /* ═══ [V8-SIDEBAR-ICON-RAIL] ЛЕВОЕ МЕНЮ — УЗКАЯ ПОЛОСА ИКОНОК, КАК В КОДЕ ЭТАЛОНА. ══════════
     ЗАМЕР ДО ПРАВКИ: у эталона содержимое начинается с X=56 (полоса `.sb` ровно 56px, только
     иконки, подписей нет), у нас — с X=88: меню несёт подписи «Поиск/Сделки/Задачи/Контакты/
     Компании/Товары/Поставщики/Аналитика/SOFCON OS/Scoreboard». Лишние 32px забираются у КАРТОЧКИ:
     она выходит уже эталонной на всю ширину экрана.
     ИСТОЧНИК ЗНАЧЕНИЙ — КОД МОКАПА, а не подбор:
       v8-purchase.html:39-47  .sb{width:56px; align-items:center; gap:2px}
       v8-purchase.html:1048   .sb{padding:8px 0}      (слой шкал — он последний, он и главный)
       v8-purchase.html:1050   .sb-btn{border-radius:6px}
       v8-purchase.html:1334   .sb-btn{padding:0}
     ⛔ ФУНКЦИИ НЕ ТЕРЯЮТСЯ. В эталоне у каждой иконки есть title («Поиск», «Сделки», …) — им и
     называется пункт, когда подписи нет. В живом меню title стоял лишь у трёх пунктов, поэтому
     девяти недостающим он дописан в разметке (sofcon_crm_v199_53.html) ИЗ ИХ ЖЕ ПОДПИСИ, вместе с
     aria-label — скринридер продолжает называть пункт вслух ([WCAG-4.1.2]). Ни один пункт не убран:
     те, которых в мокапе нет (Поставщики, SOFCON OS, Scoreboard, Настройки, Справка, Корзина),
     остаются иконками — эталон не перечисляет разделы продукта, он задаёт ФОРМУ полосы.
     ⛔ БЛАСТ-РАДИУС ОСОЗНАН: правило действует только при html[data-card-v8], то есть у человека,
     включившего вид по мокапу, и на всех его экранах разом — иначе полоса дёргалась бы шириной при
     каждом входе в карточку и выходе из неё. У остальных и на зеркальных сделках меню прежнее.
     Откат — тем же переключателем вида, без правки кода. */
  #sidebar.sb{width:56px;flex-shrink:0;padding:8px 0;gap:2px;align-items:center}
  /* min-height:58px базового правила (sofcon_crm_v199_53.html:321) заложен под ДВЕ строки
     «иконка + подпись»; подписи больше нет — снимаем и его, иначе кнопка остаётся 40×58 */
  #sidebar.sb .sb-btn{width:40px;height:40px;min-width:0;min-height:0;padding:0;border-radius:6px;
    display:flex;flex-direction:row;align-items:center;justify-content:center;gap:0}
  #sidebar.sb .sb-btn svg{width:19px;height:19px;flex-shrink:0}
  /* подпись уходит — её роль берёт на себя title/aria-label того же пункта */
  #sidebar.sb .sb-btn-lbl{display:none}
  /* счётчик просроченных не должен вылезать за 40px кнопки — прижимаем к её углу */
  #sidebar.sb .sb-btn{position:relative}
  #sidebar.sb .sb-badge{position:absolute;top:2px;right:2px;margin:0}
  /* разделители и пилюля пользователя — по ширине полосы, чтобы не распирали её обратно */
  #sidebar.sb .sb-sep{width:32px;margin:4px 0}
  #sidebar.sb .sb-user-pill{width:32px;height:32px;padding:0;border-radius:6px;
    min-width:0;font-size:13px;margin-bottom:8px}
  
  /* ═══ [V8-CT-PICK] ПАНЕЛЬ ВЫБОРА КОНТАКТА — ВИДНА, ПОКА ИДЁТ ВЫБОР. ═════════════════════════
     Чип «Контакт · + выбрать» эталона (v8-purchase:1946) открывает ЖИВУЮ панель контактов карточки
     (#deal-ct-area → #deal-ct-panel: поиск, создание, привязка через dealAttachCt → linkContactToDeal).
     Панель существует и работает, но каркас предыдущего вида гасит её насовсем правилом
     `#page-deal.v6-on #deal-ct-area{display:none!important}`. Показываем её ТОЛЬКО на время выбора:
     признак ставит и снимает сам чип ([V8-CT-PICK] в feature-deal-card-v8). Постоянно показывать
     блок нельзя — его в составе эталона нет. !important здесь обязателен: перебиваем !important. */
  #page-deal.v8-ct-pick #deal-ct-area{display:block !important}
  
  /* ═══ [CARD-ONE-FRAME] КАРТОЧКА — ЛИБО СКЕЛЕТ, ЛИБО ЦЕЛАЯ. ═══════════════════════════════════
     Жалоба владельца 21.08: «страница моргает секунд десять, открывая и сворачивая вкладки как
     будто». Блоки карточки строят РАЗНЫЕ модули от РАЗНЫХ ответов сервера, каждый своим тактом —
     и состав менялся 5-7 раз за первые 15 секунд загрузки. Пока барьер коммита держит признак
     html[data-card-assembling] (снимает его feature-deal-card-v8, когда ВСЕ дирижёры отчитались
     о готовности), содержимое карточки не показываем, а на его месте — скелет. САМО ТЕЛО ищем не по
     вшитому id, а по признаку data-card-body-busy: барьер ставит его на ЖИВОЙ узел, который назвал
     резолвер хозяина (_v8HeadHost().parentNode). Поверхностей две — с каркасом v6 (#v6-wrap) и без
     него (#dtab-main); правило, прибитое к #deal-sections, на второй не накрывало НИЧЕГО.
     ⛔ ПОЧЕМУ visibility, А НЕ display:none. Скрытый через display узел теряет размеры, и модули
     вида (их гейт — offsetParent/getClientRects) решили бы «карточка не на экране» и перестали
     строиться — барьер никогда бы не снялся. visibility оставляет вёрстку и размеры на месте:
     сборка идёт как обычно, человек её просто не видит. По той же причине не opacity: у неё узлы
     остаются кликабельными, и рука попадала бы в невидимые органы.
     ⛔ ПОЧЕМУ НЕ гасим тело ЦЕЛИКОМ: тогда пропал бы и сам скелет (::before
     наследует видимость своего хозяина). Гасим ДЕТЕЙ, псевдоэлемент остаётся видимым.
     Доступность: контейнеру ставится aria-busy="true" (WAI-ARIA busy region) — скринридер не читает
     полусобранное дерево; анимацию гасим при prefers-reduced-motion ([WCAG-2.3.3]). */
  :scope[data-card-assembling] [data-card-body-busy] > *{visibility:hidden}
  :scope[data-card-assembling] [data-card-body-busy]{position:relative;min-height:420px}
  :scope[data-card-assembling] [data-card-body-busy]::before{
    content:'';position:absolute;inset:0;display:block;border-radius:12px;
    background:
      linear-gradient(var(--card,#fff),var(--card,#fff)) 0 0/100% 92px no-repeat,
      linear-gradient(var(--card,#fff),var(--card,#fff)) 0 104px/100% 120px no-repeat,
      linear-gradient(var(--card,#fff),var(--card,#fff)) 0 236px/100% 180px no-repeat;
    box-shadow:none;opacity:.9;
    -webkit-mask-image:linear-gradient(#000,#000);mask-image:linear-gradient(#000,#000);
    animation:v8SkelPulse 1.4s ease-in-out infinite;
    border:1px solid var(--border,#e5e7eb);
  }
  @keyframes v8SkelPulse{0%,100%{opacity:.55}50%{opacity:.85}}
  @media (prefers-reduced-motion: reduce){
    :scope[data-card-assembling] [data-card-body-busy]::before{animation:none;opacity:.7}
  }
  
  /* ═══ слой: v8-a11y-css.txt ═══ */
  
  /* ══ WCAG 2.2 AA — слой доступности. Грузится ПОСЛЕДНИМ, чтобы перебивать любые слои выше.
     Каждый блок помечен номером критерия W3C: https://www.w3.org/TR/WCAG22/
     Правки сделаны по замерам audit/out-a11y.json + out-focus22.json, а не «на глаз». ══════ */
  
  /* ── 1.4.11 Non-text Contrast (AA) ────────────────────────────────────────────────────
     Граница ОРГАНА УПРАВЛЕНИЯ обязана давать ≥3:1 к соседнему фону. Замер до правки:
     --border #e5e7eb на белом = 1.24:1, --blue-bd #bfdbfe = 1.42:1 — обе провалены.
     Разделители/рамки карточек под критерий НЕ подпадают (это не орган управления) —
     поэтому --border не трогаем, вводим ОТДЕЛЬНУЮ переменную только для органов управления. */
  :root{ --border-ctl:#838a94 }   /* 3.48:1 на #fff, 3.23:1 на --bg #f6f7f9 — с запасом */
  
  .btn:not(.pri), button.chip, .ckind, .claim, .tcols, .h-on,
  select, textarea, input[type="text"], input[type="number"], input[type="date"],
  input[type="search"], input[type="time"], .compose textarea{
    border-color:var(--border-ctl)
  }
  /* .dock-btn и .dock-spine красятся своим правилом в слое дока — перебиваем адресно */
  #dock-btn.btn, .dock-btn, .dock-spine{ border-color:var(--border-ctl) }
  #demo-sel, #admin-btn, #tpl-btn, #ua-split, #comp{ border-color:var(--border-ctl) }
  /* эти три правила красились селекторами с id/двумя классами — перебиваем той же силой */
  #sec-settle .sfilt .chip{ border-color:var(--border-ctl) }
  .act-item.task-line .claim{ border-color:var(--border-ctl) }
  /* «тихая» ячейка-редактор: в покое рамки нет по замыслу, но как только рамка ПОЯВЛЯЕТСЯ
     (наведение/фокус) — она и есть граница органа управления, значит обязана дать 3:1.
     Было --border2 #b7bec9 = 1.87:1. */
  table.items tr:hover td.edc .edv, table.items td.edc .edv:focus-visible{ border-color:var(--border-ctl) }
  
  /* ── 2.4.13 Focus Appearance (AA) ─────────────────────────────────────────────────────
     Индикатор фокуса — контур ≥2 CSS-px и ≥3:1 между состояниями. Замер до правки:
     .compose textarea:focus и .dock-spine:focus-visible красились в --blue-bd = 1.42:1. */
  .compose textarea:focus, #comp:focus, #comp:focus-visible{
    outline:2px solid var(--accent); outline-offset:2px; border-color:var(--accent)
  }
  .dock-spine:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px }
  
  /* блок «Условия оплаты»: три органа управления красили фокус в --blue-bd.
     Замер: .pt-side-seg-b = 1.29:1 на дорожке #f3f4f6, .pt-sld = 1.42:1 на белом,
     а у #pt-inp был outline:0 и вообще НИ ОДНОГО собственного индикатора (2.4.7 Focus
     Visible, уровень A) — рамка-обёртка меняла --border2 → --accent, это 2.76:1, мимо. */
  .pt-side-seg-b:focus-visible{ outline:2px solid var(--accent); outline-offset:1px }
  .pt-sld:focus-visible{ outline:2px solid var(--accent); outline-offset:3px }
  #pt-inp:focus-visible{ outline:2px solid var(--accent); outline-offset:1px }
  .pt-inp-w:focus-within{ outline:2px solid var(--accent); outline-offset:2px; border-color:var(--accent) }
  
  /* редактируемые ячейки таблицы товаров — тот же класс дефекта: контур фокуса красился
     в --blue-bd #bfdbfe = 1.42:1 на белом (замер по 40 ячейкам на каждом экране). */
  table.items td.edc .edv:focus-visible{ outline:2px solid var(--accent); outline-offset:0 }
  
  /* ── 2.4.7 Focus Visible (уровень A!) ─────────────────────────────────────────────────
     Поиск по ленте: border:0 + outline:none — при переходе Tab фокус ПРОПАДАЛ совсем,
     человек без мыши не понимал, где он находится. Это провал уровня A, не AA. */
  #feed-q:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:6px }
  
  /* ── 2.5.8 Target Size (Minimum) (AA) ─────────────────────────────────────────────────
     Замер до правки: .hint-i = 21×20 px (axe target-size, 5 узлов в заказе, 3 в закупке).
     Растим до 24×24, не меняя визуальный размер знака — растёт только зона попадания. */
  .hint-i{
    min-width:24px; min-height:24px; padding:0;
    display:inline-flex; align-items:center; justify-content:center
  }
  /* Чекбокс задачи в ленте: визуально это квадрат 18×18 и таким он должен остаться —
     растим ЗОНУ ПОПАДАНИЯ невидимым слоем 24×24 поверх. 2.5.8 меряет именно зону,
     принимающую указатель, а не нарисованный квадрат. Ref: техника W3C C42. */
  .act-item .chk, .task-line .chk{ position:relative }
  .act-item .chk::after, .task-line .chk::after{
    content:''; position:absolute; left:50%; top:50%; width:24px; height:24px;
    transform:translate(-50%,-50%)
  }
  /* редактируемая ячейка таблицы: 22 px при высоте строки 31 px — 24 px влезают,
     строка от этого не вырастет (проверено замером высоты строки до/после) */
  table.items td.edc .edv{ min-height:24px }
  /* фильтр-чипы «Расчётов по цепочке» стали настоящими кнопками (см. 4.1.2) —
     а значит на них теперь распространяется 2.5.8: поднимаем высоту до 24 px */
  #sec-settle .sfilt .chip{
    min-height:24px; display:inline-flex; align-items:center;
    font-family:inherit; line-height:1
  }
  
  /* ── 4.1.2 Name, Role, Value (A) ──────────────────────────────────────────────────────
     Заголовок секции перестал быть role="button" (внутри него живут настоящие кнопки —
     вложенные интерактивные элементы, axe nested-interactive). Теперь раскрывалка —
     отдельная кнопка вокруг текста заголовка (паттерн ARIA APG Disclosure). */
  .cardb .hd .hd-tgl{
    all:unset; cursor:pointer; display:inline-flex; align-items:center; gap:7px;
    min-height:24px; font:inherit; color:inherit
  }
  .cardb .hd .hd-tgl:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:4px }
  .cardb .hd h3{ display:inline-flex; align-items:center }
  
  /* ── 2.4.1 Bypass Blocks (A) — ссылка «к содержимому», видна только с клавиатуры ────── */
  .skip-link{
    position:absolute; left:-9999px; top:0; z-index:9999;
    background:var(--surface); color:var(--accent); border:2px solid var(--accent);
    border-radius:6px; padding:8px 14px; font-weight:600; text-decoration:none
  }
  .skip-link:focus{ left:8px; top:8px; outline:2px solid var(--accent); outline-offset:2px }
}
