/* @ds-v23 — РАСШИРЕНИЕ DS V2.3 ДЛЯ ПРОДУКТА: ВЕСЬ «клей» экранов и оболочки в одном файле. Пишется руками (не порождается), только токены
   (линтер scripts/ds/lint-v23.mjs: ни одного литерала цвета/радиуса/кегля, в style="" — только --переменные). Подключён в index.html ОДИН раз,
   после components-v23.css. Прежние файлы (appr-layout.css, refs-layout.css, desk.css, ops.css, screens-v23.css, shell-v23.css) и их
   динамические подключения (ensureStyle / ensureLayoutCss / подключитьСтиль) убраны: экран не тянет свой стиль при монтировании.

   Устройство. Часть 1 — оболочка: собственные имена (.sidebar, .ctx-*, .cmdk-*, .shell23-*), НЕ обёрнута .ds23 — ровно как прежний shell-v23.css.
   Почему не в области: правила оболочки подобраны под специфичность БЕЗ `:scope` (внутри @scope каждое правило получает +1 к специфичности и
   перекроет правила DS там, где раньше проигрывало), а оболочка никогда не лежит внутри островка `.ds22`, так что предел `to (.ds22)` ей не нужен.
   ЛОВУШКА: при РАВНОЙ специфичности правило внутри @scope (DS) побеждает правило вне области (близость к корню области — раньше порядка
   в файле), поэтому правило оболочки, которое должно перебить DS, обязано быть ВЫШЕ по специфичности (см. `.m-top .ctx-slot .ctx-summary`).
   Часть 2 — экраны: под `@scope (.ds23) to (.ds22)`, как порождённый слой, поэтому в островок прежних экранов не попадает.

   Повтор — один класс, а не по классу на экран:  .gap-b / .gap-b-md / .gap-b-sm / .gap-t (отступы между блоками), .tabs-wrap (обёртка вкладок),
   .screen-toolbar (строка поиска и действий над таблицей), .row-wrap (ряд с переносом), .inline-form, .cols-2 / .cols-auto (колонки полей),
   .note-caption (пояснение мелким), .gap-spacer. Имена-«крючки» тестов (.dir-totals, .rep-banner, .a-close, .cal-bal…) сохранены, но без собственных
   отступов: отступ задаёт утилита рядом. Правило переноса длинных названий (бывший desk.css) — общее, не только для рабочего стола. */

/* ═══════════════ ЧАСТЬ 1 · ОБОЛОЧКА (public/screens/v23/shell-v23.js) ═══════════════ */

/* ── островок прежнего экрана внутри `main.page` (KEEP-экраны: прежний модуль, прежние стили под .ds22) ── */
.app[data-island] .page{padding:0;max-width:none;margin-inline:0}
/* корень экрана V2.3 внутри главной области (public/screens/v23/index.js «свой корень на каждый показ»): прозрачен для раскладки */
.shell23-screen{display:contents}
.shell23-island{flex:1 1 auto;min-height:0;min-width:0;display:flex;flex-direction:column;overflow:hidden}
.shell23-content,.shell23-main{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden}
/* телефон: страница прокручивается целиком (у S15 нет «рабочей области» фиксированной высоты) */
.m-main .shell23-island,.m-main .shell23-content,.m-main .shell23-main{display:block;overflow:visible}

/* ── слот полосы контекста: его дети — прямые участники flex-ряда полосы ── */
.ctx-slot{display:contents}
.m-top .ctx-slot{display:flex;align-items:center;min-width:0;flex:1 1 auto}
.ctx-crumbs{display:flex;align-items:center;gap:var(--space-3);min-width:0;color:var(--text-secondary);font:var(--type-label)}
.ctx-crumb-title{min-width:0;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-primary);font:var(--type-subsection)}
.ctx-primary{display:inline-flex}
.ctx-env{display:inline-flex}

/* ── боковая панель: подвал (меню пользователя) и группа «Ещё» ── */
/* дети панели не сжимаются: при низком окне панель прокручивается, а поиск и пункты не становятся 22 px высотой (измерено e2e:v22:vis) */
.sidebar>*,.sidebar .nav{flex:none}
.sidebar [data-foot]{margin-top:auto}
.sidebar .user-trigger{display:flex;align-items:center;gap:var(--space-5);width:100%;min-width:0;padding:var(--space-3);border-radius:var(--radius-md)}
.sidebar .user-trigger:hover{background:var(--action-secondary-hover)}
.sidebar .user-trigger .who{flex:1;min-width:0}
.sidebar .user-trigger .who b,.sidebar .user-trigger .who small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sidebar .user-menu{position:fixed;top:auto;right:auto;left:var(--pop-left,var(--space-6));bottom:var(--pop-bottom,var(--space-6));min-width:240px;z-index:var(--z-dropdown)}
.sidebar-note{margin:var(--space-6) var(--space-4) 0;color:var(--text-muted);font:var(--type-caption)}

/* «Ещё» — меню DS (.menu) рядом с пунктом: положение от пункта (--pop-*), высота — в пределах окна, длинный список прокручивается */
.sidebar .nav-more .nav-more-menu{position:fixed;top:var(--pop-top,var(--space-8));left:var(--pop-left,var(--layout-sidebar));right:auto;max-height:calc(100vh - var(--pop-top,var(--space-8)) - var(--space-6));overflow:auto;z-index:var(--z-dropdown)}
.sidebar [data-navgroup="more"] .nav-chev{margin-left:auto}
@media (max-width:767px){.sidebar .nav-more .nav-more-menu{left:var(--space-6);right:var(--space-6)}}
/* текущий экран лежит внутри свёрнутой «Ещё»: пункт отмечен, чтобы было видно, где человек */
.sidebar [data-navgroup="more"][data-has-current]{color:var(--text-primary)}

/* полоса значков (768–1279) */
@media (min-width:768px) and (max-width:1279px){
  .sidebar .user-trigger{justify-content:center;padding:var(--space-2)}
}

/* ── палитра Ctrl+K (окно DS «modal» + список пунктов меню) ── */
.cmdk-list{display:flex;flex-direction:column;gap:var(--space-1);margin-top:var(--space-4);max-height:min(50vh,420px);overflow:auto}
.cmdk-item{justify-content:space-between}
.cmdk-item[aria-selected="true"]{background:var(--action-secondary-hover)}
.cmdk-group{color:var(--text-muted);font:var(--type-caption)}
.cmdk-empty{padding:var(--space-6);color:var(--text-muted);font:var(--type-body)}

/* ── телефон: сводка полосы контекста живёт в верхней полосе S15 (.m-top), а не в .ctxbar —
   правило DS показывает её только внутри .ctxbar, и на телефоне контекст был скрыт (DEFECT-2 полосы desk) ── */
/* специфичность на ступень выше DS (`:scope .ctx-summary{display:none}` = 0,2,0): правило ВНЕ области при равной специфичности проигрывает правилу внутри @scope
   (близость к корню области идёт раньше порядка в файле) — e2e отчётов на 390 px: кнопка контекста была в DOM, но невидима */
.m-top .ctx-slot .ctx-summary{display:inline-flex}

/* ═══════════════ ЧАСТЬ 2 · ЭКРАНЫ (всё под .ds23, вне островка .ds22) ═══════════════ */
@scope (.ds23) to (.ds22){

/* ── метка «неполная», когда она ссылка (ведёт в набор операций): цель нажатия не меньше --target-min (WCAG 2.5.8) — была 170×18 на столах
   (найдено e2e 91, 02.10.2026). Только ссылка: метка-текст внутри предложения под правило не попадает. ── */
:scope a.incomplete{min-height:var(--target-min);align-items:center}

/* ── телефон: экран с панелью действий (.m-bar — решение по заявке, операция) прячет нижние вкладки: обе закреплены снизу на одном
   z-index, и вкладки перекрывали «Согласовать / Вернуть / Отклонить» (найдено e2e потока G, 02.10.2026). Канон m-approval.html: вкладок нет. ── */
:scope :has(.m-bar) .m-tabs{display:none}

/* ── общие раскладочные классы (один на повторяющийся приём) ── */
/* отступ ПОД блоком: между панелью/пояснением/итогами и следующим блоком (layout-gap — между блоками, md/sm — внутри секции) */
:scope .gap-b{margin-bottom:var(--layout-gap)}
:scope .gap-b-md{margin-bottom:var(--space-6)}
:scope .gap-b-sm{margin-bottom:var(--space-5)}
:scope .gap-t{margin-top:var(--layout-gap)}
/* flex:none — страница в оболочке «panes» — flex-колонка фиксированной высоты: пустой спейсер с умолчательным flex-shrink
   сжимался до 0, и карточки календаря слипались (замерено в браузере: 20px в <body>, 0px в main.page; фаза 3) */
:scope .gap-spacer{height:var(--layout-gap);flex:none}
/*
 * ОБОЛОЧКА «panes» БЕЗ ПРОКРУЧИВАЕМОЙ ПАНЕЛИ (фаза 3, замер в браузере на 1440×900). DS задумывал panes как «рабочая панель
 * тянется и прокручивается внутри» (`.pane-panel > .pane-scroll`), но ни один экран V2.3 эту панель не использует: страница —
 * flex-колонка с `overflow:hidden`, и всё, что выше окна, ОБРЕЗАЛОСЬ без прокрутки. Измерено: «Платёжный календарь» выше
 * окна на 1033 px, колесо не двигает ничего (недели сетки и список платежей недостижимы); П&У — 132 px. Тот же корень у
 * слипшихся карточек и пропавших вкладок «Внимания»: элементы с overflow≠visible (`.tabs-wrap`) сжимались до 0.
 * Лечение — то, что DS уже делает для `fixed`: страница прокручивается сама, блоки экрана не сжимаются. Островок прежнего
 * экрана (растягивается и прокручивается внутри) не трогается.
 */
:scope .app[data-shell=panes] .page{overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
:scope .app[data-shell=panes] .shell23-screen>*{flex-shrink:0}
/* обёртка вкладок: на узком экране вкладки прокручиваются, а не выдавливают страницу */
:scope .tabs-wrap{margin-bottom:var(--space-5);max-width:100%;overflow-x:auto}
/* строка поиска и действий над таблицей/списком: поиск слева, кнопки справа (.grow раздвигает) */
:scope .screen-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-5);margin-bottom:var(--space-5);min-width:0}
:scope .screen-toolbar .grow{flex:1 1 auto}
/* внутри панели: с полями панели, а не вплотную к её краю; панель и строка под ней не слипаются */
:scope .panel .screen-toolbar{padding:var(--space-4) var(--panel-padding);margin-bottom:0}
:scope .panel + .screen-toolbar{margin-top:var(--space-6)}
/* ряд с переносом: кнопки действий, фильтры, «назад» */
:scope .row-wrap{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-4);min-width:0}
:scope .inline-form{margin-bottom:var(--space-4)}
:scope .inline-form .input{flex:1 1 220px;min-width:0}
/* два столбца полей (окна, права, реквизиты), на телефоне — один; .cols-auto — сколько влезет по 220 px */
:scope .cols-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5)}
:scope .cols-auto{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--space-4) var(--space-6)}
@media (max-width:767px){:scope .cols-2{grid-template-columns:minmax(0,1fr)}}
/* телефон (ревью B, фаза 3): ящик меню — по видимой высоте окна (`100vh` мобильного браузера выше видимой области, подвал с
   «Профиль / Выйти» уходил под адресную строку); у телефонной оболочки нет `.app`, где DS ставит `--sticky-top`, — без него
   отчёт терял собственную прокрутку и липкую шапку месяцев */
@media (max-width:767px){
  :scope .sidebar{height:auto;max-height:100dvh}
  :scope .m-shell{--sticky-top:0px}
}

/* пояснение мелким приглушённым; .note-block — отдельной строкой (план и остаток в ячейке календаря) */
:scope .note-caption{font:var(--type-caption);color:var(--text-muted)}
:scope .note-block{display:block}
/* длинные названия (счёт, контрагент, решение) переносятся, а не растягивают строку и не дают горизонтальную прокрутку на 390/360 */
:scope .strip-line .t,:scope .decision-title,:scope .line-row-main .a,:scope .pay-text .a{overflow-wrap:anywhere;white-space:normal;min-width:0}
/* списки выбора и комментарии */
:scope .pick-list{max-height:calc(var(--control-md) * 8);overflow:auto}
:scope .comments{list-style:none;padding:0;margin:0}
:scope .inline-error{color:var(--negative-strong);font:var(--type-caption);margin:var(--space-3) 0 0}

/* ── «Требует внимания» и «Согласование платежей» (десктоп и телефон) ── */
:scope .ap-grid{display:grid;grid-template-columns:minmax(360px,440px) minmax(0,1fr);gap:var(--layout-gap);align-items:start}
:scope .ap-detail{display:flex;flex-direction:column;gap:var(--space-5);min-width:0}
:scope .ap-confirm{min-width:0}
@media (max-width:1279px){:scope .ap-grid{grid-template-columns:minmax(0,1fr)}}
:scope .appr-pairs{list-style:none;margin:var(--space-3) 0 0;padding:0}
:scope .appr-pairs li{display:flex;justify-content:space-between;align-items:center;gap:var(--space-5);padding:var(--space-3) 0;border-top:1px solid var(--border);font:var(--type-body)}
:scope .appr-pairs li:first-child{border-top:0}
:scope .appr-pairs small{display:block;font:var(--type-caption);color:var(--text-muted)}
:scope .appr-events{list-style:none;margin:var(--space-3) 0 0;padding:0}
:scope .appr-events li{padding:var(--space-3) 0;border-top:1px solid var(--border);font:var(--type-caption)}
:scope .appr-flags{display:flex;flex-direction:column;gap:var(--space-3)}
:scope .appr-sections{display:flex;flex-direction:column;gap:var(--space-4)}
:scope .appr-radios{display:flex;flex-direction:column;gap:var(--space-2);margin-bottom:var(--space-5)}
:scope .appr-users{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-6)}
/* телефон: заголовок пункта — кнопка-открывалка листа (всё, кроме основного действия, — во втором уровне) */
:scope .appr-open{all:unset;box-sizing:border-box;cursor:pointer;display:block;min-height:var(--target-min);text-align:left;font:inherit;color:inherit}
:scope .appr-open:focus-visible{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)}
:scope .appr-batch{position:sticky;bottom:0;padding:var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom));background:var(--surface);border-top:1px solid var(--border);display:flex;flex-direction:column;gap:var(--space-3)}

/* ── справочники: счета, контрагенты, настройки, кабинет поставщика ── */
:scope .d-wizard{display:grid;grid-template-columns:minmax(0,1fr) var(--layout-rail);gap:var(--layout-gap);align-items:start}
@media (max-width:1279px){:scope .d-wizard{grid-template-columns:minmax(0,1fr)}}
:scope .refs-inline-error{margin-bottom:var(--space-4)}
:scope .refs-links{display:flex;flex-wrap:wrap;gap:var(--space-3) var(--space-5);margin-top:var(--space-4)}
:scope .refs-h{margin:var(--space-5) 0 var(--space-2);font:var(--type-label);color:var(--text-muted)}
/* очередь «Требует действия» кабинета поставщика: пункты внутри панели с её полями */
:scope .fra-list{display:grid;gap:var(--space-5);padding:var(--space-5) var(--panel-padding)}

/* ── рабочий стол ── */
:scope .a-process{padding:var(--space-6) var(--panel-padding) var(--space-5)}
:scope .a-close{gap:var(--space-5);flex-wrap:wrap;align-items:center}
:scope .a-close-reason{flex:1 1 320px}
:scope .a-acc-flag{display:block;margin-top:var(--space-1)}

/* ── операции ── */
:scope .ops-bar{display:flex;align-items:center;gap:var(--space-2) var(--space-6);margin-bottom:var(--space-2);flex-wrap:wrap;min-width:0}
:scope .ops-totals{margin-left:auto;min-width:0}
:scope .ops-toolbar{display:flex;flex-direction:column;gap:var(--space-4);margin-bottom:var(--space-2)}
:scope .ops-tb-row .search-field{flex:0 1 170px;min-width:150px}
:scope .ops-more{display:flex;align-items:center;justify-content:center;gap:var(--space-5);padding:var(--space-4) var(--layout-gutter);flex-wrap:wrap}
:scope .ops-more:empty{display:none}
@media (max-width:767px){:scope .ops-totals{margin-left:0}}
/* инспектор: пять вкладок помещаются в ширину панели (DS-отступ 12px × 5 выдавливал «История» за край); поиск контрагента — не растягивается по высоте колонки */
:scope #ops-insp .inspector-tabs .tabs{display:flex;width:100%}
:scope #ops-insp .inspector-tabs .tab{flex:1 1 auto;padding:0 var(--space-4)}
:scope [data-cp-field] .search-field{flex:0 0 auto;max-width:none}

/* ── семейство отчётов (П&У, ДДС, баланс) и платёжный календарь ── */
:scope .rep-cell{border-bottom-color:transparent}
/* REPORT_HEATMAP / CELL_INTENSITY (DS-ADDITIONS.md): необязательный вид отчёта, по умолчанию выключен. Шкала НЕСИГНАЛЬНАЯ —
   нейтральный --chart-neutral, пять ступеней по модулю; ни зелёного, ни красного (они заняты смыслом «хорошо/плохо»), число не перекрашивается. */
:scope .cell-intensity{position:relative;isolation:isolate;border-radius:var(--radius-sm);padding-inline:var(--space-1)}
:scope .cell-intensity::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--chart-neutral);opacity:0}
:scope .cell-intensity[data-intensity="1"]::before{opacity:.12}
:scope .cell-intensity[data-intensity="2"]::before{opacity:.20}
:scope .cell-intensity[data-intensity="3"]::before{opacity:.28}
:scope .cell-intensity[data-intensity="4"]::before{opacity:.36}
:scope .cell-intensity[data-intensity="5"]::before{opacity:.44}
:scope .cal-plan{cursor:grab}

}
