/* Серый — основная тема, с 1 сентября 2026.
 *
 * Была холодная: во всех серых намешан синий (#16171b против нейтрального
 * #1a1a1a). Рядом с фотографией это заметно — глаз принимает холодный
 * интерфейс за точку отсчёта и видит на снимке лишнее тепло. Для программы,
 * в которой каждый день лежат визуализации и снимки, это прямая помеха, а не
 * вкусовщина. Холодная осталась выбором в настройках.
 *
 * Цвета холста — линейки, клетка прозрачности, фон полотна — читают эти же
 * переменные и потому меняются вместе с темой (`uiColor` в view.js). Пока они
 * были зашиты числами, в серой теме линейка и клетка оставались синеватыми:
 * ровно то, на что жаловался владелец.
 */
:root {
  --bg: #1a1a1a;
  --panel: #212121;
  --panel-2: #2b2b2b;
  --line: #383838;
  --text: #e8e8e8;
  --muted: #9e9e9e;
  /* Полотно вокруг листов и клетка прозрачности внутри листа без фона.
     Отдельными переменными, а не «чуть темнее панели»: холст рисуется на
     canvas, где вычислять оттенки неоткуда */
  --stage: #151515;
  --checker-a: #1e1e1e;
  --checker-b: #262626;
  --ruler-bg: #212121;
  --ruler-line: #383838;
  --ruler-text: #9e9e9e;
  --ruler-tick: #565656;
  /* Наведение на кнопку, полосы прокрутки и мелкая клетка прозрачности в
     значках. Всё это было записано числами и в серой теме отдавало синим */
  --hover: #2e2e2e;
  --scroll: #4a4a4a;
  --scroll-hover: #5c5c5c;
  --chip-a: #2b2b2b;
  --chip-b: #343434;
  --accent: #4f8cff;
  --accent-2: #3a76e8;
  --danger: #ff5c5c;
  --radius: 9px;
  --toolbar-h: 52px;
  /* Насколько плавающая панель инструментов поднята над нижним краем холста.
     Прежде было 18 px, и панель почти лежала на кромке. Владелец 27 августа:
     поднять примерно на высоту прежней полосы состояния — той, что шла во всю
     ширину и занимала 28 px. 18 + 28 = 46.
     Число одно на всю стопку: под панелью ничего нет, над ней свойства
     инструмента, и считаются они отсюда же — иначе разъедутся при первой же
     правке.

     29 августа владелец попросил убрать треть: 46 → 32. Полотна стало видно
     больше, а панель по-прежнему не лежит на кромке. */
  --bar-lift: 32px;
  --bar-h: 52px;      /* высота самой панели: от неё отсчитывается всё, что выше */
  font-synthesis-weight: none;
}

/* Холодная тема — прежнее умолчание, теперь выбор. Меняются только серые:
   акцент, опасность и радиусы общие. */
:root[data-ui="blue"] {
  --bg: #16171b;
  --panel: #1e2026;
  --panel-2: #24262e;
  --line: #32353f;
  --text: #e7e9ee;
  --muted: #9aa0ad;
  --stage: #101216;
  --checker-a: #17181d;
  --checker-b: #1f2127;
  --ruler-bg: #1e2026;
  --ruler-line: #32353f;
  --ruler-text: #8b93a5;
  --ruler-tick: #4a4f5e;
  --hover: #2c2f39;
  --scroll: #3c4150;
  --scroll-hover: #4a5062;
  --chip-a: #22252c;
  --chip-b: #2a2d36;
}

/* Серый посветлее — тот же нейтральный ряд, поднятый на пару ступеней.
   Нужен при ярком свете в комнате: на тёмном интерфейсе днём у окна не видно
   границ панелей, и вся левая колонка сливается в одно пятно. Поднимаются
   только фоны и линии; текст чуть притушен, иначе на светлом фоне он бьёт по
   глазам. Просьба владельца, 31 августа. */
:root[data-ui="gray-light"] {
  --bg: #2a2a2a;
  --panel: #333333;
  --panel-2: #3d3d3d;
  --line: #4a4a4a;
  --text: #ededed;
  --muted: #a8a8a8;
  --stage: #242424;
  --checker-a: #2f2f2f;
  --checker-b: #383838;
  --ruler-bg: #333333;
  --ruler-line: #4a4a4a;
  --ruler-text: #a8a8a8;
  --ruler-tick: #6a6a6a;
  --hover: #3f3f3f;
  --scroll: #5a5a5a;
  --scroll-hover: #6c6c6c;
  --chip-a: #3a3a3a;
  --chip-b: #444444;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; overflow: hidden; }
body {
  background: var(--bg);
  color: var(--text);
  font: 13px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  -webkit-user-select: none;
  user-select: none;
}

/* `relative` — ради плавающих палитр: они стоят абсолютно внутри #app, и
   отсчитываются от него, а не от окна (см. `.panel-float` ниже). */
#app { position: relative; display: flex; flex-direction: column; height: 100%; }

/* Прежняя верхняя панель звалась `.toolbar`, и её правила остались здесь
   мёртвым грузом: сама панель давно `.topbar` и стилей у неё своих хватает.
   Мёртвыми они были ровно до того дня, когда панель инструментов переехала
   вниз и получила тот же класс, — и тут же начали течь в неё:

     height    — плавающая панель получала высоту прежней верхней;
     border-bottom — под ней рисовалась лишняя черта;
     app-region: drag — в настольной версии перетаскивание панели
                        инструментов тащило за собой всё окно.

   Убрано 27 августа 2026. От блока осталась одна строка, которая и правда
   нужна другому: распорка в полосе состояния. */

.btn {
  -webkit-app-region: no-drag;
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 10px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid transparent; border-radius: var(--radius);
  font: inherit; font-weight: 500; cursor: pointer; white-space: nowrap;
}
.btn:hover { background: var(--hover); }
.btn:active { transform: translateY(1px); }
.btn.icon { padding: 0; width: 30px; justify-content: center; }
.btn.small { height: 26px; padding: 0 9px; font-size: 12.5px; border-radius: 7px; gap: 5px; }
.btn.small.icon { width: 26px; padding: 0; }
.btn.small svg { width: 17px; height: 17px; }
.btn svg { width: 20px; height: 20px; flex: 0 0 auto; }
.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-2); }
.btn.danger { background: #3a2226; color: #ffb3b3; }
.btn.danger:hover { background: #4a2a2f; }
.btn.active { background: var(--accent); color: #fff; }
.btn[disabled] { opacity: .38; pointer-events: none; }

/* ---------------------------------- Холст ---------------------------------- */
main { flex: 1 1 auto; display: flex; min-height: 0; }
#stage {
  position: relative; flex: 1 1 auto; min-width: 0;
  overflow: hidden;
  /* Ровный фон, а не клетка: клетка отвечает за «здесь ничего нет» и живёт
     теперь только внутри листа без фона (см. `checkerPattern` в view.js).
     Виден он до первой отрисовки холста — то есть на стартовом окне, — и
     синеватая клетка там оставалась даже в серой теме */
  background: var(--stage);
  cursor: default;
}
#canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Поповер с дополнительными фигурами */
.popwrap { position: relative; }
.popwrap .chev { width: 10px; height: 10px; margin-left: -4px; opacity: .7; }
#shapes-btn { width: 40px; }
.popover {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  display: flex; gap: 4px; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0,0,0,.5);
}
.popover.hidden { display: none; }

/* Пресеты фильтров */
.presets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 8px; }
.preset {
  cursor: pointer; border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: var(--panel-2); padding: 0 0 3px;
}
.preset.active { border-color: var(--accent); }
.preset canvas { display: block; width: 100%; height: 42px; object-fit: cover; }
.preset span { display: block; font-size: 12px; color: var(--muted); text-align: center; padding-top: 2px; }

/* Раскрывающиеся блоки «Ещё» */
details.more { margin-top: 10px; }
details.more > summary {
  cursor: pointer; list-style: none; color: var(--muted); font-size: 12.5px;
  padding: 6px 0; user-select: none;
}
details.more[open] > summary { margin-bottom: 6px; }
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::before { content: '▸ '; }
details.more[open] > summary::before { content: '▾ '; }
.rowbtns { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
/* Число у ползунка теперь поле ввода, а не подпись: его набирают с
   клавиатуры. Выглядеть оно должно по-прежнему подписью — рамка появляется
   только под курсором и при наборе, иначе в панели свойств рябило бы от
   десятка рамок. */
.slider-val {
  flex: 0 0 46px; width: 46px; text-align: right;
  color: var(--muted); font: inherit; font-size: 12px;
  background: none; border: 1px solid transparent; border-radius: 5px;
  padding: 1px 4px; cursor: text;
}
.slider-val:hover { border-color: var(--line); }
.slider-val:focus { outline: none; border-color: var(--accent); color: var(--fg, #e8eaf0); background: var(--panel-2); }

/* Поле правки имени страницы — поверх подписи, в её же месте */
.frame-rename {
  position: absolute; z-index: 8;
  height: 22px; padding: 0 6px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--accent); border-radius: 5px;
  font: inherit; font-size: 12px;
}
.frame-rename:focus { outline: none; }

#stage.drag-over { outline: 2px dashed var(--accent); outline-offset: -8px; }

.floating-bar {
  position: absolute; left: 50%; bottom: var(--bar-lift); transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; white-space: nowrap;
  max-width: calc(100% - 32px);
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 8px 10px; box-shadow: 0 10px 30px rgba(0,0,0,.45);
}
.floating-bar.hidden { display: none; }
.floating-bar span { color: var(--muted); margin-right: 4px; }


/* --------------------------------- Панель ---------------------------------- */
#props-legacy-unused {
  flex: 0 0 286px; width: 286px;
  background: var(--panel); border-left: 1px solid var(--line);
  overflow-y: auto; overflow-x: hidden;   /* вбок панель не прокручивается никогда */
  padding: 14px 14px 32px;
}
/* Колонки должны уметь сжиматься: обычный 1fr не уже своего содержимого */
#props .grid2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
#props .presets { grid-template-columns: repeat(4, minmax(0, 1fr)); }
#props .row, #props .rowbtns { min-width: 0; }
/* Длинная надпись переносится, а не вылезает за край */
/* Кнопка в колонке — того же роста, что и поле рядом (26), иначе ряд
   «Заливка · Обводка» стоит ступенькой. Текст 12.5, как у `.btn.small`:
   так «На передний» и «Дублировать» перестают переноситься на две строки
   в узкой колонке, то есть мелкий шрифт здесь ещё и экономит строку */
#props .btn {
  white-space: normal; line-height: 1.15; min-height: 26px; height: auto;
  padding: 4px 8px; font-size: 12.5px;
  justify-content: center; text-align: center; min-width: 0;
}
#props .btn.small { min-height: 26px; }
#props .rowbtns .btn { flex: 0 1 auto; }
#props select.field, #props input.field { max-width: 100%; }
/* Отбивка секции 14 → 10. Секций в свойствах фигуры три, у картинки до шести,
   и каждая платит дважды — снизу своим отступом и сверху отступом соседа */
#props .section { margin-bottom: 0; padding-bottom: 10px; }
#props .section + .section { border-top: 1px solid var(--line); padding-top: 10px; }
#props .section > *:last-child { margin-bottom: 0; }
/* Галочка прямо в разделе — такая же строка, как поле рядом. Без отбивки она
   липла к следующему ряду: до 1 сентября 2026 галочки жили только внутри
   свёртков, где снизу и так был воздух. */
#props .section > .toggle { margin-bottom: 8px; }
#props h3 {
  margin: 0 0 7px; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted); font-weight: 700;
}
/* Свёрнутый раздел (`foldSection` в ui/props.js): заголовок тот же, что у
   обычного раздела, — человек ищет глазами имя, а не серую строчку «ещё».
   Треугольник рисуем сами: браузерный маркер встаёт над заголовком. */
#props .section.fold > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; gap: 6px;
}
#props .section.fold > summary::-webkit-details-marker { display: none; }
#props .section.fold > summary::before {
  content: '▸'; color: var(--muted); font-size: 10px; line-height: 1;
}
#props .section.fold[open] > summary::before { content: '▾'; }
#props .section.fold > summary > h3 { margin: 0; }
#props .section.fold[open] > summary > h3 { margin-bottom: 0; }
#props .section.fold[open] > summary { margin-bottom: 7px; }
.row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.row.wrap { flex-wrap: wrap; }
/* Подпись не переносится посреди фразы: лучше подрезать хвост многоточием,
   чем показать «Ширина,» и «px» на двух строках */
.row label {
  flex: 0 1 82px; min-width: 0; color: var(--muted); font-size: 12.5px; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* `min-height` не украшение, а страховка от `flex-basis: 0`.
   Запись `flex: 1 1 0` сделана ради ширины: в строке поле занимает всё
   свободное место. Но как только строка оказывается вертикальной — а такие
   у нас есть и в окне создания, и в свойствах, — та же запись читается как
   «расти в высоту от нуля», и поле схлопывается до 19 px при положенных
   тридцати. Владелец 27 августа: «поля очень широкие и очень в высоту
   маленькие» — это оно и было, обе половины жалобы от одной строки. */
.field {
  /* `min-width` — не косметика: в узкой колонке подпись и поле сжимались
     поровну, и «Размер» со списком форматов оставался шириной в 65 точек, где
     «A4 альбомный» не помещался вовсе. Подпись умеет обрезаться многоточием,
     поле — нет, поэтому уступает первой она. */
  flex: 1 1 0; min-width: 92px; height: 30px; min-height: 30px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 7px; padding: 0 8px;
  font: inherit;
}
.field:focus { outline: none; border-color: var(--accent); }
select.field { padding-left: 5px; }
textarea.field { height: 68px; padding: 6px 8px; resize: vertical; line-height: 1.35; }
input[type=range].field { padding: 0; border: 0; background: transparent; }
input[type=color] {
  width: 34px; height: 30px; padding: 0; border: 1px solid var(--line);
  border-radius: 7px; background: var(--panel-2); cursor: pointer;
}
.hintline { color: var(--muted); font-size: 12.5px; line-height: 1.5; margin-bottom: 8px; }
/* Подзаголовок внутри секции свойств: у группы кнопок есть своё имя, но своей
   секции она не заслуживает. Заведён под подгонку изображения — «во фрейме» и
   «по странице» это две разные работы, и различаться они должны словом, а не
   памятью человека о том, какая кнопка что делает. */
.sublabel {
  color: var(--muted); font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; margin: 2px 0 6px;
}
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
/* Ряд значков вместо выпадающего списка.
   Список прячет варианты за щелчком, и человек про них просто не знает: лассо,
   овал и палочка лежали в нём годами, а владелец 1 сентября 2026 дважды
   написал, что выделения лассом в программе нет. Ряд показывает всё сразу и
   заодно говорит, что выбрано, — так устроена полоса опций в Photoshop. */
/* Кисточка выбирается по рисунку, а не по слову.
   Столбик нарисованных мазков — так это устроено в Фигме, и владелец
   1 сентября 2026 показал его как образец: «листом» и «клином» отличаются
   одной буквой в слове и всем в рисунке. */
.tip-peek { display: block; }
.tip-wrap { display: flex; }
.tip-btn {
  display: flex; align-items: center; gap: 2px; height: 26px; padding: 0 4px 0 2px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
}
.tip-btn .chev { width: 10px; height: 10px; opacity: .7; }
/* Всплывающие списки полосы опций живут В САМОМ НИЗУ ДОКУМЕНТА и ставятся по
   месту кнопки: полоса прокручивается по горизонтали, а прокрутка обрезает всё,
   что вылезло за её края. Из-за этого выбор кисточки не работал вовсе — список
   рождался внутри полосы и лишь мелькал. Владелец 1 сентября 2026. */
.pop-float {
  position: fixed; z-index: 60; top: 0; left: 0;
  flex-direction: column; gap: 1px; padding: 4px;
  max-height: min(360px, 70vh); overflow-y: auto;
}
.tip-pop { min-width: 148px; }
/* Список всех открытых проектов: вкладок бывает больше, чем помещается */
.tabs-pop { min-width: 200px; }
/* Кнопка стоит СРАЗУ ЗА ЛЕНТОЙ и появляется, только когда вкладки перестали
   помещаться. Раньше она висела там всегда — голая галочка посреди пустого
   места, которую принимали за часть ленты. Владелец 2 сентября 2026: «должна
   быть более явной и появляться справа, когда уже не помещаются вкладки».
   «Справа» с 4 сентября 2026 значит «справа от вкладок»: отдельной полосы,
   у правого края которой она стояла, больше нет — вкладки живут в середине
   шапки, и правый край ленты и есть их правый край (п. 77A). */
.tab-list {
  flex: 0 0 auto; align-self: center;
  display: flex; align-items: center; gap: 5px;
  height: 21px; padding: 0 7px; margin-left: 6px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel-2); color: var(--muted);
  font-size: 12px; line-height: 1; cursor: pointer;
}
.tab-list:hover { color: var(--text); border-color: var(--accent); }
.tab-list .chev { font-size: 11px; opacity: .8; }
.brush-pop { min-width: 232px; }
.pop-rows { display: flex; flex-direction: column; gap: 6px; padding: 2px; }
.pop-rows .row { margin: 0; }
.tip-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 4px 6px; border: 0; border-radius: 7px;
  background: transparent; color: var(--text); cursor: pointer; text-align: left;
}
.tip-item:hover { background: var(--hover); }
.tip-item.active { background: var(--accent); color: #fff; }
.tip-name { font-size: 11.5px; }

/* Набор отпечатков: сетка нарисованных штрихов, а не список имён.
   Владелец 2 сентября 2026: «ищу интуитивные переключатели, а они закопаны в
   параметрах. Хочу как в Photoshop». В Photoshop набор кистей — именно сетка
   образцов, и выбирают в ней глазами. Две колонки, а не одна: образец широкий,
   и столбиком из девяти встроенных набор уехал бы за край экрана. */
/* Набор выше обычного поповера: девять образцов, ручки формы и кнопка
   загрузки. По общей мерке в 360 px кнопка «Загрузить кисти…» оказывалась под
   краем — то есть о загрузке чужих наборов человек бы и не узнал. */
.tipset-pop { min-width: 268px; max-height: min(560px, 82vh); }
.tipset-group h4 {
  margin: 6px 4px 2px; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
}
.tipset { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; }
.tipset .tip-item { padding: 3px 4px; }
.tipset .tip-peek { width: 118px; height: 30px; }
.pop-foot { display: flex; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.pop-foot .btn { flex: 1; white-space: normal; text-align: center; }
/* Ручка, которой этой кисти нечего делать: жёсткость у растрового отпечатка
   неприменима — край нарисован в самом отпечатке. Гасим, а не прячем: иначе
   полоса опций прыгала бы при каждой смене кисти. */
.tool-options .row.dim { opacity: .42; }

/* Готовое число в полосе опций: измеритель показывает, а не спрашивает */
.tool-options .to-read {
  font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; white-space: nowrap;
}
/* Отпечаток кисти: показать форму нарисованной, а не тремя числами */
.brush-peek {
  display: block; border: 1px solid var(--line); border-radius: 7px;
  background: var(--panel-2); flex: 0 0 auto;
}
.seg { display: flex; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 8px; }
.seg .btn.icon {
  width: 26px; height: 22px; min-width: 26px; padding: 0; border: 0; background: transparent;
}
.seg .btn.icon svg { width: 15px; height: 15px; }
.seg .btn.icon.active { background: var(--accent); color: #fff; }
.seg .btn.icon:not(.active):hover { background: var(--hover); }
/* Ряд значков во всю ширину строки — так стоит выключка. Подписи у такого ряда
   нет: над ним имя раздела, а на колонке в 180 точек подпись забрала бы
   половину ширины и четыре значка сжались бы до нечитаемых. Кнопки делят
   ширину поровну, поэтому попасть в них мышью легче, чем в ряд по 26 точек. */
.seg.wide { flex: 1 1 auto; min-width: 0; }
.seg.wide .btn.icon { flex: 1 1 0; width: auto; min-width: 0; }
/* Ряд кнопок внутри строки с подписью: отбивку снизу держит сама строка.
   Переноса здесь нет нарочно — на колонке в 180 точек «Ж» и «К» уезжали друг
   под друга и строка «Начертание» становилась вдвое выше пустой. Кнопке из
   одной буквы тесно не бывает: ей хватает и того, что остаётся от подписи. */
.row > .rowbtns.inrow { flex: 1 1 auto; min-width: 0; margin: 0; gap: 4px; flex-wrap: nowrap; }
.swatch { width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--line); cursor: pointer; }
.toggle { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12.5px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.grid2 .row { margin-bottom: 0; }
/*
   В двух колонках на ячейку остаётся сотня с небольшим пикселей. Подпись
   слева тут рассчитана на «X» и «Y», а кладут в неё «Ширина, px» — и она
   переносилась посреди фразы. Ставим подпись НАД полем: так узкие панели
   устроены везде, и длина подписи перестаёт что-либо ломать.
*/
.grid2 .row {
  flex-direction: column; align-items: stretch; gap: 3px;
}
.grid2 .row label { flex: none; font-size: 11.5px; }
.grid2 .field { min-width: 0; }
/* Строки с одной буквой в подписи — X, Y, Ш, В — остаются в строку: там
   вертикаль только съела бы высоту */
.grid2 .row.tight { flex-direction: row; align-items: center; gap: 8px; }
.grid2 .row.tight label { flex: 0 0 auto; min-width: 14px; }
.muted-empty { color: var(--muted); font-size: 13px; line-height: 1.6; }
kbd {
  background: var(--panel-2); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 5px; padding: 1px 5px; font: 11px/1.4 ui-monospace, monospace; color: var(--text);
}

/* ----------------------------- Подвалы колонок ----------------------------- */
/*
   Полосы состояния во всю ширину больше нет: она тянулась через весь экран
   ради двух слов и ряда значков. Её содержимое разошлось по низу колонок —
   решение владельца 27 августа 2026.

   Прижимаются книзу сами: .dock — колонка flex, а поля панелей растут сверху.
*/
.dock-foot {
  margin-top: auto; flex: 0 0 auto;
  padding: 7px 10px;
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12px; line-height: 1.45;
}
.dock-foot:empty { display: none; }
/* Та же плашка, поставленная НАВЕРХ колонки: она отвечает на вопрос «что я
   держу», и читают её первой, до самих свойств. Черта уходит вниз, отступ
   сверху не нужен — над ней полоса сворачивания */
.dock-head {
  margin-top: 0;
  border-top: 0; border-bottom: 1px solid var(--line);
}
/* Масштаба и переключателей вида в подвале колонки больше нет: 3 сентября
   2026 они уехали в строку состояния под холстом (см. `.statusbar`). Правила
   `.view-foot` ушли вместе с разметкой — держать мёртвый набор селекторов
   значило бы обещать блок, которого нет. */
.dock-foot .name { color: var(--text); display: block; }
/* Подвал левой колонки: ходьба по страницам. «‹ 3 из 12 ›» — как внизу слева
   в InDesign. Стрелки узкие, счётчик посередине не прыгает по ширине. */
/* Ходьба по страницам живёт в строке состояния (с 4 сентября 2026), кнопки —
   того же роста, что соседний масштаб */
.statusbar .page-foot { display: flex; align-items: center; gap: 2px; }
.statusbar .page-foot.hidden { display: none; }
.statusbar .page-foot .btn.small {
  width: 22px; min-width: 22px; height: 22px; min-height: 22px; padding: 0;
  justify-content: center; border-radius: 5px; font-size: 14px;
}
.page-foot .btn[disabled] { opacity: .35; pointer-events: none; }
.page-foot .page-count { font-variant-numeric: tabular-nums; min-width: 56px; text-align: center; color: var(--text); }

/* Свёрнутая колонка — это узкая полоса со значками панелей: подвал в неё не
   лезет ни по ширине, ни по смыслу. */
.dock.collapsed .dock-foot { display: none; }

/* -------------------------------- Модалки ---------------------------------- */
#modal-root:empty { display: none; }
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.5);
  display: grid; place-items: center; z-index: 50;
}
.modal {
  /* min-width: 0 обязателен: карточка — элемент grid-подложки, а у таких
     min-width по умолчанию auto, то есть «не уже своего содержимого». Из-за
     этого длинная строка внутри раздвигала окно ШИРЕ заданного, и настройки
     меняли ширину при переключении разделов: «Интерфейс» с двумя кнопками
     переноса был заметно шире соседей */
  min-width: 0;
  width: min(480px, 92vw); background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,.5); padding: 18px;
  /* Выше экрана окно не растёт. Без этого длинный список — проверка перед
     печатью на сотню замечаний — уезжал за верх и низ экрана разом: до кнопок
     было не добраться, и окно выглядело сломанным. Сетка подложки центрирует
     карточку, то есть срезает её с ОБЕИХ сторон, — заголовок пропадал первым */
  max-height: 88vh; overflow-y: auto; overscroll-behavior: contain;
}
.modal.wide { width: min(780px, 94vw); }

/* --- Окно создания документа ---------------------------------------------
   Слева форматы вкладками, справа параметры — так устроены «Создать» в
   Photoshop и Illustrator. Раньше всё стояло одним столбцом: окно выходило
   узким и длинным, а формат и его размеры оказывались далеко друг от друга. */
.nd-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 250px;
  gap: 20px;
  margin-top: 14px;
  align-items: start;
}
.nd-tabs { display: flex; gap: 2px; margin-bottom: 12px; }
.nd-tab {
  appearance: none; font: inherit; font-size: 13px;
  padding: 6px 12px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--muted);
  cursor: pointer;
}
.nd-tab:hover { background: var(--panel-2); color: var(--fg); }
.nd-tab.on {
  background: var(--sel-bg, rgba(79, 140, 255, .16));
  border-color: var(--accent, #4f8cff);
  color: var(--fg);
}
/* Все группы в одной ячейке сетки: видна одна, а высоту держит самая
   высокая — окно не меняет рост при переходе между вкладками */
.nd-stack { display: grid; }
.nd-stack > .nd-group { grid-area: 1 / 1; }
.nd-group.off { visibility: hidden; pointer-events: none; }
.nd-presets { min-width: 0; }
.nd-presets .layouts { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 0; }
.nd-side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
/* Поле не тянется по высоте. `.field` объявлен `flex: 1 1 0` — это верно для
   строки, где поле занимает свободную ширину. Но здесь строка вертикальная, и
   та же запись означала «расти в высоту от нуля»: поле сжималось до 19 px при
   положенных тридцати. Отсюда и жалоба владельца, что поля «очень широкие и
   очень в высоту маленькие», — широкими они были по той же причине. */
.nd-side .row .field, .nd-side .row select.field { flex: 0 0 auto; }

/* Подпись над полем, а не слева от него: в колонке на 250 px подпись и поле
   в одну строку не помещаются — поле сжималось до нечитаемого */
.nd-side .row {
  display: flex; flex-direction: column; align-items: stretch; gap: 4px; margin: 0;
}
.nd-side .row label {
  flex: none; font-size: 11.5px; color: var(--muted); line-height: 1.2;
}
.nd-side .row .field, .nd-side .row input, .nd-side .row select { width: 100%; }
.nd-side .row input[type="color"] { width: 42px; height: 26px; padding: 0; }
/* Размер одной строкой: ширина, замок, высота, ориентация. Поля узкие и
   высокие, а не наоборот: в них набирают три-четыре цифры, и растянутое на
   всю колонку поле под «210» выглядит ошибкой вёрстки. Владелец 27 августа:
   «поля для ввода цифр очень широкие и очень в высоту маленькие». */
/* Свои «−» и «+» вместо системного счётчика: он рисуется браузером и в тёмной
   теме выглядит чужеродно, да ещё и не совпадал с полями размера рядом */
.nd-step { display: flex; gap: 2px; flex: 0 0 auto; }
.nd-step .btn.small.icon {
  width: 24px; min-width: 24px; height: 26px; padding: 0;
  display: flex; align-items: center; justify-content: center; font-size: 14px; line-height: 1;
}
/* Счётчик страниц: поле и кнопки в одну строку, а не столбиком, как остальное
   в колонке — число там короткое, и растягивать его на всю ширину незачем */
.nd-side .row:has(> .nd-step) { flex-direction: row; align-items: center; }
.nd-side .row:has(> .nd-step) label { flex: 0 1 auto; }
.nd-side .row:has(> .nd-step) .field { width: auto; flex: 1 1 0; min-width: 56px; }

.nd-size { display: flex; align-items: flex-end; gap: 6px; }
.nd-size > .row { flex: 1 1 0; min-width: 0; }
.nd-size .field { height: 34px; min-height: 34px; text-align: center; font-variant-numeric: tabular-nums; }
.nd-lock { flex: 0 0 auto; height: 34px; width: 30px; margin-bottom: 0; }
.nd-lock.active { background: var(--accent); color: #fff; }
.nd-orient { display: flex; gap: 3px; flex: 0 0 auto; }
.nd-orient .btn { height: 34px; width: 30px; }
.nd-orient .btn.active { background: var(--accent); color: #fff; }

/* Строка, которой сейчас не место, но место она держит: без этого окно
   подпрыгивает на её высоту при переходе «Экран» ↔ «Печать» */
.ghost { visibility: hidden; }

/* Подпись под полями держит две строки всегда: у печатного формата она
   длиннее (миллиметры, пиксели при разрешении и соотношение) и переносится,
   у экранного укладывается в одну — окно меняло рост на эту разницу */
.nd-params .hintline { min-height: 32px; }

/* Соотношение сторон на карточке — тише размера, но на виду */
.layout-card .sub.ratio { opacity: .62; }

.nd-params { display: flex; flex-direction: column; gap: 12px; }
.nd-params .grid2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
.nd-params .hintline { font-size: 11.5px; line-height: 1.4; }
.modal h2 { margin: 0 0 14px; font-size: 16px; }
.modal .actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

/* --- Справка о клавишах ---------------------------------------------------
   Список строится из каталога команд, а в нём сочетаний сотня: без своей
   прокрутки окно вылезало бы за экран, и кнопка «Понятно» уезжала бы вместе
   с ним. Две колонки — чтобы список читался разделами, а не лентой.

   Прокрутка и колонки — на РАЗНЫХ элементах, и это не украшение. Пока
   `columns` стояли на том же элементе, что и `max-height`, лишнее не
   прокручивалось вниз, а уходило вбок новыми колонками: ширина содержимого
   выходила 3798 px при видимых 742, и последних тридцати строк не было видно
   вовсе. То есть справка снова врала — просто иначе. */
.keys-scroll { max-height: 60vh; overflow-y: auto; }
.keys-list { columns: 2; column-gap: 22px; }
.keys-list .row {
  break-inside: avoid; display: grid; grid-template-columns: 150px minmax(0, 1fr);
  gap: 8px; align-items: baseline; margin-bottom: 3px;
}
.keys-section {
  break-inside: avoid; break-after: avoid;
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin: 12px 0 5px;
}
.keys-list > .keys-section:first-child { margin-top: 0; }
/* Узкое окно двух колонок не выдержит: подпись сожмётся в столбик по слову */
@media (max-width: 700px) { .keys-list { columns: 1; } }
.layouts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.layout-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
  padding: 8px 6px 6px; cursor: pointer; text-align: center;
}
.layout-card.active { border-color: var(--accent); background: #26314a; }
.layout-card .prev { display: grid; gap: 2px; height: 34px; margin-bottom: 5px; }
.start-presets { grid-template-columns: repeat(3, 1fr); }
.paper-wrap { height: 34px; display: grid; place-items: center; margin-bottom: 5px; }
.paper { background: #f2f4f8; border-radius: 2px; box-shadow: 0 1px 3px rgba(0,0,0,.5); }
.notice {
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
  background: #26314a; border: 1px solid var(--accent); border-radius: 9px;
  padding: 8px 10px; margin: 10px 0; font-size: 13px;
}
.layout-card .prev i { background: var(--muted); border-radius: 2px; display: block; opacity: .7; }
.layout-card span { display: block; font-size: 12px; color: var(--muted); }
.layout-card .sub { font-size: 11px; opacity: .7; }

/* --------------------------------- Тосты ----------------------------------- */
/* Вверху холста, а не внизу: внизу по центру стоит плавающая панель
   инструментов, а над ней — свойства инструмента, и сообщение садилось прямо
   на них. Отсчёт от верха #stage, а не от края окна: высота шапки с вкладками
   проектов меняется, и от окна тост рано или поздно сел бы уже на них.
   Отступ взят с запасом на линейку — она рисуется по краю холста. */
#toast {
  position: absolute; top: 22px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 6px; align-items: center; z-index: 60;
  pointer-events: none;
}
.toast {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 14px; box-shadow: 0 8px 24px rgba(0,0,0,.45);
  animation: pop .16s ease-out;
  pointer-events: auto;
  display: flex; align-items: center; gap: 10px;
}
.toast.err { border-color: #613; color: #ffb3b3; }
.toast .btn { height: 24px; padding: 0 8px; font-size: 12.5px; }
@keyframes pop { from { opacity: 0; transform: translateY(-6px); } } /* выезжает сверху — оттуда же, где встал */


/* ------------------------- Линейки и направляющие ------------------------- */
#rulers {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;   /* события ловит #stage, линейки только рисуются */
}
#rulers.hidden { display: none; }
body.rulers-on #stage { cursor: default; }

/* ---------------------------- Список объектов ---------------------------- */
#objects-panel {
  position: absolute; top: 12px; right: 12px; width: 230px; max-height: 60%;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 14px 36px rgba(0,0,0,.5); overflow: hidden; z-index: 20;
}
#objects-panel.hidden { display: none; }
.op-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 8px 8px 12px; font-size: 12px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); font-weight: 700;
  border-bottom: 1px solid var(--line);
}
.op-list { overflow-y: auto; padding: 6px; }
.op-item {
  display: flex; align-items: center; gap: 8px; padding: 5px 6px;
  border-radius: 7px; cursor: pointer; font-size: 13px;
}
.op-item:hover { background: var(--panel-2); }
.op-item.sel { background: #26314a; }
.op-item.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.op-item.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.op-item svg { width: 15px; height: 15px; opacity: .8; flex: 0 0 auto; }
.op-item .name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-item .eye { opacity: .45; }
.op-item .eye.on { opacity: 1; }
.op-hint { padding: 6px 10px 8px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--line); }

/* --------------------- Полосы прокрутки в тёмной теме -------------------- */
* { scrollbar-width: thin; scrollbar-color: var(--scroll) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scroll); border-radius: 6px; border: 2px solid var(--panel); }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-hover); }
::-webkit-scrollbar-corner { background: transparent; }



/* ========================================================================== */
/*  Оболочка полной версии: рельс инструментов слева, панели справа           */
/* ========================================================================== */

:root {
  /* Высота шапки. Мерой она стала, пока полос было две: шапка и строка
     вкладок стояли вплотную, и разной высоты читались ступенькой (до
     3 сентября 2026 — 40 при 31, владелец: бар «очень высокий», «режет
     глаз»). Строка вкладок ушла в саму шапку 4 сентября 2026 (п. 77A), и
     мера осталась одна на одну полосу — от неё считают её содержимое.
     Имя своё: `--bar-h` — высота НИЖНЕЙ полосы инструментов, от неё
     отсчитывается полоса опций; 3 сентября шапка на день заняла то же
     имя, и опции сели на инструменты. */
  --top-h: 32px;
  /* Кнопка и значок верхних полос. Внизу, у инструментов, кнопка под руку —
     34 при полосе 48; вверху под глаз — 26 при полосе 32. Значок 16 — мера
     Figma для верхней полосы; прежние 20 в полосу 32 не влезают вовсе. */
  --top-btn: 26px;
  --top-icon: 16px;
  --right-w: 288px;
}

/* --------------------------------- Верх ---------------------------------- */

.topbar {
  height: var(--top-h);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  -webkit-app-region: drag;
}
.topbar .group { display: flex; align-items: center; gap: 4px; -webkit-app-region: no-drag; }
/* Без выравнивания по центру кнопка растягивалась по высоте группы и
   вставала выше соседних ярлыков PDF · SVG · PNG на две точки: базовые
   линии подписей не совпадали (владелец 3 сентября 2026) */
/* Кнопки шапки мельче общих: полоса 32, значит 30-пиксельной кнопке с
   20-пиксельным значком там места нет. Правило одно на всю шапку, включая
   синюю «Экспорт» и шестерёнку: у соседей в одной полосе высота общая, а
   выделяться «Экспорт» должна цветом, а не размером плашки. Ярлыки быстрого
   вывода (PDF · SVG · PNG) сюда не попадают — у `.quick-export .btn.tiny`
   правило подробнее, и свои 22 они держат: мельче некуда. */
.topbar .btn { height: var(--top-btn); padding: 0 9px; font-size: 12.5px; border-radius: 7px; gap: 5px; }
.topbar .btn.icon { width: var(--top-btn); padding: 0; }
.topbar .btn svg { width: var(--top-icon); height: var(--top-icon); }
/* Счётчик на кнопке: сколько замечаний нашла последняя проверка перед
   печатью. Пока проверку не звали, счётчика нет вовсе — кнопка не должна
   обещать знание, которого у неё нет. Ноль показываем зелёным: «смотрели, всё
   чисто» — это тоже ответ, и ради него проверку и зовут. */
.topbar .btn.has-count { position: relative; overflow: visible; }
.btn-count {
  position: absolute; top: -3px; right: -3px;
  min-width: 14px; height: 14px; padding: 0 3px;
  border-radius: 7px; background: var(--danger); color: #fff;
  font-size: 9.5px; font-weight: 700; line-height: 14px; text-align: center;
  font-variant-numeric: tabular-nums; pointer-events: none;
}
.btn-count.clean { background: #3f9a5a; }
.btn-count.hidden { display: none; }
.topbar .sep { width: 1px; height: 16px; background: var(--line); margin: 0 3px; }
/* Распорки в шапке нет: середину занимают вкладки (`.doc-tabs`), и растягивают
   правую группу к краю они же (4 сентября 2026, п. 77A). */
.topbar .brand {
  font-weight: 800; letter-spacing: .16em; font-size: 12px; color: var(--muted);
  padding-left: 72px; padding-right: 10px; display: flex; align-items: center; gap: 6px;
  white-space: nowrap;
}
body.win .topbar .brand, body.linux .topbar .brand { padding-left: 4px; }
/* Номер версии — кнопка: щелчок проверяет обновления (владелец 4 сентября
   2026; тогда же снята плашка «альфа»). Сюда же пишет служба обновлений
   («Загрузка 42 %»), поэтому ширина не задана — строка то короткая, то
   длинная. Шапка тянет окно, кнопка — нет. */
.topbar .brand .version {
  -webkit-app-region: no-drag;
  border: 0; background: none; color: inherit; font: inherit; cursor: pointer;
  padding: 2px 5px; border-radius: 4px;
  font-weight: 600; letter-spacing: .04em; font-size: 11px; opacity: .75;
  font-variant-numeric: tabular-nums;
}
.topbar .brand .version:hover { background: var(--panel-2); opacity: 1; }
.topbar .brand .version:empty { display: none; }

/* --------------------------- Переключатель режимов ------------------------ */
/*
   Три корешка вместо ленты со вкладками. Вкладочность, ради которой ленту и
   хотят, — видно все три мира сразу и видно, где ты, — остаётся; сотни кнопок
   с подписями под ними не появляется. Так же устроены персоны Affinity и
   вкладки рабочих сред Blender. Разбор — в UI.md.
*/

.modes {
  display: flex; gap: 2px;
  padding: 2px;
  margin-right: 4px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  -webkit-app-region: no-drag;
}
.modes .mode {
  height: 26px; padding: 0 11px;
  background: none; border: 0; border-radius: 6px;
  color: var(--muted); font: inherit; font-size: 12.5px; font-weight: 600;
  white-space: nowrap; cursor: pointer;
}
.modes .mode:hover { color: var(--text); }
.modes .mode.active { background: var(--panel); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.35); }
.modes .mode:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Недоступный выбор виден и объясняется подсказкой, а не пропадает: кнопка,
   исчезающая и появляющаяся сама по себе, читается как сбой отрисовки. */
.modes .mode[disabled] { opacity: .38; cursor: default; }
.modes .mode[disabled]:hover { color: var(--muted); }

/* ---------------------------- Рельс инструментов -------------------------- */
/*
   Рельс рисуется из каталога (ui/tools.js) гнёздами. Гнездо — одна кнопка, в
   которой может стоять несколько инструментов; лишние достаются списком.
   Раньше кнопки лежали здесь все подряд и в окно не помещались.
*/

/* Уголок в правом нижнем углу, как у вложенных инструментов Photoshop: по
   уголку — сразу список, по кнопке — то, что на ней показано; удержание тоже
   открывает список. Заведено для гнёзд рельса; кнопка «Добавить страницу»,
   жившая тем же уголком в шапке, оттуда ушла 3 сентября 2026 — страницы
   добавляют в панели страниц и знаком «+» у самого листа. */
.btn.has-fly { position: relative; }
.btn.has-fly::after {
  content: '';
  position: absolute; right: 3px; bottom: 3px;
  border: 3.5px solid transparent;
  border-right-color: currentColor;
  border-bottom-color: currentColor;
  opacity: .55;
}
.btn.has-fly:hover::after { opacity: .9; }

/* Список гнезда: с именами, а не одними значками — по значку ромб от
   параллелограмма не отличить */
.tool-fly {
  position: fixed; z-index: 60;
  display: flex; flex-direction: column; gap: 1px;
  padding: 5px;
  min-width: 190px;
  max-height: calc(100vh - 16px); overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 14px 36px rgba(0,0,0,.5);
}
.tool-fly .btn.tool {
  width: 100%; height: 30px; padding: 0 9px;
  display: flex; align-items: center; gap: 9px;
  justify-content: flex-start; text-align: left;
  background: transparent; border-radius: 6px;
  font-size: 13px; color: var(--text);
}
.tool-fly .btn.tool:hover { background: var(--panel-2); }
.tool-fly .btn.tool svg { width: 18px; height: 18px; flex: 0 0 18px; }
.tool-fly .fly-name { white-space: nowrap; flex: 1 1 auto; }
/* Галочка у того, что сейчас в руке. Раньше выбранная строка красилась синим —
   тем же цветом, каким во многих меню красится строка под курсором, и понять,
   что из двух ты видишь, было нельзя. Столбец держится и у пустых строк:
   иначе значки разъезжаются по строке (E6). */
.tool-fly .fly-ck { flex: 0 0 12px; width: 12px; display: grid; place-items: center; }
.tool-fly .fly-ck svg { width: 12px; height: 12px; flex: 0 0 12px; color: var(--accent); }
/* Клавиша у каждой строки списка (E6). Пока буквы жили только во всплывающей
   подсказке, узнать их можно было по одной за наведение — то есть про то, что
   шестнадцать фигур берутся с клавиатуры, не узнавали вовсе. */
.tool-fly .fly-key {
  flex: 0 0 auto; margin-left: auto; padding-left: 10px;
  color: var(--muted); font-size: 11.5px; white-space: nowrap;
}
/* Шапка списка: клавиша ГНЕЗДА и то, что Shift перебирает его по кругу. Одной
   строкой сверху вместо пятнадцати одинаковых «U» напротив каждой фигуры
   (разбор 4 сентября 2026, п. 100) */
.tool-fly .fly-head {
  padding: 4px 9px 6px;
  color: var(--muted); font-size: 11px; white-space: nowrap;
  border-bottom: 1px solid var(--line); margin-bottom: 3px;
}

/* ------------------------------ Колонки палитр ----------------------------- */
/*
   Две колонки, левая и правая. Панель переносится между ними за свой
   заголовок: у документа на сто страниц панели страниц нужна высокая колонка,
   а не окошко в четыре строки внизу правой. Раскладка помнится на режим —
   режим и есть рабочее пространство.
*/

.dock {
  flex: 0 0 auto;
  background: var(--panel);
  display: flex; flex-direction: column;
  min-height: 0;
}
.dock-left { width: var(--left-w, 240px); border-right: 1px solid var(--line); }
.dock-right { width: var(--right-w); border-left: 1px solid var(--line); }
.dock.hidden { display: none; }

/* Колонка под курсором во время переноса */
.dock.drop { outline: 2px solid var(--accent); outline-offset: -2px; }
body.docking .dock { min-width: 56px; }
body.docking { cursor: grabbing; }
.panel.dragging { opacity: .45; }

/* Ярлык, который едет за курсором */
.dock-ghost {
  position: fixed; z-index: 80; pointer-events: none;
  padding: 5px 10px; border-radius: 7px;
  background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
}

/* Свёрнутая колонка: узкая полоса с именами, как значковый край InDesign.
   Холст получает всю ширину, а палитры остаются в одном щелчке. */
.dock.collapsed { width: 30px !important; }
.dock.collapsed > *:not(.dock-bar) { display: none; }
/* Высота задана числом, а не содержимым: слева в строке переключатель вида,
   справа масштаб, и от разницы в их внутренних отступах строки выходили
   разной высоты — глаз ловит это сразу, потому что они стоят на одном уровне
   по краям экрана. */
/* Полоса сворачивания колонки. В ней осталась одна стрелка: переключатель
   вида документа уехал в панель страниц, масштаб — вниз к переключателям
   вида. Поэтому она втрое тоньше прежнего — полоса ради одной кнопки не
   должна занимать высоту заголовка. Владелец 1 сентября 2026. */
.dock-bar {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  /* Полоса — сама кнопка: её жмут целиком, чтобы свернуть колонку. Потому и
     высота под палец, а не 13 (владелец 3 сентября 2026) */
  height: 18px; padding: 0 4px; cursor: pointer; user-select: none;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
/* Свёрнутая колонка: значки панелей идут СВЕРХУ, сразу под стрелкой разворота
   (п. 109, 4 сентября 2026). Развёрнутая полоса горизонтальная, и
   `space-between` в ней разводит стрелку и то, что положили рядом, по краям —
   а в столбце то же правило вжимало единственный корешок в самый пол колонки,
   за сотни точек от стрелки, которой он пара. */
.dock.collapsed .dock-bar {
  flex-direction: column; align-items: stretch; justify-content: flex-start;
  border-bottom: 0; height: 100%; padding: 4px 2px;
}
.dock-fold, .dock-tab {
  background: none; border: 0; border-radius: 5px;
  color: var(--muted); font: inherit; cursor: pointer;
}
/* Кнопка сворачивания стоит у ВНЕШНЕГО края своей колонки: слева — слева,
   справа — справа. Так она всегда со стороны кромки экрана, куда колонка и
   уезжает, а остаток строки достаётся тому, что в неё положили.
   Прежде обе кнопки шли первыми, и справа выходило наоборот: сначала
   сворачивание, потом масштаб, и оба сбиты к середине. */
.dock-fold {
  width: 18px; height: 16px; padding: 0; border: 0; background: transparent;
  color: var(--muted); line-height: 1; cursor: pointer; display: grid; place-items: center;
}
/* Значок `i-chev` смотрит вниз; повернём вправо, а наружу у левой колонки — влево */
.dock-fold svg { width: 12px; height: 12px; transform: rotate(-90deg); }
.dock-fold.to-left svg { transform: rotate(90deg); }
.dock-bar:hover { background: var(--panel-2); }
.dock-left .dock-fold { order: 0; margin-right: auto; }
.dock-right .dock-fold { order: 2; margin-left: auto; }
.dock.collapsed .dock-fold { order: 0; margin: 0 0 6px; }
.dock-fold:hover, .dock-tab:hover { background: var(--panel-2); color: var(--text); }
/* Корешок свёрнутой колонки — ЗНАЧОК панели, а не её имя набок.
   Вертикальное «СТРАНИЦЫ» читалось поворотом головы и занимало половину
   высоты корешка на одно слово; при двух панелях полоса была занята целиком.
   Значок узнаётся мгновенно, а полное имя даёт подсказка по наведению —
   решение владельца 3 сентября 2026 (A8). */
.dock-tab {
  width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center; margin: 0 auto 2px;
}
.dock-tab svg { width: 17px; height: 17px; }
/* Корешок группы вкладок — один на всю группу, со значками всех её панелей.
   Три слова столбиком в полосу шириной в тридцать точек не помещаются, а
   вопрос «что там лежит» задают именно свёрнутой колонке. Имена остаются
   подсказкой по наведению. */
.dock-tab-icons {
  writing-mode: horizontal-tb; padding: 7px 0;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
}
.dock-tab-icons svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* Переключатель вида документа, переехавший в строку левой колонки.
   Строка там занята одной кнопкой сворачивания, а рядом пусто — место
   названо владельцем 29 августа. Переключатель занимает остаток строки
   целиком: половинками по краям он читался бы как две разные кнопки, а не
   как один выбор из двух. */
.dock-bar .doc-kind {
  flex: 1 1 auto; min-width: 0;
  margin-right: 0;
  padding: 1px;
  border-radius: 6px;
}
.dock-bar .doc-kind .mode {
  flex: 1 1 0; min-width: 0;
  height: 20px; padding: 0 4px;
  font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis;
}

/* Масштаб по строкам колонок больше не кочует: с 3 сентября 2026 он живёт
   в строке состояния под холстом и никуда оттуда не уезжает. */

/* Заголовок панели — он же ручка переноса */
.panel-head { cursor: grab; }
body.docking .panel-head { cursor: grabbing; }

/* Убранная палитра прячется классом `hidden` от ui/docks.js — одинаково любая.
   Отдельного `body.no-layers` тут больше нет: он был вторым выключателем над
   той же панелью, и они не знали друг о друге. */

/* Свойства — сверху: с ними работают чаще, чем со списком слоёв, и они не
   должны уезжать вниз, когда слоёв много. Ниже — страницы и слои; когда
   страниц больше одной, три панели делят колонку долями и каждая скроллится
   сама, иначе нижняя выдавливает верхнюю за край. */
.panel { display: flex; flex-direction: column; min-height: 0; }
/* Доли высоты задаёт app.js: он пишет каждой панели свой flex-grow по имени и
   помнит его между запусками. В css остаётся только запас, ниже которого
   панель превращается в полоску без содержимого. */
.panel.props { flex: 40 1 0; min-height: 96px; }
.panel.layers { flex: 30 1 0; min-height: 90px; border-top: 1px solid var(--line); }
.panel.navigator { min-height: 60px; border-top: 1px solid var(--line); }
/* Разделитель между соседними панелями. Тонкий, но берётся: полоса захвата
   шире рисунка, иначе в неё надо целиться. */
.panel-split {
  flex: 0 0 auto; height: 7px; margin: -3px 0; cursor: row-resize; position: relative; z-index: 2;
}
.panel-split::after {
  content: ''; position: absolute; left: 0; right: 0; top: 3px; height: 1px; background: var(--line);
}
.panel-split:hover::after { background: var(--accent); }

/* ------------------- Вкладки и плавающие палитры --------------------------
 * Свободная стыковка, решение владельца 3 сентября 2026. Две вещи из
 * Photoshop: панель, брошенная на заголовок соседки, встаёт с ней вкладками
 * одной группы; вытащенная на полотно — плавающим окном.
 */

/* Группа вкладок: одна шапка с корешками на несколько панелей. Собственные
   заголовки панелей внутри группы не показываются — их заменяют корешки, и
   две полосы подряд читались бы как две разные панели. */
.panel-group { display: flex; flex-direction: column; min-height: 0; }
.panel-group > .panel { flex: 1 1 auto !important; min-height: 0; border-top: 0; }
.panel-group > .panel > .panel-head { display: none; }
/* Невидимая вкладка группы: место она не занимает, но из разметки не уходит —
   переключение корешка не должно перекладывать узлы */
.panel-group > .panel.stowed { display: none; }

.group-tabs {
  flex: 0 0 auto; display: flex; align-items: stretch;
  height: 26px; padding: 0 2px; gap: 2px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  cursor: grab; user-select: none;
  overflow-x: auto; scrollbar-width: none;
}
.group-tabs::-webkit-scrollbar { display: none; }
body.docking .group-tabs { cursor: grabbing; }
.group-tab {
  flex: 0 1 auto; min-width: 0; padding: 0 8px;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--muted); font: inherit;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.group-tab:hover { color: var(--text); }
.group-tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* Куда упадёт то, что тащат: подсветка целится в шапку, а не в колонку —
   бросок сюда значит «во вкладки», а не «в стопку» */
.droptab > .panel-head, .droptab > .group-tabs,
.panel-head.droptab { box-shadow: inset 0 0 0 2px var(--accent); }

/* Плавающее окно. Стоит внутри #app, а не #stage: колонки ему тоже не
   хозяева — окно висит над всем рабочим местом. Место и размер помнятся в
   раскладке, а сесть на шапку или на нижние плавающие полосы оно не может:
   ui/docks.js держит его в свободной области (`freeArea`). */
.panel-float {
  position: absolute; z-index: 35;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .5);
  overflow: hidden;
}
.panel-float > .panel, .panel-float > .panel-group { flex: 1 1 auto !important; min-height: 0; }
.panel-float > .panel { border-top: 0; }
/* Заголовок окна — ручка окна, и только: свернуть панель, которая и есть всё
   окно, значило бы оставить пустую коробку с полоской наверху (app.js это и
   не даёт). Значит и треугольника состояния тут быть не должно — он обещает
   то, чего не будет. */
.panel-float > .panel > .panel-head { cursor: grab; }
body.docking .panel-float > .panel > .panel-head { cursor: grabbing; }
.panel-float .panel-head > span:first-child::before { display: none; }
/* Окно, которое сейчас несут: сквозь себя оно должно пропускать курсор,
   иначе колонка под ним не поймает бросок */
.panel-float.floating-drag { pointer-events: none; opacity: .92; }

/* Уголок изменения размера. Полоса захвата шире рисунка — иначе в неё надо
   целиться, та же беда, что была у разделителя панелей. */
.float-size {
  position: absolute; right: 0; bottom: 0; width: 16px; height: 16px;
  cursor: nwse-resize; z-index: 3;
}
.float-size::after {
  content: ''; position: absolute; right: 4px; bottom: 4px; width: 7px; height: 7px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  opacity: .55;
}
.float-size:hover::after { opacity: 1; }
/* Высота 26, а не 30: заголовок только называет панель, работают ниже. В
   колонке их до четырёх подряд, и четыре лишние полоски по четыре точки —
   это строка списка слоёв целиком. 26 — та же высота, что у `.btn.small`:
   если в шапку однажды вернутся кнопки, они встанут в неё ровно. */
.panel-head {
  flex: 0 0 auto;
  height: 26px; padding: 0 8px 0 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}

#props {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Было 12 со всех сторон. Сверху и снизу отступ работает дважды — у панели
     уже есть заголовок и полоса под списком, — а по бокам каждая точка идёт
     полю в ширину: в колонке 288 их и так мало. */
  padding: 9px 10px 10px;
  min-width: 0;
}

/* --------------------- Плотность колонок: поля мельче ---------------------
 * Владелец 1 сентября 2026: «можно сделать некоторые элементы правой и левой
 * колонки, особенно некоторые поля ввода, чуть-чуть мельче — для экономии
 * места, как в InDesign. Но размер нижних баров я бы не трогал».
 *
 * Мерка — «чуть-чуть»: поле 30 → 26 точек, просвет между строками 8 → 6.
 * Ниже 26 не опускаемся и шрифт мельче 11.5 px не делаем: в поле надо
 * попадать мышью и читать, что в нём набрано. 26 выбрано не на глаз — столько
 * же у `.btn.small` и у кнопок в нижних полосах, поэтому поле и кнопка рядом
 * стоят в один рост, а не ступенькой.
 *
 * Сужение живёт под `.dock`, а не в самих `.field` и `.row`. Те же классы
 * стоят в модальных окнах (создание документа, настройки, справка о клавишах)
 * и в плавающей полосе опций инструмента — там своя мерка и своя ширина, и
 * менять её не просили. Нижние полосы колонок (`.panel-bar`, `.page-foot`,
 * `.view-foot`) не задеты намеренно: их только что свели к общим 35 точкам.
 */
:is(.dock, .panel-float) .field { height: 26px; min-height: 26px; }
/* Многострочное поле мерится строками, а не общей высотой: 26 — это одна
   строка, а вводят в него абзац. Уменьшено на ту же долю, что и остальное */
:is(.dock, .panel-float) textarea.field { height: 58px; min-height: 58px; }
:is(.dock, .panel-float) input[type=color] { height: 26px; }
:is(.dock, .panel-float) .cp-swatch { height: 26px; }
/* Ползунку 92 точки в ширину не обязательны, а подписи — да. `min-width: 92px`
   у `.field` заведён ради списков («A4 альбомный» не помещался), но достался и
   ползункам: в суженной колонке строка «Поворот» не влезала, ужималась подпись
   (она одна умеет), и от неё не оставалось НИЧЕГО — ползунок без имени. Пусто
   хуже обрезанного: «Пово…» хотя бы отвечает, о чём строка. */
:is(.dock, .panel-float) input[type=range].field { min-width: 64px; }
:is(.dock, .panel-float) .row { margin-bottom: 6px; }
/* Строке внутри сетки просвет снизу не нужен — его держит сама сетка.
   Правило повторено, потому что `.dock .row` равен по весу `.grid2 .row`
   выше и иначе побеждал бы порядком, вернув просветы внутрь сетки */
:is(.dock, .panel-float) .grid2 .row { margin-bottom: 0; }
:is(.dock, .panel-float) .grid2 { gap: 6px 8px; margin-bottom: 6px; }
:is(.dock, .panel-float) .rowbtns { margin-bottom: 6px; }
:is(.dock, .panel-float) .hintline { margin-bottom: 6px; }
:is(.dock, .panel-float) .presets { margin-bottom: 6px; }
:is(.dock, .panel-float) .sublabel { margin: 0 0 4px; }
:is(.dock, .panel-float) details.more { margin-top: 7px; }
:is(.dock, .panel-float) details.more > summary { padding: 4px 0; }

/* Краски документа в поповере цвета */
.cp-spots { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 0 0; }
.cp-spots-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  font-size: 11px; color: var(--muted); padding-bottom: 2px;
}
.cp-chip.spot { position: relative; }
/* Уголок у плашки: по нему её отличают от обычной краски, как в InDesign */
.cp-chip.spot.pantone::after {
  content: ''; position: absolute; right: 0; bottom: 0;
  border: 4px solid transparent; border-right-color: #fff; border-bottom-color: #fff;
}

/* --------------------------- Отчёт перед печатью --------------------------- */

/* Список замечаний прокручивается сам, а заголовок и кнопки стоят на месте:
   с ними-то и работают — «показать» и «всё равно собрать» */
.pf-list { max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; padding-right: 4px; }
.pf-item { padding: 6px 0; border-bottom: 1px solid var(--line); }
.pf-item:last-child { border-bottom: none; }
.pf-head { display: flex; align-items: center; gap: 8px; }
.pf-title { font-size: 13px; font-weight: 600; }
.pf-page { font-size: 11px; color: var(--muted); }
.pf-head .btn { margin-left: auto; }
.pf-detail { font-size: 12px; color: var(--muted); line-height: 1.45; padding-left: 16px; }
.pf-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.pf-dot.error { background: #ff5c5c; }
.pf-dot.warning { background: #ffb020; }

/* ----------------------------- Панель страниц ----------------------------- */

/* Появляется только когда страниц больше одной — как полоса вкладок.
   Одностраничный документ выглядит ровно как раньше. */
.panel.pages { flex: 30 1 0; min-height: 90px; border-top: 1px solid var(--line); }
.panel.pages.hidden { display: none; }

/* Отступ 4 и просвет 3: у строки страницы есть своя рамка выделения, и
   разделять соседей ещё и воздухом в четыре точки незачем — на двадцати
   листах это лишний экран прокрутки */
.pg-list { flex: 1 1 auto; overflow-y: auto; padding: 4px; display: flex; flex-direction: column; gap: 3px; min-height: 0; }

/* Половина шаблонов — верх панели страниц. Доля задаётся ползунком ниже и
   помнится между запусками; здесь только пол, ниже которого плитку не видно */
.pg-masters {
  flex: 22 1 0; min-height: 46px;
  display: flex; flex-direction: column; overflow: hidden;
}
.pg-masters.hidden { display: none; }
/* Заголовок половины шаблонов: одна надпись, без кнопок. Кнопка «завести
   шаблон» переехала в полосу под списком, к «добавить страницу», — они
   заводят соседние вещи и стоять должны рядом */
.pg-masters-head {
  flex: 0 0 auto; min-height: 19px; padding: 2px 8px;
  display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); user-select: none;
}
/* Шаблонов нет — половина живёт одной строкой «Мастер-макеты · нет · +», и ни
   списка, ни ползунка под ней не остаётся. Разбор 4 сентября 2026, п. 93:
   пояснение в три строки стояло выше самих страниц в каждом документе, где
   шаблон не завели. Оно не выброшено, а перенесено в подсказку заголовка. */
/* Имя класса не `empty`: так зовётся пустой экран программы
   (`.empty` — подложка во весь холст, `position: absolute; inset: 0`), и
   половина шаблонов, помеченная им, растягивалась на всё окно */
.pg-masters.no-masters { flex: 0 0 auto; min-height: 0; }
.pg-masters.no-masters .mp-list { display: none; }
/* «нет» — не заголовок, а ответ: без разрядки и прописных, которые несёт само
   слово «Мастер-макеты» */
.pg-masters-none { font-weight: 400; letter-spacing: 0; text-transform: none; }
/* Кнопка «+» видна только в пустой строке: в полосе под списком у неё есть
   близнец «+A», и вдвоём они звали бы одну команду дважды */
.pg-masters-add {
  margin-left: auto; width: 18px; height: 18px; padding: 0;
  display: none; place-items: center; line-height: 1; font-size: 13px;
}
.pg-masters.no-masters .pg-masters-add { display: grid; }
/* Ползунок между шаблонами и листами. Полоса захвата шире рисунка: в линию
   толщиной в пиксель не прицелиться */
.pg-split {
  flex: 0 0 auto; height: 7px; margin: 0; cursor: row-resize; position: relative; z-index: 2;
}
.pg-split.hidden { display: none; }
.pg-split::after {
  content: ''; position: absolute; left: 6px; right: 6px; top: 3px; height: 1px; background: var(--line);
}
.pg-split:hover::after, .pg-split.dragging::after { background: var(--accent); left: 0; right: 0; }

.pg-row {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 3px 6px;
  border: 1px solid transparent;
  border-radius: 7px;
  cursor: pointer;
  /* Перетаскивание своё, на pointer-событиях: выделение текста и системный
     drag внутри строки только мешают жесту */
  user-select: none;
  touch-action: none;
}
.pg-row:hover { background: var(--panel-2); }
.pg-row.sel { background: var(--sel-bg, rgba(79, 140, 255, .16)); border-color: var(--accent, #4f8cff); }
.pg-row.dragging { opacity: .5; }

/* Размер задаётся строкой: он зависит от пропорций страницы (см. pages.js) */
.pg-thumb {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
}
.pg-canvas { display: block; }

.pg-meta { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pg-name { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pg-sub { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pg-num {
  font-size: 11px; color: var(--muted);
  min-width: 18px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.pg-row.master .pg-num { color: var(--accent, #4f8cff); font-weight: 700; }

.pg-group {
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); padding: 4px 6px 0;
}
.pg-row.master { border-color: var(--line); background: var(--panel-2); }
/* Кнопки строки лежат поверх неё, а не в её сетке: пока они занимали свою
   колонку, имя страницы обрезалось до «Стр…» даже там, где места хватало.
   Появляются они всё равно только на наведении — место под них не нужно. */
.pg-btns {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  display: flex; gap: 2px; opacity: 0; transition: opacity .1s;
  padding-left: 10px;
  background: linear-gradient(90deg, transparent, var(--panel-2) 10px);
  border-radius: 6px;
  pointer-events: none;
}
/* Только на наведении. У выбранной строки они висели постоянно и в узкой
   колонке накрывали собой имя страницы: видно было «Стра…» и два значка.
   Те же два действия стоят в полосе под списком — там до них дотянуться
   можно всегда, а строка остаётся читаемой */
.pg-row:hover .pg-btns { opacity: 1; pointer-events: auto; }

/* Куда встанет страница, если отпустить: линия между строками */
.pg-row.drop-before::before,
.pg-row.drop-after::after {
  content: '';
  position: absolute; left: 4px; right: 4px; height: 2px;
  background: var(--accent, #4f8cff);
  border-radius: 2px;
}
.pg-row.drop-before::before { top: -4px; }
.pg-row.drop-after::after { bottom: -4px; }

/* Значок макета: доли страницы прямоугольниками — текст и картинка разным
   рисунком, чтобы макет узнавался с одного взгляда */
.tpl-paper { position: relative; }
.tpl-mark { position: absolute; display: block; border-radius: 1px; }
.tpl-mark.text { background: rgba(140, 150, 170, .75); }
.tpl-mark.image { background: rgba(79, 140, 255, .5); border: 1px solid rgba(79, 140, 255, .9); box-sizing: border-box; }

/* ------------------------------ Панель слоёв ------------------------------ */

.lay-list { flex: 1 1 auto; overflow-y: auto; padding: 3px 0 8px; }
.lay-empty { color: var(--muted); font-size: 12.5px; padding: 14px 12px; line-height: 1.5; }

/* Крупные миниатюры включает кнопка над списком: строка становится выше
   ровно настолько, чтобы в неё влезла картинка 44 точки */
/* Полоса под списком слоёв: что со слоями делают. Прижата к низу панели и
   не прокручивается вместе со списком — до неё должно быть одинаково далеко
   и на трёх слоях, и на сотне */
/* «Свободно · Альбом» внутри панели страниц: это про то, как лежат страницы,
   и стоять должно рядом с ними, а не в отдельной полосе наверху колонки */
.doc-kind-inpanel {
  flex: 0 0 auto; display: flex; gap: 2px; padding: 4px 6px;
  border-bottom: 1px solid var(--line);
}
.doc-kind-inpanel .mode { flex: 1 1 0; justify-content: center; }

/* Полоса действий под списком — одна на все панели колонки.
 *
 * У слоёв и страниц она устроена одинаково, и выглядеть должна одинаково:
 * значки посередине, просветы равные, разделители одной длины, кнопка
 * 24 точки — та же, что в подвалах колонок. Прежде значки жались к левому
 * краю, а справа оставалась пустая треть строки; отступы у соседних полос
 * не совпадали. Владелец 1 сентября 2026: «иконки имеют разные отступы,
 * прибиты к левому краю, справа пустой кусок — распределить адекватнее».
 */
.panel-bar {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 5px 8px; min-height: 35px;
  border-top: 1px solid var(--line);
}
.panel-bar .btn.small { height: 24px; }
.panel-bar .btn.small.icon { width: 24px; min-width: 24px; padding: 0; }
/* Ширина постоянная: с «+A» на «+B» ряд не должен дёргаться */
.panel-bar-letter {
  width: 32px; min-width: 32px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; line-height: 1;
}
.panel-bar-sep { width: 1px; height: 16px; background: var(--line); margin: 0 4px; flex: 0 0 auto; }
/* Нижняя полоса слоёв: три пачки кнопок разводятся по краям и середине.
   Пока они стояли вплотную с одинаковым просветом, шесть значков читались
   одним рядом, и куда нажимать — было неочевидно (владелец 3 сентября 2026).
   Разделители становятся распорками: сами не видны, но держат просвет */
.lay-foot { justify-content: space-between; }
.lay-foot .panel-bar-sep { flex: 1 1 auto; width: auto; background: transparent; margin: 0; }
.panel-bar-del:hover { color: var(--danger); }

.lay-list.lay-big .lay-row { height: 50px; }
.lay-list.lay-big .lay-thumb { width: 44px; height: 44px; }

.lay-row {
  --depth: 0;
  display: flex; align-items: center; gap: 5px;
  height: 26px;
  padding-right: 6px;
  padding-left: calc(4px + var(--depth) * 13px);
  cursor: default;
  border-left: 2px solid transparent;
}
.lay-row:hover { background: var(--panel-2); }
.lay-row.sel { background: #26314a; border-left-color: var(--accent); }
.lay-row.frame .lay-name { font-weight: 600; }
.lay-row.off .lay-name, .lay-row.off .lay-icon { opacity: .42; }
.lay-row.dragging { opacity: .45; }
.lay-row.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.lay-row.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.lay-row.drop-inside { background: #2c3b58; box-shadow: inset 0 0 0 1px var(--accent); }

.lay-twisty {
  width: 14px; height: 20px; flex: 0 0 14px;
  background: none; border: 0; padding: 0; color: var(--muted);
  cursor: pointer; display: grid; place-items: center;
}
.lay-twisty svg { width: 12px; height: 12px; transform: rotate(-90deg); transition: transform .12s; }
.lay-twisty.open svg { transform: rotate(0deg); }
.lay-twisty.empty { visibility: hidden; }

.lay-icon { width: 15px; height: 15px; flex: 0 0 15px; opacity: .75; }
.lay-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px;
}
.lay-rename {
  flex: 1 1 auto; min-width: 0;
  height: 20px; padding: 0 4px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--accent); border-radius: 4px;
  font: inherit; font-size: 13px;
}
.lay-btn {
  width: 20px; height: 20px; flex: 0 0 20px;
  background: none; border: 0; padding: 0; border-radius: 4px;
  color: var(--muted); cursor: pointer; display: grid; place-items: center;
  opacity: 0;
}
.lay-btn svg { width: 14px; height: 14px; }
.lay-row:hover .lay-btn, .lay-btn.on, .lay-row.sel .lay-btn { opacity: 1; }
.lay-btn.eye.on { opacity: .5; }
.lay-row:hover .lay-btn.eye.on { opacity: 1; }
.lay-btn.lock.on { color: #ffb347; }
.lay-btn:hover { background: rgba(255,255,255,.08); color: var(--text); }

/* ------------------------------ Правка текста ----------------------------- */

/* Поле правки невидимо и ничего не показывает. Оно осталось приёмником
   нажатий: через настоящее поле работают китайский ввод, буфер обмена,
   системные сочетания и переходы по словам. Буквы, курсор и выделение
   рисует холст — той же раскладкой, которой печатает. Пока поле было
   видимым, оно ломало строки по-своему, и текст в нём стоял не там, где
   на холсте. */
#text-editor {
  position: absolute; top: 0; left: 0;
  display: none;
  transform-origin: 0 0;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  border: 0;
  padding: 0;
  outline: none; resize: none; overflow: hidden;
  margin: 0;
  box-sizing: border-box;
  white-space: pre-wrap; word-break: break-word;
  /* Мышь принадлежит холсту: курсор ставит он, а не браузер */
  pointer-events: none;
}
#text-editor.on { display: block; }
/* Подсветку своего выделения рисуем сами — системная тут только мешала бы */
#text-editor::selection { background: transparent; }

/* ----------------------------- Палитра команд ----------------------------- */
/*
   Стоит поверх всего и ближе к верху окна, а не по центру: список растёт вниз,
   и если держать поле по центру, при наборе он лезет за нижний край.
*/

.pal-back {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(6, 8, 12, .55);
  display: flex; justify-content: center; align-items: flex-start;
  padding: 12vh 16px 16px;
}
.pal {
  width: min(620px, 100%);
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
  overflow: hidden;
}
.pal-input {
  height: 48px; padding: 0 16px;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  color: var(--text); font: inherit; font-size: 15px;
}
.pal-input:focus { outline: none; }
.pal-input::placeholder { color: var(--muted); }

.pal-list { max-height: min(52vh, 460px); overflow-y: auto; padding: 6px; }
.pal-section {
  padding: 9px 10px 4px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted);
}
.pal-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; height: 32px; padding: 0 10px;
  background: none; border: 0; border-radius: 7px;
  color: var(--text); font: inherit; font-size: 13.5px; text-align: left;
  cursor: pointer;
}
.pal-row.on { background: var(--accent); color: #fff; }
.pal-row.on kbd { border-color: rgba(255,255,255,.35); color: #fff; }
/* Команда, которой сейчас нечего делать: видна, но не берётся. Прятать её
   хуже — «почему тут нет „сгруппировать“» вопрос неприятнее, чем серая строка */
.pal-row.off { opacity: .38; cursor: default; }
.pal-ico { width: 17px; height: 17px; flex: 0 0 17px; opacity: .8; }
.pal-name { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pal-name b { font-weight: 700; color: inherit; }
.pal-row kbd {
  flex: 0 0 auto;
  font: 500 11px/1 ui-monospace, monospace;
  padding: 3px 6px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.pal-empty { padding: 18px 12px; color: var(--muted); font-size: 13px; text-align: center; }

.pal-foot {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--muted);
}
.pal-foot kbd {
  font: 500 10.5px/1 ui-monospace, monospace;
  padding: 3px 5px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.pal-foot span { margin-right: 8px; }

/* ------------------------ Выбор способа: две карточки ---------------------- */

/* Кнопка-карточка: заголовок и пояснение под ним. Нужна там, где выбор не
   между «да» и «нет», а между двумя разными обещаниями, и решать надо зная,
   чем платишь. */
.ways { display: grid; gap: 8px; margin: 12px 0 4px; }
.ways .way {
  display: block; width: 100%; height: auto;
  padding: 11px 13px; text-align: left; white-space: normal;
}
.ways .way b { display: block; font-size: 13.5px; margin-bottom: 4px; }
.ways .way .way-note {
  display: block; font-size: 12px; line-height: 1.45; opacity: .72; font-weight: 400;
}
.ways .way.primary .way-note { opacity: .85; }

/* -------------------- Поле правки направляющей на холсте ------------------- */

/* Поле встаёт прямо у линии, а не в панели: точную работу делают глядя на
   холст, и уводить туда-сюда глаза не на что. */
.guide-input {
  position: absolute; z-index: 30; width: 74px;
  height: 24px; padding: 0 7px;
  background: var(--panel); color: var(--text);
  border: 1px solid #ffb020; border-radius: 6px;
  font: inherit; font-size: 12px;
  box-shadow: 0 6px 18px rgba(0,0,0,.5);
}
.guide-input:focus { outline: none; border-color: #ffb020; }

/* ---------------------------- Контекстное меню ---------------------------- */

.ctx {
  /* fixed, а не absolute: координаты приходят от события в системе окна
     (clientX/clientY), а меню лежит внутри #stage — при absolute они
     складывались с отступом сцены, и меню выскакивало ниже и правее
     курсора ровно на высоту шапки и ширину рельса. */
  position: fixed; z-index: 40; min-width: 190px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 9px; padding: 5px;
  box-shadow: 0 12px 34px rgba(0,0,0,.55);
  /* Длинное меню (у направляющей их десяток) не должно уходить за низ окна */
  max-height: calc(100vh - 24px); overflow-y: auto;
}
.ctx.hidden { display: none; }
.ctx-item {
  display: block; width: 100%; text-align: left;
  height: 27px; padding: 0 9px;
  background: none; border: 0; border-radius: 6px;
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
}
.ctx-item:hover { background: var(--accent); color: #fff; }
.ctx-sep { height: 1px; background: var(--line); margin: 4px 6px; }
/* Строка с подменю: «Выровнять ▸». Знак — общий шеврон, повёрнутый вправо;
   заводить ради него отдельный символ незачем (G2, 3 сентября 2026) */
.ctx-item.ctx-sub { display: flex; align-items: center; gap: 8px; }
.ctx-sub-mark {
  width: 12px; height: 12px; flex: 0 0 12px; margin-left: auto;
  transform: rotate(-90deg); opacity: .7;
}
/* Подменю лежит при body, а не внутри меню: длинное меню прокручивается, и
   вложенный список обрезался бы его собственной прокруткой */
.ctx-fly { position: fixed; z-index: 41; min-width: 200px; }

/* --------------------------------- Статус --------------------------------- */

/* Тонкая черта внутри группы переключателей: отделяет просмотр и цветопробу
   от подгонки вида — это разные занятия, хотя кнопки стоят рядом. */

/* -------------------------- Диалоги: буфер и экспорт ----------------------- */

.notice.clip {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border-color: var(--accent);
  background: #22304c;
}
.notice.clip .clip-info { display: flex; flex-direction: column; gap: 1px; }
.notice.clip .sub { color: var(--muted); font-size: 12.5px; }

.export-list {
  max-height: 190px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 8px;
  padding: 4px; margin-bottom: 12px;
}
.export-row {
  display: flex; align-items: center; gap: 8px;
  height: 26px; padding: 0 6px; border-radius: 5px;
  font-size: 13px; cursor: pointer;
}
.export-row:hover { background: var(--panel-2); }
.export-row .name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.export-row .sub { color: var(--muted); font-size: 12px; }

/* Подпись над набором кнопок в шапке: одно слово на несколько выходов.
   Мельче и тусклее самих кнопок — она называет, а не предлагает нажать. */
/* Экспорт — кнопка со стрелкой (split button): слева дело, справа выбор.
   Три ярлыка формата рядом с синей кнопкой ушли 3 сентября 2026: четыре
   кнопки на один вывод не говорили, какая из них главная.
   Половинки — одна плашка: синее слово и серая стрелка без скруглений на
   стыке. Владелец 4 сентября 2026: стрелка стояла отдельным синим квадратом
   со всеми четырьмя углами — правило `.topbar .btn.tiny.primary` с большим
   весом перебивало её радиус, и «одна кнопка» разваливалась на две. */
.split { display: inline-flex; align-self: center; margin-left: 4px; }
.topbar .split .btn.tiny { margin-left: 0; height: 22px; }
.topbar .split .split-main { border-radius: 6px 0 0 6px; }
.topbar .split .split-arrow {
  border-radius: 0 6px 6px 0; min-width: 0; width: 20px; padding: 0;
  justify-content: center; background: var(--panel-2); color: var(--text);
  border-left: 1px solid var(--line);
}
.topbar .split .split-arrow:hover { background: var(--hover, #3a3a3a); }
.split .split-arrow svg { width: 13px; height: 13px; }
/* «Экспорт» — тот же ярлык, что и раньше, только синий */
.topbar .btn.tiny.primary {
  height: 22px; padding: 0 8px; margin-left: 4px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; border-radius: 6px;
}

.group-label {
  font-size: 11.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  align-self: center;
  margin-right: 2px;
  white-space: nowrap;
}

/* Шаблоны плитками по три в ряд: строкой во всю ширину три штуки съедали
   полколонки. Имя не показываем — вместо него буква, та же, что стоит на
   миниатюре страницы; всё остальное ушло в подсказку. */
.mp-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  padding: 2px;
}
.mp-tile {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 4px;
  cursor: pointer;
  background: var(--panel-2);
}
.mp-tile:hover { border-color: var(--accent, #4f8cff); }
.mp-tile.sel { border-color: var(--accent, #4f8cff); box-shadow: 0 0 0 1px var(--accent, #4f8cff) inset; }
/* Заведён и никому не назначен — приглушаем: по ленте видно, что он лишний */
.mp-tile.idle { opacity: .55; }
.mp-tile .mp-pic { display: grid; place-items: center; min-height: 42px; }
.mp-tile canvas { display: block; max-width: 100%; }
.mp-letter {
  position: absolute; left: 4px; top: 4px;
  min-width: 15px; height: 15px; padding: 0 3px;
  display: grid; place-items: center;
  border-radius: 4px;
  background: var(--accent, #4f8cff); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 1;
}
/* Кнопок на плитке больше нет: они вспыхивали под курсором, идущим к соседнему
   шаблону, и удаление случалось нечаянно. Удалить, продублировать и назначить —
   правой кнопкой; назначить ещё и перетаскиванием на страницу (ui/masters.js) */
.mp-tile.dragging { opacity: .5; }

/* Буква шаблона поверх миниатюры страницы — внизу по центру, как просил
   владелец. Полупрозрачная подложка: под ней бывает и белый лист, и тёмная
   фотография, и буква обязана читаться на обоих. */
.pg-thumb { position: relative; }
.pg-master {
  position: absolute; left: 50%; bottom: 1px; transform: translateX(-50%);
  min-width: 13px; padding: 0 3px;
  border-radius: 3px;
  background: rgba(0, 0, 0, .62); color: #fff;
  font-size: 9.5px; font-weight: 700; line-height: 13px;
  text-align: center;
  pointer-events: none;
}
.pg-master.hidden { display: none; }

/* ------------------------------- Настройки -------------------------------- */

/* Разделы слева, содержимое справа: язык, ножницы и обновления перестали
   лежать одним свитком. Ширина окна задаётся здесь — раньше правила
   .settings стояли в файле дважды, и вторая пара переписывала первую. */
.settings { min-width: 0; }
.settings h3.sub {
  margin: 4px 0 10px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}

.set-split {
  display: grid;
  grid-template-columns: 168px 1fr;
  gap: 20px;
  margin-top: 14px;
  align-items: start;
}
.set-nav { display: flex; flex-direction: column; gap: 2px; }
/* Разделов мало — столбец слева не нужен: вкладки встают строкой сверху, и
   окно возвращается к обычной ширине. Разбор 4 сентября 2026, п. 102: в
   браузере разделов ровно два, и колонка в 168 точек показывала две строки,
   отнимая треть широкого окна. Столбец полей при этом не трогаем — галочки и
   поля как стояли одним столбцом, так и стоят. */
.settings.flat .set-split { grid-template-columns: 1fr; gap: 12px; }
.settings.flat .set-nav {
  flex-direction: row; gap: 4px;
  border-bottom: 1px solid var(--line); padding-bottom: 8px;
}
.settings.flat .set-tab { padding: 5px 12px; }
.set-tab {
  appearance: none;
  text-align: left;
  padding: 7px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--fg);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 7px;
  cursor: pointer;
}
.set-tab:hover { background: var(--panel-2); }
.set-tab.on {
  background: var(--sel-bg, rgba(79, 140, 255, .16));
  border-color: var(--accent, #4f8cff);
}
/* Высота окна не прыгает при переключении раздела: короткий раздел не должен
   собирать окно в гармошку, длинный — уезжать за экран */
/* Высота ЗАДАНА, а не «от и до»: пока стояло min/max, окно дышало под каждый
   раздел — «Интерфейс» 502 px, «О программе» 443, и переключение вкладки
   дёргало карточку. Владелец просил зафиксировать. Короткий раздел теперь
   оставляет пустое место внизу, и это честная плата: прыгающее окно мешает
   больше, чем пустота.

   min-width: 0 — по той же причине, что и у самой карточки: колонка
   содержимого не должна распирать окно под свою самую длинную строку. */
.set-body {
  height: clamp(320px, 60vh, 500px);
  overflow-y: auto;
  padding-right: 4px;
  min-width: 0;
}
.set-pane { min-width: 0; }
.set-pane.hidden { display: none; }

/* Один столбец управления на весь раздел.
   Раньше краёв было три: подписи полей слева, поля и их подсказки с отступом
   144 px, а галочки со своими подсказками — снова у левого края, с отступом 23.
   Получалась лесенка, и владелец назвал это сбитыми рядами. Теперь слева
   только подписи полей, а всё, чем человек управляет — поля, галочки, кнопки —
   и все подсказки начинаются с одного места. */
.settings .row { align-items: center; margin-bottom: 10px; }
.settings .row label { flex: 0 0 136px; line-height: 1.3; }
.settings .row .field { flex: 1 1 auto; min-width: 0; }
.settings .row + .opt-hint { margin-left: 144px; }
/* Сверху отбивка больше, чем снизу: подсказка предыдущей настройки иначе
   упирается в следующую галочку, и глазом они читаются как один блок */
.settings .opt { margin: 16px 0 12px 144px; }
.settings .opt .opt-hint { margin-left: 0; }
.settings .actions { margin-top: 18px; }
.opt { margin-bottom: 10px; }
.opt-main { display: flex; align-items: center; gap: 8px; cursor: pointer; }
/* margin: 0 — у флажка есть своё умолчательное поле (в Chromium 3px 3px 3px 4px),
   и оно сдвигало галочки на четыре пикселя вправо от столбца полей */
.opt-main input { width: 15px; height: 15px; margin: 0; accent-color: var(--accent, #5b8cff); }
.opt-main span { font-size: 13.5px; }
.opt-hint {
  margin: 4px 0 0 23px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
}
.opt-hint.sys { margin-top: 6px; }
.opt-hint.hidden { display: none; }
.settings .row.off { opacity: .45; }
.field.key { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; text-align: center; }
.field.key.waiting { outline: 1px solid var(--accent, #5b8cff); color: var(--muted); }

/* -------------------------------- Вкладки --------------------------------- */

/* Полотно со своими вкладками и строкой состояния — одна колонка на всех */
.stagewrap { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.stagewrap > #stage { flex: 1 1 auto; min-height: 0; }

/* ---------------------------- Строка состояния ---------------------------- */
/*
   Под холстом, во всю его ширину, ровно 24 точки. Решение владельца
   3 сентября 2026 (A3, A4): десять значков в два ряда в правом нижнем углу
   колонки съедали 80 точек высоты у панели свойств и не отвечали ни на один
   вопрос, который задают на ходу, — где курсор, какого размера то, что я
   тяну, и что сделает Shift.

   Три части: слева координаты и подсказка, по центру масштаб, справа единица
   и переключатели вида. Раздвигают их две пружины `.sb-spring` — масштаб
   стоит по СЕРЕДИНЕ строки, а не там, куда его вытолкнет длина подсказки.

   Строка не переносится и не растёт: `white-space: nowrap` и `overflow:
   hidden`. Порядок, в котором она ужимается, назван владельцем 4 сентября
   2026 (п. 97): СНАЧАЛА подсказка к жесту, ПОТОМ координаты, сообщение —
   последним. До этого дня подсказка и сообщение делили нехватку поровну, и в
   окне 1280 были обрезаны оба: сообщение — то, что программа сказала прямо
   сейчас, и терять его последнюю половину нельзя. Порядок задан не рукой, а
   долями сжатия: у подсказки она в тысячу раз больше, чем у сообщения, и
   flexbox отдаёт нехватку ей, пока та не сойдёт на нет.
*/
/* Рост 28 и кегль 12 — с 4 сентября 2026: при 24 значки справа читались
   плохо (владелец). Кнопки в строке — 22 */
.statusbar {
  flex: 0 0 auto; height: 28px;
  display: flex; align-items: center; gap: 12px;
  padding: 0 10px;
  background: var(--panel); border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12px; line-height: 1;
  white-space: nowrap; overflow: hidden;
  user-select: none;
}
.statusbar > * { flex: 0 0 auto; }
.statusbar .sb-spring { flex: 1 1 0; min-width: 0; }
/* Числа моноширинные: иначе от «9» к «188,5» строка дёргается на каждом
   движении руки, а глаз ловит именно движение.

   Ширина держится снизу (п. 98, 4 сентября 2026): от «X 9 · Y 9 мм» к
   «X 1234,5 · Y 1234,5 мм» коробка росла на добрую сотню точек и толкала
   вправо всё, что за ней, — подсказку и сообщение. Пол взят по самому
   длинному значению, какое здесь бывает; ниже него координаты не ужимаются
   ни при какой тесноте, а ужимаются они вторыми — после подсказки, но раньше
   сообщения. */
.sb-pos {
  font-variant-numeric: tabular-nums; color: var(--text);
  flex: 0 20 auto; min-width: 152px;
  overflow: hidden; text-overflow: ellipsis;
}
.sb-pos:empty { display: none; min-width: 0; }
.sb-pos b { font-weight: 600; }
/* Подсказка к жесту — серым и мельче: её читают краем глаза. Ужимается
   ПЕРВОЙ: она объясняет, а сообщение и координаты отвечают о том, что
   происходит сейчас */
.sb-hint {
  flex: 0 1000 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis;
  opacity: .8;
}
.sb-hint:empty { display: none; }
.sb-sep { width: 1px; height: 16px; background: var(--line); }

/* Последнее сообщение программы и журнал сеанса (G7).
   Стоит сразу за подсказкой к жесту, ужимается многоточием и щёлкается —
   щелчок открывает журнал. Ошибка помечена красной точкой и крестиком: она
   висит, пока её не закроют, и обычные сообщения её не вытесняют. */
.sb-msg {
  /* Ужимается ПОСЛЕДНИМ (п. 97): доля сжатия единица против тысячи у
     подсказки и двадцати у координат */
  flex: 0 1 auto; min-width: 0;
  display: inline-flex; align-items: center; gap: 2px;
}
.sb-msg.hidden { display: none; }
.sb-msg-open {
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; min-width: 0;
  height: 20px; padding: 0 6px; border: 0; border-radius: 5px;
  background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 12px; cursor: pointer;
  overflow: hidden;
}
.sb-msg-open:hover { background: var(--hover); }
.sb-msg-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--danger); flex: none; }
.sb-msg.err .sb-msg-open { color: var(--danger); }
.sb-msg-x {
  width: 16px; height: 16px; padding: 0; border: 0; border-radius: 4px;
  background: none; color: var(--muted); font: inherit; font-size: 13px;
  line-height: 1; cursor: pointer; flex: none;
}
.sb-msg-x:hover { background: var(--hover); color: var(--text); }

/* Полоса хода долгой работы. Одна на всю работу — вместо череды сообщений
   «страница 7 из 60», которые и мельтешили, и ничего не говорили о том,
   сколько ещё ждать. */
.sb-prog { flex: 0 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 8px; }
.sb-prog.hidden { display: none; }
.sb-prog-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.sb-prog u {
  display: block; width: 120px; height: 3px; flex: none;
  border-radius: 2px; background: rgba(128, 128, 128, .35);
  overflow: hidden; text-decoration: none;
}
.sb-prog i {
  display: block; height: 100%; width: 0; border-radius: 2px;
  background: var(--accent); transition: width .18s ease-out;
}
.sb-prog.endless i { width: 34%; animation: tertsia-endless 1.1s ease-in-out infinite; }

/* Журнал сеанса: время слева, текст справа, новые сверху. Высота ограничена —
   двести строк иначе уехали бы за край экрана. */
.log-pop { width: 420px; max-height: 320px; overflow: auto; padding: 6px; }
.log-head {
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); padding: 2px 6px 6px;
}
.log-row { display: flex; gap: 8px; padding: 3px 6px; border-radius: 5px; font-size: 12px; }
.log-row:hover { background: var(--hover); }
.log-row.err .log-text { color: var(--danger); }
.log-row.empty { color: var(--muted); }
.log-time { flex: none; color: var(--muted); font-variant-numeric: tabular-nums; }
.log-text { min-width: 0; }
/* Масштаб. Кнопки 20 точек — строка всего 24, и 24-точечная кнопка в неё не
   влезает вовсе */
.statusbar .zoom { display: flex; align-items: center; gap: 2px; }
.statusbar .zoom .btn {
  height: 22px; min-height: 22px; padding: 0 6px; border-radius: 5px;
  font-size: 12px;
}
.statusbar .zoom .btn.icon { width: 22px; min-width: 22px; padding: 0; }
.statusbar .zoom .btn svg { width: 16px; height: 16px; }
.statusbar .zoom #zoom-label {
  min-width: 48px; justify-content: center; font-variant-numeric: tabular-nums;
}
.statusbar .zoom .zoom-sep { width: 1px; align-self: stretch; margin: 3px 2px; background: var(--line); }
/* Чип единицы: единственное место в строке, где написано слово, — потому и
   выделен цветом текста, а не серым */
.sb-unit .unit-chip {
  height: 22px; min-height: 22px; padding: 0 8px; border-radius: 5px;
  font-size: 12px; font-weight: 600;
}
.sb-view { display: flex; align-items: center; gap: 8px; }
.sb-view .vt-group { display: flex; gap: 2px; }
.sb-view .btn.small.icon {
  width: 22px; height: 22px; min-height: 22px; padding: 0; border-radius: 5px;
  flex: 0 0 auto;
}
.sb-view .btn svg { width: 17px; height: 17px; }
/* Включённое — синим на плашке. Кроме линеек и привязок: они включены по
   умолчанию, и вечно горящая плашка не значит ничего (владелец 3 сентября
   2026). У этих двоих говорит обратное состояние — выключенные приглушены. */
.sb-view .btn.active { background: var(--accent); color: #fff; }
.sb-view .btn.dim { opacity: .4; }
/* --------------------------- Вкладки документов --------------------------- */
/*
   Живут в СЕРЕДИНЕ ШАПКИ, между «отменить · повторить · история» и «проверка ·
   экспорт · настройки» (п. 77, вариант A, решение владельца 4 сентября 2026:
   «вкладки переезжают в шапку»). Отдельная полоса над холстом занимала целую
   строку экрана ради того, что помещается в пустое место, которое в шапке и
   так было; холст стал на неё выше, а линейки начинаются сразу под шапкой.

   Шапку в настольной версии тянут за пустое место (`-webkit-app-region: drag`),
   и середина рядом с вкладками остаётся таким местом: из перетаскивания
   исключено только то, по чему щёлкают (см. `.tab, .tab-list, .tab-new` ниже).
   Погасить его на всё гнездо нельзя — тогда окно перестало бы браться за
   самую широкую свою часть.
*/
.doc-tabs {
  flex: 1 1 auto; min-width: 0;
  align-self: stretch;
  display: flex; align-items: center; gap: 4px;
  /* Кластер вкладок стоит посередине шапки. `safe` — на случай, когда вкладок
     больше, чем влезает: без него лента при переполнении уезжает левым краем
     за предел прокрутки, и первую вкладку не достать ничем. */
  justify-content: safe center;
  padding: 0 6px;
}
/* Из перетаскивания окна исключено то, по чему щёлкают: иначе щелчок по
   вкладке ловило бы окно, а не она. Пустая середина рядом с вкладками при
   этом остаётся ручкой окна. */
.tab, .tab-list, .tab-new { -webkit-app-region: no-drag; }
/* Прокручивается ЛЕНТА, а не всё гнездо: кнопка со списком проектов и «+»
   стоят рядом с ней и уезжать вместе с вкладками не должны */
.tab-strip {
  flex: 0 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 3px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tab-strip::-webkit-scrollbar { display: none; }
/*
   Ширина вкладки: 220 обычно, 120 в тесноте, 360 когда документ открыт один.
   Решение владельца 4 сентября 2026: «пусть, если документ открыт один,
   вкладка будет широкой, чтобы имя максимально влезало; при открытии второй
   они уже будут меньше».

   Считает это флексбокс, а не скрипт: ширина — желаемая, `min-width` — предел
   сжатия. Пока вкладки помещаются, они делят середину поровну; когда перестают
   помещаться даже по 120, лента прокручивается и появляется кнопка со списком.
*/
.tab {
  flex: 0 1 auto;
  width: 220px; min-width: 120px;
  display: flex; align-items: center; gap: 6px;
  height: 23px;
  padding: 0 4px 0 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: none;
  color: var(--muted);
  font-size: 12.5px;
  cursor: default;
  user-select: none;
}
/* Документ один — вкладке отдаётся вся середина, до 360 точек: длинное имя
   вроде «Подача Заказчику финал.trts» должно влезать целиком, а не обрываться
   при том, что справа пусто. */
.tab-strip.one .tab { width: 360px; }
.tab:hover { color: var(--text); background: var(--panel-2); }
/* Вкладка в руке: полупрозрачна — видно, что её ведут */
.tab.dragging { opacity: .65; }
.tab.active {
  background: var(--panel-2);
  border-color: var(--line);
  color: var(--text);
}
.tab-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tab.dirty .tab-name::after { content: ' •'; color: var(--accent); }
.tab-x {
  flex: 0 0 auto;
  width: 17px; height: 17px;
  display: grid; place-items: center;
  border: none; border-radius: 5px;
  background: transparent; color: inherit;
  font-size: 14px; line-height: 1;
  cursor: pointer; opacity: .5;
}
.tab-x:hover { background: var(--line); opacity: 1; }
/* «+» — новый документ. Стоит справа от вкладок, как в любом браузере и в
   Photoshop: рядом с тем, к чему прибавляет. Из шапки за ним ушла отдельная
   кнопка «Новый документ» — два входа в одно дело в одной полосе. */
.tab-new {
  flex: 0 0 auto;
  width: 22px; height: 22px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid transparent; border-radius: 6px;
  background: none; color: var(--muted);
  cursor: pointer;
}
.tab-new svg { width: 15px; height: 15px; }
.tab-new:hover { background: var(--panel-2); color: var(--text); }

.size-note { margin: -2px 0 8px; font-size: 12px; color: var(--muted); }

/* ------------------------- Выбор цвета за плашечкой ------------------------ */

.cp-swatch {
  flex: 1 1 auto; min-width: 0; height: 28px;
  border: 1px solid var(--line); border-radius: 7px;
  cursor: pointer; padding: 0;
  box-shadow: inset 0 0 0 2px rgba(0,0,0,.18);
}
.cp-swatch:hover { border-color: var(--accent); }
/* «Без заливки» — красная диагональ на клетке */
.cp-swatch.none {
  background:
    linear-gradient(to top right, transparent 46.5%, #ff5c5c 46.5%, #ff5c5c 53.5%, transparent 53.5%),
    repeating-conic-gradient(var(--chip-b) 0% 25%, var(--chip-a) 0% 50%) 50% / 12px 12px;
}

.cp-pop {
  position: fixed; z-index: 70; width: 248px;
  max-height: calc(100vh - 16px); overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 18px 48px rgba(0,0,0,.55);
  padding: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.cp-head { display: flex; align-items: center; gap: 8px; }
.cp-headcol { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cp-preview {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: 8px; border: 1px solid var(--line);
}
.cp-hex { height: 26px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.cp-name { font-size: 11px; color: var(--muted); min-height: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.cp-svwrap { position: relative; }
.cp-sv { display: block; width: 100%; height: 130px; border-radius: 8px; cursor: crosshair; }
.cp-huewrap { position: relative; }
.cp-hue { display: block; width: 100%; height: 14px; border-radius: 7px; cursor: crosshair; }
.cp-dot {
  position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border: 2px solid #fff; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,.6);
  pointer-events: none;
}
.cp-dot.hue { top: 50%; }

.cp-rows { display: flex; flex-direction: column; gap: 6px; }
.cp-row { display: flex; gap: 6px; }
.cp-mini { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 4px; }
.cp-mini span { color: var(--muted); font-size: 11px; flex: 0 0 auto; }
.cp-num { height: 24px; padding: 0 4px; font-size: 12px; }
.cp-num::-webkit-inner-spin-button { display: none; }

.cp-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.cp-chip {
  width: 22px; height: 22px; padding: 0;
  border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.cp-chip:hover { border-color: #fff; }

.cp-tabs { display: flex; gap: 5px; }
.cp-tabs .btn.small.active { background: var(--accent); color: #fff; }
.cp-lib { display: flex; flex-direction: column; gap: 6px; }
.cp-lib.hidden { display: none; }
.cp-search { height: 26px; font-size: 12.5px; }
.cp-libgrid {
  display: flex; flex-wrap: wrap; gap: 4px;
  max-height: 148px; overflow-y: auto; padding: 2px;
}
.cp-chip.lib { width: 20px; height: 20px; border-radius: 5px; }
.cp-empty { color: var(--muted); font-size: 12.5px; padding: 6px 2px; }
.cp-note { color: var(--muted); font-size: 11px; line-height: 1.4; }

/* Градиент в поповере цвета */
.cp-grad { display: flex; flex-direction: column; gap: 6px; }
.cp-grad.hidden { display: none; }
.cp-gradbar { height: 22px; border-radius: 7px; border: 1px solid var(--line); }
.cp-gradstops { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.cp-chip.sel { outline: 2px solid var(--accent); outline-offset: 1px; }
.cp-at { width: 44px; flex: 0 0 44px; }

/* Кривые и уровни */
.curves-preview { display: block; width: 100%; border-radius: 8px; border: 1px solid var(--line); margin-bottom: 8px; }
.curves-canvas { display: block; width: 100%; border-radius: 8px; border: 1px solid var(--line); cursor: crosshair; margin-bottom: 4px; }

/* Цветовой диапазон: слева оригинал, справа то, что выделится */
.crange-pair { display: flex; gap: 8px; margin-bottom: 8px; }
.crange-canvas { display: block; width: 50%; height: auto; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); }
.crange-canvas.pick { cursor: crosshair; }
.crange-swatches { display: flex; flex-wrap: wrap; gap: 4px; min-height: 16px; margin-bottom: 4px; }
.crange-chip { width: 16px; height: 16px; border-radius: 4px; border: 1px solid var(--line); }

/* Ручки кисти по правой кнопке: строки-ползунки внутри контекстного меню */
.ctx-brush { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; min-width: 260px; }
.ctx-brush .row { display: flex; align-items: center; gap: 8px; }
.ctx-brush .row > label { flex: 0 0 72px; color: var(--muted); font-size: 12px; }
.ctx-brush input[type=range].field { width: 108px; flex: 0 0 108px; }

/* Панель истории */
.history-pop { position: absolute; z-index: 45; min-width: 220px; }
.history-pop .ctx-item.current { background: var(--accent); color: #fff; }
/* Исходное состояние — не правка: серым и без номера, как в Photoshop.
   Разбор 4 сентября 2026, п. 106 */
.history-pop .ctx-item.history-base { color: var(--muted); }
.history-pop .ctx-item.history-base.current { color: #fff; }

/* -------------------- Полоса опций активного инструмента ------------------- */

/* Полоса переносится на вторую строку, а не уезжает вбок.
   Горизонтальная прокрутка прятала половину параметров за краем окна: увидеть
   их можно было, только прокрутив полосу, о чём ничто не говорило. Двух строк
   хватает на любой инструмент; всё, что не поместилось и в них, прокручивается
   уже по вертикали — там полоса хотя бы видна целиком. */
/* Свойства инструмента: плавающая полоса над панелью инструментов.
   Прежде она стояла под шапкой и занимала всю ширину окна постоянной высотой
   в 58 px — холст терял эту полосу всегда, даже когда показывать было нечего.
   Здесь она висит над панелью, живёт по ширине содержимого и исчезает вовсе,
   когда у инструмента настроек нет. */
.tool-options {
  position: absolute; z-index: 6;
  /* По середине — полями, а не `left: 50%` со сдвигом. У абсолютной полосы с
     `left: 50%` доступная ширина — ПОЛОВИНА полотна, и полоса, ужимаясь по
     содержимому, вставала уже своих ручек: у текста коробка 656 при
     содержимом 886, хвост резался, а свёртка «⋯» считала, что всё влезло
     (замер 3 сентября 2026). С полями слева и справа доступна вся ширина */
  left: 12px; right: 12px; width: fit-content; margin: 0 auto;
  /* Ровно над панелью инструментов: её отступ снизу плюс её высота плюс просвет */
  bottom: calc(var(--bar-lift) + var(--bar-h) + 8px);
  display: flex; align-items: center;
  gap: 4px 10px;
  max-width: 100%;
  padding: 5px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  white-space: nowrap;
}
.tool-options::-webkit-scrollbar { display: none; }
/* Полоса опций живёт в одну строку поверх холста, и каждый лишний пиксель в
   ней — это то, что не влезло на маленьком экране. Ползунок и список тут
   узкие: точное число набирают в поле рядом, а ползунком водят на глаз.
   Владелец 1 сентября 2026: «ширина второго бара снизу не влезает в экран,
   и причём не влезает прилично». */
.tool-options input[type="range"].field { width: 108px; flex: 0 0 auto; min-width: 108px; }
.tool-options select.field { max-width: 132px; }
.tool-options .field { min-width: 0; }
/* «Ещё» — то, что не влезло. Кнопка узкая: место в полосе и так кончилось */
.tool-options .to-more { flex: 0 0 auto; width: 26px; min-width: 26px; padding: 0; font-size: 15px; line-height: 1; }
.more-pop { min-width: 248px; }
.tool-options .row > label { flex: 0 0 auto; }
.tool-options.hidden { display: none; }

/* Слева — кто сейчас в руке. Photoshop называет инструмент в самой полосе,
   и без подписи непонятно, чьи параметры показаны. */
.tool-options .to-tool {
  display: flex; align-items: center; gap: 6px;
  flex: 0 0 auto; padding-right: 2px;
  font-size: 12px; color: var(--text);
}
.tool-options .to-tool svg { width: 16px; height: 16px; opacity: .85; }
.tool-options .to-tool .to-name { font-weight: 600; white-space: nowrap; }
.tool-options .to-tool kbd {
  font: 600 10.5px/1 ui-monospace, monospace;
  padding: 3px 5px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.tool-options .to-sep {
  flex: 0 0 auto; width: 1px; height: 18px; background: var(--line);
}
.tool-options .row.tight label { min-width: 0; }
.tool-options .row.tight input[type=number].field { width: 54px; flex: 0 0 54px; }
.tool-options .rowbtns { display: flex; gap: 3px; flex: 0 0 auto; margin: 0; }
.tool-options .rowbtns .btn.small { padding: 0 6px; height: 24px; }
.tool-options .row { display: flex; align-items: center; gap: 6px; margin: 0; flex: 0 0 auto; }
.tool-options .row label { flex: 0 0 auto; font-size: 12px; color: var(--muted); }
.tool-options .field { height: 24px; }
.tool-options input[type=number].field { width: 58px; flex: 0 0 58px; }
.tool-options select.field { width: auto; flex: 0 0 auto; }
/* Ползунки жёсткости и плотности были 96 px: на всю шкалу от нуля до ста
 * процентов приходилось меньше сотни точек, и поставить, скажем, 35 % было
 * делом удачи. Владелец 28 августа: «сглаживание и растушёвка краёв имеют
 * очень маленькие диапазоны» — диапазон-то полный, мал был сам ползунок.
 * Полоса плавающая и прокручивается, места ей не жалко. */
/* Ползунок в полосе — одной ширины у всех инструментов: 108, как у кисти.
   Было два правила (84 и 168), и у ластика с выделением области ползунок
   выходил вдвое шире соседнего (владелец 3 сентября 2026) */
.tool-options input[type=range].field { width: 108px; flex: 0 0 108px; }
/* А вот у кисти ползунков в полосе четыре разом — толщина, жёсткость,
 * плотность и нажим, — и по 168 px они не помещаются даже на большом
 * мониторе: полоса сворачивала половину из них под кнопку «ещё», то есть
 * ровно туда, откуда их 2 сентября 2026 и попросили достать. Здесь ход
 * короче, и это не откат правки 28 августа: точное число набирается в поле
 * рядом с ползунком, которого тогда не было вовсе. Ползунок — чтобы вести
 * и смотреть на след, поле — чтобы поставить ровно 35 %. */
/* Ход у кисти ещё короче: с 4 сентября 2026 в полосе рядом стоят миниатюра с
   именем кисти, плотность и режим наложения (пп. 84, 104), и на прежних 108
   плотность с режимом уезжали под «⋯» даже в окне 1440. Восемь точек хода —
   та цена, за которую они остаются на виду; точное число по-прежнему
   набирается в поле рядом и тянется скрабом за подпись. */
.tool-options .row.brushrow input[type=range].field {
  width: 100px; flex: 0 0 100px; min-width: 100px;
}
.tool-options .row.brushrow .slider-val { width: 38px; flex: 0 0 38px; padding: 0 4px; text-align: right; }
.tool-options .cp-swatch { width: 40px; flex: 0 0 40px; height: 22px; }
.tool-options .slider-val { flex: 0 0 auto; }
/* Подсказки к жесту в полосе больше нет (п. 80, 4 сентября 2026): те же слова
   стояли в строке состояния под холстом, и человек читал их дважды. Правило
   `.to-hint` ушло вместе с ней — вернётся только вместе с решением вернуть
   саму подсказку. */

/* Имя взятой кисти рядом с её миниатюрой (п. 104). Сто десять точек и
   многоточие: длинное имя загруженного набора («Charcoal Pencil Large»)
   вытеснило бы из полосы целую ручку. Когда и этого места нет, имя уходит
   первым — это делает `свернутьЛишнее` в ui/props.js. */
.tool-options .to-tipname {
  max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11.5px; color: var(--text);
}
/* Список цветов градиента — по самому длинному пункту, а не по общему пределу
   в 132 точки: «Основной → прозрачный» обрезалось до «Основной → фо…», и все
   три набора выглядели одинаково (п. 83, 4 сентября 2026). */
.tool-options .row.wideselect select.field { max-width: none; }
/* Подпись ползунка — ручка: тянешь вбок, число идёт следом (п. 81). Тот же
   жест, что у подписей в панели свойств, — значит и тот же курсор. */
.tool-options .row > label.pp-scrub,
.pop-rows .row > label.pp-scrub { cursor: ew-resize; user-select: none; }
.tool-options .row > label.pp-scrub:hover,
.pop-rows .row > label.pp-scrub:hover { color: var(--text); }
.tool-options .btn.small { flex: 0 0 auto; height: 24px; }

/* ------------- Плавающая полоса действий у выделенного объекта ------------ */

/* Стоит под рамкой выделения и ходит за ней (B5, `syncSelActions` в app.js).
   Вид — тот же, что у полосы опций: тёмная плашка со скруглением и тенью,
   иконки в 32 пикселя высотой. Место ставится из скрипта, поэтому здесь ни
   left, ни top нет — только то, как она выглядит. */
.sel-actions {
  position: absolute; z-index: 6;
  display: flex; align-items: center; gap: 2px;
  height: 32px; padding: 0 4px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
  white-space: nowrap;
}
.sel-actions.hidden { display: none; }
.sel-actions .btn.small.icon { width: 26px; height: 26px; }
.sel-actions .to-sep { flex: 0 0 auto; width: 1px; height: 18px; margin: 0 2px; background: var(--line); }
/* Кнопка с кареткой: тот же знак, что у наборов кисти, и то же место — угол */
.sel-actions .btn.has-chev { width: 34px; gap: 1px; }
.sel-actions .btn.has-chev .chev { width: 9px; height: 9px; opacity: .7; }
/* Меню выравнивания: две строки значков — шесть по краям и три по просветам.
   Столбиком из девяти строк оно было бы вдвое выше самого объекта */
.align-pop {
  display: grid; grid-template-columns: repeat(3, 30px); gap: 2px;
}
.align-pop .btn.small.icon { width: 30px; height: 30px; }

/* Единица документа: не поле, а метка, по которой щёлкают */
.unit-chip {
  min-width: 30px; padding: 0 7px;
  color: var(--muted); font-weight: 600;
}
.unit-chip:hover { color: var(--text); }
/* Единица — переключатель, а не текст: у неё должна быть кромка, иначе о том,
   что по ней щёлкают, не догадаться (владелец 3 сентября 2026) */
.unit-chip { border: 1px solid var(--line); border-radius: 5px; }
/* Подсказка в правой колонке — одной строкой, полный текст по наведению */
#props .hintline.clamp { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: help; }

/* Заголовок ужимается, кнопки — никогда: иначе значки складывались в стопку
   и уезжали за край узкой колонки */
.panel-head > span:first-child {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.panel-head .head-btns { display: flex; gap: 4px; flex: none; }

/* --------------------------- Сворачивание панелей ------------------------- */
/*
   Три панели в колонке 288 пикселей делили высоту поровну, и списку слоёв на
   полтора десятка объектов доставалось окошко в четыре строки. Теперь любую
   можно свернуть до заголовка щелчком по нему — как в Photoshop и Figma.
*/

.panel-head { cursor: pointer; user-select: none; gap: 6px; }
.panel-head:hover { color: var(--text); }
.panel-head .head-btns { cursor: default; }

/* Треугольник состояния слева от названия. Повёрнут вниз у раскрытой панели,
   вправо у свёрнутой — движение то же, что у папок в любом дереве. */
.panel-head > span:first-child::before {
  content: '';
  display: inline-block;
  width: 0; height: 0;
  margin-right: 7px;
  vertical-align: 1px;
  border: 4px solid transparent;
  border-top-color: currentColor;
  opacity: .65;
  transition: transform .12s ease;
}
.panel.collapsed .panel-head > span:first-child::before {
  transform: rotate(-90deg) translateY(2px);
}
@media (prefers-reduced-motion: reduce) {
  .panel-head > span:first-child::before { transition: none; }
}

/* Свёрнутая панель отдаёт всю высоту соседям и оставляет только заголовок */
.panel.collapsed { flex: 0 0 auto !important; min-height: 0 !important; }
.panel.collapsed > *:not(.panel-head) { display: none; }

/* Крестик у предложения восстановить работу: убирает запасную копию совсем */
.notice-x { width: 26px; padding: 0; font-size: 15px; line-height: 1; opacity: .6; }
.notice-x:hover { opacity: 1; }

/* Утилита скрытия. Раньше `.hidden` был определён только у отдельных
   элементов (.popover, .ctx, #rulers…), а на всех прочих класс молча ничего
   не делал: собственный `display` элемента побеждал при равной
   специфичности. Из-за этого не скрывались, например, подсказка про
   PrintScreen в настройках и параметры неактивного фильтра. */
.hidden { display: none !important; }

/* Значок маски в строке слоя: приглушён обычно, подсвечен во время правки */
.lay-badge { display: inline-flex; align-items: center; opacity: .55; margin-right: 4px; }
.lay-badge svg { width: 13px; height: 13px; }
.lay-badge.on { opacity: 1; color: var(--accent, #4c8dff); }
/* Значок цепочки перетекания: связь плюс своё место в ней — «2/3». Номер
   мелкий и рядом со звеном, чтобы читалось одним взглядом. */
.lay-badge.chain { gap: 2px; opacity: .75; }
.lay-badge.chain .lay-badge-num { font-size: 10px; color: var(--muted); }

/* --- Пустой старт ---------------------------------------------------------
   Раньше программа встречала модальным окном создания холста: чтобы просто
   перетащить в неё картинку, окно приходилось сначала закрыть. Теперь пусто —
   это нормальное состояние с подсказкой и кнопками, а перетаскивание работает
   прямо сквозь него. */
.empty {
  position: absolute; inset: 0; display: grid; place-items: center;
  pointer-events: none;               /* перетаскивание файлов проходит насквозь */
  z-index: 5;
}
.empty-card {
  pointer-events: auto;
  display: flex; flex-direction: column; gap: 14px;
  /* Ширины хватает всему ряду быстрого запуска в одну строку: пять карточек
     с просветами. На 420 px ряд переносился, и экран разъезжался по высоте. */
  width: 596px; max-width: 88vw;
  color: var(--muted);
}
/* Рамка-приёмник: пунктир говорит «сюда можно бросить» без единого слова */
.empty-drop {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 34px 28px; text-align: center;
  border: 1.5px dashed var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, .015);
}
.empty-title { font-size: 15px; font-weight: 600; color: var(--fg, #e8eaf0); letter-spacing: .2px; }
.empty-sub { font-size: 12.5px; line-height: 1.5; }
.empty-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 8px; }
.empty-restore { width: 100%; }

/* --- Быстрый запуск на пустом экране ------------------------------------ */
/* Ряд форматов, как на стартовом экране InDesign: лист в своих пропорциях,
   имя, размер. Рисуем тем же способом, что и карточки в окне создания, —
   один визуальный язык на две двери в одну и ту же вещь. */
/* --- Панель инструментов внизу -------------------------------------------
   Оторвана от края и от полосы состояния, как в Figma. Плавающая панель
   выигрывает не красотой: инструменты стоят у самой руки, а не у дальнего
   края экрана, и на широком мониторе до них не тянутся через всю ширину.
   Прежний вертикальный рельс слева — в метке ui-before-figma. */
.toolbar {
  position: absolute; z-index: 6;
  /* Та же посадка, что у полосы опций над ней: полями, а не `left: 50%` */
  left: 12px; right: 12px; width: fit-content; margin: 0 auto;
  bottom: var(--bar-lift);
  display: flex; align-items: center; gap: 2px;
  padding: 5px;
  max-width: 100%;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 13px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.toolbar .tb-group { display: flex; align-items: center; gap: 2px; flex-wrap: nowrap; }
/* Инструменты режима — единственное, что может не поместиться: их набор
   меняется, а ход по документу и режимы постоянны */
.toolbar #tb-tools { overflow-x: auto; scrollbar-width: none; }
.toolbar #tb-tools::-webkit-scrollbar { display: none; }
.toolbar .tb-sep { width: 1px; align-self: stretch; margin: 3px 5px; background: var(--line); }
/* `flex: 0 0 auto` не украшение: без него кнопки сжимались, когда набор
   инструментов не помещался в ширину панели. Мерили 29,7 px вместо 34, и
   ряд разъезжался — плашки цвета с их честными 34 стояли выше соседей.
   Не помещается — панель прокручивается, а не плющит значки. */
.toolbar .btn.tool {
  flex: 0 0 auto;
  width: 34px; height: 34px; padding: 0;
  justify-content: center; background: transparent; border-radius: 9px;
}
.toolbar .btn.tool:hover { background: var(--panel-2); }
.toolbar .btn.tool.active { background: var(--accent); color: #fff; }
.toolbar .btn.tool svg { width: 19px; height: 19px; }

/* Шеврон гнезда — как в Figma (E2, решение владельца 3 сентября 2026).
   Не отдельная кнопка, а узкая зона в 14 px, прижатая к значку отрицательным
   отступом и без своего фона: фон появляется только под курсором.
   Прежняя каретка была полноценной кнопкой со своим фоном и своей шириной, и
   шесть таких читались как второй ряд кнопок. Владелец: «в Figma стрелка явно
   относится к своему инструменту, потому что стоит вплотную и она узкая;
   у нас блок огромный и непонятно, к чему он». */
.toolbar .tool-pair { display: flex; align-items: center; }
.toolbar .tool-chev {
  flex: 0 0 auto; width: 14px; height: 34px; padding: 0;
  margin-left: -3px;
  display: grid; place-items: center;
  background: transparent; border: 0; border-radius: 6px;
  color: var(--muted); cursor: pointer;
}
/* 9 px — тот размер, при котором шеврон читается стрелкой и не спорит со
   значком инструмента рядом. Рисуется своим символом (`i-chev-slot`): общий
   `i-chev` собран в сетке 24 и на этом размере теряет штрих */
.toolbar .tool-chev svg { width: 9px; height: 9px; }
.toolbar .tool-chev:hover { background: var(--panel-2); color: var(--text); }

/* Цвет кисти и фона: две плашки внахлёст, как в Photoshop, только лёжа.
   Стоит отдельной пачкой — разделитель слева и по 12 px воздуха с обеих
   сторон (E3, вариант A, решение владельца 3 сентября 2026). Пока пара стояла
   вплотную к последнему гнезду, она читалась ещё одной кнопкой панели, хотя
   это не инструмент и не режим.

   Числа тут меньше двенадцати, потому что воздух складывается: у панели своя
   щель между детьми (`gap: 2px`), у разделителя — поле 5 px, у переключателя
   режимов — отступ 6 px. Слева выходит 5 + 2 + 5 = 12 до черты разделителя,
   справа 4 + 2 + 6 = 12 до черты режимов. */
.toolbar .swatches { display: flex; align-items: center; gap: 3px; margin-left: 5px; margin-right: 4px; }

/* Режимы — третья часть панели, отделённая. Раньше стояли в шапке, где
   терялись среди кнопок вывода; здесь они рядом с тем, на что влияют.
 *
 * Отделены ТЕМ ЖЕ, чем отделены остальные части полосы, — вертикальной чертой
 * `.tb-sep` в разметке, а не своим `border-left`: две разные черты в одной
 * полосе читаются как разное деление, хотя делят одинаково. И сама группа
 * стоит на плашке потемнее — режим не инструмент, и рядом с инструментами он
 * выглядел ещё двумя кнопками того же ряда (A6, владелец 3 сентября 2026).
 *
 * Активный режим горит ровно так же, как активный инструмент, — синей
 * заливкой (E5). Жирное слово на сером было третьим языком подсветки в одной
 * полосе, и по нему нельзя было сказать, выбран режим или просто подсвечен.
 */
.toolbar .modes {
  display: flex; gap: 2px; margin: 0 0 0 2px;
  padding: 3px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--line);
}
.toolbar .modes .mode {
  padding: 0 11px; height: 28px; border-radius: 7px;
  background: none; border: 0; color: var(--muted);
  font: inherit; font-size: 12.5px; cursor: pointer; white-space: nowrap;
}
.toolbar .modes .mode:hover { background: var(--panel-2); color: var(--fg, #e8eaf0); }
.toolbar .modes .mode.active {
  background: var(--accent); color: #fff; font-weight: 600; box-shadow: none;
}

/* --- Полосы прокрутки ----------------------------------------------------
   Лежат поверх холста, как линейки: полоса появляется и исчезает по ходу
   работы, и пересчитывать из-за неё размер холста — лишний повод для дрожания
   картинки. Тонкие и всегда видимые, а не всплывающие: их задача — постоянно
   отвечать, где ты в документе. */
.scrollbar {
  position: absolute; z-index: 4;
  background: rgba(0, 0, 0, .22);
}
.scrollbar.h { left: 0; right: 11px; bottom: 0; height: 11px; }
.scrollbar.v { top: 0; bottom: 11px; right: 0; width: 11px; }
.scrollbar .thumb {
  position: absolute; border-radius: 6px;
  background: rgba(200, 208, 222, .34);
}
.scrollbar .thumb:hover { background: rgba(200, 208, 222, .52); }
.scrollbar.h .thumb { top: 2px; bottom: 2px; min-width: 26px; }
.scrollbar.v .thumb { left: 2px; right: 2px; min-height: 26px; }

/* Пропорции и ориентация в одной строке: обе про форму листа */
.row.orient { display: flex; gap: 6px; align-items: center; }
.row.orient .btn.icon { flex: 0 0 auto; min-width: 30px; }

.quick { width: 100%; }
.quick-head {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); text-align: center; padding-bottom: 10px;
}
.quick-row { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; }
.quick-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  /* Ширины хватает на самое длинное имя в одну строку: «A3 альбомный» на
     прежних 84 px переносился, и весь ряд разъезжался по высоте */
  width: 108px; padding: 10px 6px 9px;
  background: none; border: 1px solid transparent; border-radius: 10px;
  color: var(--fg, #e8eaf0); font: inherit; cursor: pointer; text-align: center;
}
.quick-card:hover { background: var(--hover, rgba(255,255,255,.06)); border-color: var(--line); }
.quick-card b { font-size: 12px; font-weight: 600; white-space: nowrap; }
.quick-card .sub { font-size: 10.5px; color: var(--muted); }
/* Место под лист постоянной высоты: иначе книжный A4 и альбомный A3 растащили
   бы подписи по разным уровням и ряд перестал бы читаться рядом */
/* Место под лист постоянной высоты, и его хватает самому крупному формату:
   иначе ряд поехал бы по вертикали от того, что 4K выше A4 */
.quick-card .paper-wrap { display: grid; place-items: center; height: 44px; margin-bottom: 2px; }
.quick-card .paper {
  display: block; border: 1.4px solid var(--muted); border-radius: 2px;
  background: rgba(255, 255, 255, .04);
}
/* Карточка «Создать документ» шире прочих: имя длиннее, а переносить его
   на две строки — значит растащить ряд по высоте */
.quick-card.other { width: 124px; }
.quick-card.other b { color: var(--accent); }
.quick-card .quick-dots {
  display: grid; place-items: center; width: 30px; height: 30px;
  border: 1.4px solid var(--accent); border-radius: 50%;
  font-size: 17px; line-height: 1; color: var(--accent);
}
.quick-card.other:hover .quick-dots { background: var(--accent); color: #fff; }

/* --- Просмотр: на экране только макет -----------------------------------
   «Убрать всю служебную графику» до сих пор значило «перестать рисовать
   оверлеи на холсте»: рамки выделения, направляющие, подписи страниц. А
   колонки палитр, линейки, полосы прокрутки и обе плавающие панели
   оставались на месте — то есть половина служебной графики никуда не
   девалась, просто она не на холсте, а поверх него.

   Владелец 27 августа: нажал глазик — и «перестало работать перемещение
   колесиком». Так и было: панель инструментов осталась висеть внизу по
   центру, курсор попадал в неё, и колесо доставалось ей, а не холсту.

   Шапку оставляем: из просмотра надо чем-то выйти, а Escape помнят не все.
   Так же устроен режим просмотра в InDesign — панели уходят, меню остаётся. */
body.preview #toolbar,
body.preview #tool-options,
body.preview #sel-actions,
body.preview #rulers,
body.preview .scrollbar,
body.preview #dock-left,
body.preview #dock-right,
body.preview #grip-left,
body.preview #grip-right { display: none !important; }

/* --- Документа нет: рабочего интерфейса тоже -----------------------------
   Photoshop и InDesign до открытия файла не показывают ни одного инструмента.
   Причина простая: без документа они ничего не делают, но занимают весь экран
   и обещают работу, которой пока нет. Остаются только двери, через которые
   документ появляется. */
.no-doc #toolbar,
.no-doc #tool-options,
.no-doc #sel-actions,
/* Линейки и полосы прокрутки — тоже рабочий интерфейс: мерить и листать
   нечего, пока документа нет, а на пустом экране они читаются как обломки */
.no-doc #rulers,
.no-doc .scrollbar,
.no-doc #dock-left,
.no-doc #dock-right,
.no-doc #grip-left,
.no-doc #grip-right,
.no-doc .topbar .sep,
.no-doc .zoom-foot .zoom,
.no-doc [data-needs-doc] { display: none !important; }

/* Последние файлы — список, а не подпись. Раньше заголовок стоял по центру и
   бледный, а под ним одиноко висело имя файла: читалось как сбой отрисовки. */
.empty-recent { display: flex; flex-direction: column; gap: 1px; width: 100%; }
.empty-recent .head {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); padding: 0 8px 5px;
}
.empty-recent .rec {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 6px 8px; border-radius: 7px; background: none; border: 0;
  color: var(--fg, #e8eaf0); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
}
.empty-recent .rec:hover { background: var(--hover, rgba(255,255,255,.06)); }
.empty-recent .rec .name { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empty-recent .rec .where {
  flex: 1 1 auto; min-width: 0; font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left;
}

/* Миниатюра в строке слоя — на месте прежнего значка типа */
.lay-thumb {
  width: 22px; height: 22px; flex: 0 0 22px; border-radius: 3px;
  background: repeating-conic-gradient(var(--chip-b) 0 25%, var(--chip-a) 0 50%) 0 0 / 8px 8px;
  outline: 1px solid rgba(255,255,255,.08); outline-offset: -1px;
}

/* Полосы режима и непрозрачности над списком слоёв больше нет: и то и другое
   живёт разделом «Слой» в панели свойств, первым сверху (B6, F2). Одна и та
   же пара спрашивалась в двух местах, а в узкой колонке слово «Обычный»
   резалось до «Обыч». */

/* --- Цвет кисти и фон -----------------------------------------------------
   Два перекрывающихся квадрата внизу рельса, как в Photoshop: сразу видно,
   чем рисуешь, и куда попадёт X. Раньше цвет был виден только в панели
   опций активного инструмента, а у половины инструментов её нет. */
/* В лежачей панели плашки стоят в один рост с кнопками: прежние поля были
   рассчитаны на вертикальный рельс и здесь растащили бы панель по высоте. */
/* Цвет кисти и фона. Схема прежняя, фотошоповская — две плашки внахлёст, —
   но разложена так, чтобы ничто ни на что не налезало. Переделано
   27 августа 2026, решение владельца.

   Прежняя беда была не в плашках, а в двух мелких кнопках при них. Обмен
   и сброс висели на отрицательных отступах поверх плашек, и на 34 px
   высоты им просто негде было стоять: они наезжали на цвет, друг на друга
   и на край панели. Теперь у блока четыре непересекающихся места —
   плашки по диагонали в середине, обмен в правом верхнем углу, сброс
   в левом нижнем. Ни одного нахлёста, кроме того единственного, который
   и должен быть: кисть поверх фона.

   Плашки выросли до 20×20: на 15 px, как в первом заходе, цвет не читался.

   Ширина блока — ровно 34, как у кнопки инструмента: прежний был шире
   кнопок и ломал ритм рельса ровно в одном месте. Теперь не ломает.

   Размеры мелких кнопок не выбраны на глаз, а посчитаны из одного условия:
   просвет до плашек одинаковый со всех сторон, 2 px. Плашки стоят по 0..20
   и 12..32, значит свободных углов два — верхний правый (x 20..34, y 0..12)
   и нижний левый (x 0..12, y 20..34). Обмену, чтобы отступить на 2 и слева
   от кисти, и сверху от фона, остаётся ровно 10×10 при left 22 top 0;
   сбросу на тех же условиях — 8×8 при left 2 top 22. Отсюда и разные
   размеры: они следствие, а не вкус.

   Сброс стал одним квадратиком, разрезанным по диагонали на чёрное
   и белое. Двух крошечных плашек рядом на 12 px было не разобрать —
   они сливались в серое пятнышко; разрезанный квадрат читается сразу
   и говорит то же самое.

   Край у плашек двойной: тёмный снаружи, светлый внутри. Такой держится
   на любом цвете, каким бы плашку ни залили. Прежний — белый
   полупрозрачный — на светлой плашке исчезал вовсе. */
.swatches { position: relative; width: 34px; height: 34px; flex: 0 0 auto; }
.swatches .sw {
  position: absolute; width: 20px; height: 20px; padding: 0;
  border: 0; border-radius: 4px; cursor: pointer;
  box-shadow: 0 0 0 1px rgba(0,0,0,.65), inset 0 0 0 1px rgba(255,255,255,.45);
}
.swatches .sw-fg { left: 0; top: 0; z-index: 2; }
.swatches .sw-bg { left: 12px; top: 12px; z-index: 1; }

.swatches .sw-swap,
.swatches .sw-reset {
  position: absolute; padding: 0;
  border: 0; cursor: pointer; z-index: 3;
}
.swatches .sw-swap {
  left: 22px; top: 0; width: 10px; height: 10px; border-radius: 2px;
  background: none; color: var(--muted); display: grid; place-items: center;
}
.swatches .sw-swap svg { width: 10px; height: 10px; display: block; }
.swatches .sw-swap:hover { color: var(--text); }
/* Сброс мельче обмена намеренно: обмен нажимают часто, сброс — редко,
   и размер это говорит раньше подписи.
   Углы не скруглены: на восьми пикселях радиус съедает сам угол, и квадрат
   перестаёт быть квадратом — остаётся катышек. Прямой угол на таком размере
   честнее скругления. */
.swatches .sw-reset {
  left: 2px; top: 22px; width: 8px; height: 8px; border-radius: 0;
  background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.65);
}
/* Чёрная половина — треугольник поверх белого квадрата. */
.swatches .sw-reset::before {
  content: ''; position: absolute; inset: 0;
  background: #000; clip-path: polygon(0 0, 100% 0, 0 100%);
}
.swatches .sw-swap:active, .swatches .sw-reset:active { transform: scale(.92); }
.swatches .sw-reset:hover { transform: scale(1.12); }
/* Пипетка стоит рядом с цветами, а не только в рельсе: берут её ради них */

/* --------------------------- Настройка макета ---------------------------- */
/*
 * Окно сетки: слева миниатюра страницы, справа схемы и числа. Миниатюра не
 * украшение — четыре числа полей сами по себе не читаются, «18 и 25» это
 * широкий корешок или узкий, видно только на картинке. В InDesign это окно
 * устроено так же и по той же причине.
 */
.layout-dlg { min-width: 0; }
.layout-body { display: flex; gap: 18px; align-items: flex-start; }
.layout-prev {
  flex: 0 0 auto; width: 176px; min-height: 176px;
  display: flex; align-items: center; justify-content: center;
  padding: 4px; border-radius: 6px; background: var(--bg-soft, rgba(128,128,128,.08));
}
.layout-side { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 12px; }

/* Схемы сетки — свой класс, не `layout-card`: тот уже занят карточками
 * форматов, коллажей и шаблонов, и общее имя молча переписывало их вид */
.grid-schemes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.grid-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 7px 4px; height: auto; line-height: 1.2;
}
/*
 * Выбранная схема и схема под фокусом должны различаться с одного взгляда.
 * Пока выбор рисовался только цветной рамкой, он выглядел ровно как обычное
 * кольцо фокуса браузера: на снимке владельца 27 августа синими оказались две
 * карточки сразу — выбранная и та, по которой щёлкнули последней. Поэтому
 * выбор — это заливка и цвет подписи, а фокус — отступающая рамка снаружи.
 */
.grid-card.on {
  border-color: var(--accent); color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--panel-2));
}
.grid-card.on .grid-card-pic { opacity: 1; }
.grid-card:focus-visible { outline: 2px dashed var(--accent); outline-offset: 2px; }
.grid-card:focus:not(:focus-visible) { outline: none; }
.grid-card-pic { display: block; opacity: .85; }
.grid-card-name { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.grid-own { color: var(--muted); font-size: 12px; align-self: center; }

.layout-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--muted); margin-top: 2px;
}
.layout-head span:first-child { flex: 1 1 auto; }
.layout-chain.on { color: var(--accent); }
.layout-num { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--muted); }
.layout-num .field { width: 100%; }

/* Кнопка во всю ширину колонки: «Настройка макета» — единственное, что там
 * теперь есть от сетки, и жаться ей не к чему */
.btn.wide { width: 100%; justify-content: center; margin-top: 6px; }

/* ---------------------------- Мастер-макеты ------------------------------ */
/*
 * Третья панель левой колонки. Растёт по содержимому и не спорит с делителем
 * страниц и слоёв: шаблонов обычно один-два, и отдавать им долю высоты наравне
 * со списком страниц было бы расточительно.
 */
.mp-list { flex: 1 1 auto; overflow-y: auto; padding: 2px 5px 5px; min-height: 0; }
/* Правила `.mp-empty` больше нет: пустой список молчит, а о том, что шаблонов
   нет, говорит строка заголовка (п. 93, 4 сентября 2026) */

/* Строчной раскладки у шаблонов больше нет — они плитками (`.mp-tile` выше).
   Правила `.mp-row`, `.mp-text`, `.mp-del`, `.mp-all` и ширина `.mp-pic`
   пережили переезд и продолжали работать: `.mp-pic { width: 48px }` стояло
   ниже `.mp-tile .mp-pic`, перебивало его ширину, и лист внутри рамки стоял
   прижатый влево, а не по центру. Владелец 31 августа 2026: «рамочка
   мастер-макета не по центру находится лист внутри» */
.mp-thumb { border-radius: 2px; box-shadow: 0 0 0 1px rgba(128,128,128,.45); background: #fff; }

/* Строка, на которую сейчас роняют шаблон */
.pg-row.drop-master { outline: 2px solid var(--accent, #4f8cff); outline-offset: -2px; }

.mp-assign { display: flex; flex-direction: column; gap: 3px; padding: 6px 2px 2px; }
.mp-assign label { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Недавние цвета: два ряда по шесть — ровно дюжина, которую помнит модуль.
 * Ряд появляется, только когда есть что показать: пустая полоса в палитре,
 * и без того плотной, была бы чистой потерей высоты. */
.cp-recent { display: flex; flex-direction: column; gap: 4px; }
.cp-recent-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.cp-recent-grid .cp-chip { width: 100%; }

/* Полоска хода работы. Держится, пока идёт дело, — у хода работы нет причины
 * исчезать по таймеру, а собрать PDF из двадцати листов может занять десятки
 * секунд, за которые обычное сообщение успевает пропасть. */
.toast.progress { display: flex; flex-direction: column; gap: 6px; align-items: stretch; min-width: 240px; }
.toast.progress u { display: block; height: 3px; border-radius: 2px; background: rgba(128,128,128,.35); overflow: hidden; text-decoration: none; }
.toast.progress i { display: block; height: 100%; width: 0; border-radius: 2px; background: var(--accent); transition: width .18s ease-out; }
/* Сколько всего — неизвестно: полоска ходит из края в край и не врёт о доле */
.toast.progress.endless i { width: 34%; animation: tertsia-endless 1.1s ease-in-out infinite; }
@keyframes tertsia-endless { 0% { margin-left: -34%; } 100% { margin-left: 100%; } }

/* Миниатюра маски слоя. Меньше миниатюры самого слоя и с рамкой: это не
 * содержимое, а то, чем оно закрыто, — и путать их нельзя. */
.lay-mask-thumb {
  display: block; width: 18px; height: 18px; border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(128,128,128,.55); background: #fff;
}
.lay-badge.on .lay-mask-thumb { box-shadow: 0 0 0 2px var(--accent); }

/* --------------------------------- Навигатор ------------------------------ */
/* Карта перерисовывается редко, рамка ездит каждый кадр — поэтому она узел
 * поверх, а не часть картинки: двигать style дешевле, чем перерисовывать сцену. */
.nav-body { padding: 6px; }
/* Рамка видимого бывает шире самой карты — когда в окно влезает больше,
 * чем есть в документе. Прячем вылезшее, иначе она лезет на соседние
 * панели колонки */
.nav-wrap { position: relative; display: block; cursor: pointer; overflow: hidden; }
.nav-map { display: block; border-radius: 4px; background: var(--bg-soft, rgba(128,128,128,.10)); }
.nav-view {
  position: absolute; pointer-events: none;
  border: 1.5px solid var(--accent); border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

/* Вторая строка панели слоёв: сколько нашлось и кнопка «взять всё найденное».
   Нужна там, где список отобран фильтром: без неё полсотни штрихов подряд
   приходилось брать по одному (владелец 3 сентября 2026) */
.lay-find-row2 { display: flex; align-items: center; gap: 8px; padding: 0 8px 6px; }
.lay-find-row2 .lay-find-note { padding: 0; }
/* `flex: 0 0 auto` перебивает ширину значка-кнопки (`.lay-chip` — 22 точки):
   здесь кнопка со словами, и жить ей по мерке значка не с чего */
.lay-take-all { margin-left: auto; white-space: nowrap; padding: 2px 8px; width: auto; flex: 0 0 auto; }

/* Обводки нет — толщина и штрих приглушены, но видны: так понятно, что они
   есть и чего ждут. Раньше их прятала галочка, и о них нельзя было узнать */
.stroke-off > .row:not(:first-child) { opacity: .5; }

/* ========================================================================== *
 *              Панель свойств — по макетам, принятым 3 сентября 2026
 *
 * Своя система классов (`pp-`), а не правка общих `.row` и `.field`: те же
 * классы носит полоса параметров инструмента и все диалоги, и подтягивание
 * их под колонку 288 px ломало бы окна. Здесь всё считано на эту ширину.
 *
 * Мерки взяты с макета: поле 26 точек, радиус 7, просвет между строками 6,
 * заголовок раздела 11,5 px прописными.
 * ========================================================================== */

/* Шапка панели свойств — это шапка ОБЪЕКТА: значок, имя, глаз, замок.
   Прописных и разрядки здесь нет: имя объекта пишут как имя, а не как
   ярлык раздела. */
.panel.props > .panel-head {
  height: 32px;
  text-transform: none; letter-spacing: 0; font-weight: 400;
  font-size: 13px; color: var(--text);
  justify-content: flex-start;
}
.panel.props > .panel-head > .pp-head-ic {
  flex: 0 0 auto; overflow: visible; display: inline-flex; align-items: center; color: var(--muted);
}
.panel.props > .panel-head > .pp-head-ic svg { width: 15px; height: 15px; }
.pp-head-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: text;
}
.pp-head-sub { flex: 0 0 auto; color: var(--muted); font-size: 11.5px; }
.pp-head-edit {
  flex: 1 1 auto; min-width: 0; height: 22px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--accent); border-radius: 5px; padding: 0 5px; font: inherit;
}
.pp-head-edit:focus { outline: none; }

/* --------------------------------- Разделы -------------------------------- */

.pp-sec { padding: 8px 0 9px; }
.pp-sec + .pp-sec { border-top: 1px solid var(--line); }
#props > .pp-sec:first-child { padding-top: 2px; }
.pp-sec > h3 {
  margin: 0 0 7px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted); font-weight: 700;
  display: flex; align-items: center; gap: 4px;
}
/* «+», «⋯» и «?» прижаты к правому краю заголовка: слева имя, справа то, что
   с разделом делают */
.pp-sec > h3 > .pp-ic:first-of-type, .pp-sec > h3 > .pp-help { margin-left: auto; }
.pp-sec > h3 > .pp-ic ~ .pp-ic, .pp-sec > h3 > .pp-help ~ .pp-ic { margin-left: 0; }
/* Раздел, у которого нечего настраивать, гаснет целиком, но остаётся виден:
   пропавший раздел человек ищет, погасший — понимает */
.pp-sec.pp-dim > *:not(h3) { opacity: .55; }

/* Свёрнутый раздел: имя видно, места не занимает */
.pp-fold > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; gap: 6px;
}
.pp-fold > summary::-webkit-details-marker { display: none; }
.pp-fold > summary::before { content: '▸'; color: var(--muted); font-size: 10px; line-height: 1; }
.pp-fold[open] > summary::before { content: '▾'; }
.pp-fold > summary > h3 { margin: 0; flex: 1 1 auto; }
.pp-fold[open] > summary { margin-bottom: 7px; }

/* --------------------------------- Строки --------------------------------- */

.pp-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.pp-row:last-child { margin-bottom: 0; }
/* Строка, где поле стоит под подписью, ровняется по НИЗУ: иначе значки рядом
   с полем уезжают вверх, на уровень подписи */
.pp-row.bot { align-items: flex-end; }
.pp-row.checks { flex-wrap: wrap; gap: 4px 12px; }
.pp-gap { width: 6px; flex: none; }

.pp-g2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 6px 8px; margin-bottom: 6px; }
.pp-g4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 6px; }

.pp-col { display: flex; flex-direction: column; gap: 2px; flex: 1 1 0; min-width: 0; }
/* Подпись — она же ручка скраба (B13). Курсор говорит об этом прямо */
.pp-lab { font-size: 11.5px; color: var(--muted); line-height: 1.2; white-space: nowrap; }
.pp-lab.pp-scrub { cursor: ew-resize; user-select: none; }
.pp-lab.pp-scrub:hover { color: var(--text); }
.pp-lab-row {
  font-size: 11.5px; color: var(--muted); margin: 4px 0 4px;
}

/* --------------------------------- Поля ----------------------------------- */

/* Поле — коробка с числом и серым суффиксом единицы внутри (B1, B12).
   Единица в поле, а не в подписи: подпись «Толщина обводки, мм» не влезала в
   колонку и резалась многоточием. */
.pp-f {
  display: flex; align-items: center; gap: 4px;
  height: 26px; min-width: 0; flex: 1 1 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  padding: 0 7px;
}
.pp-f:focus-within { border-color: var(--accent); }
.pp-f > .pp-in {
  flex: 1 1 0; min-width: 0; width: 100%;
  background: transparent; border: 0; outline: none; padding: 0;
  color: var(--text); font: inherit; font-size: 12.5px; height: 100%;
}
.pp-f > .pp-in::-webkit-inner-spin-button { display: none; }
/* Единица и короткая метка — серым, мельче и в набор не мешаются */
.pp-f > .pp-u { color: var(--muted); font-size: 11.5px; flex: none; margin-left: auto; padding-left: 2px; }
.pp-f > .pp-p { color: var(--muted); font-size: 11.5px; flex: none; }
.pp-f.pct { flex: 0 0 58px; }
/* Ползунок прозрачности: долю подбирают на глаз, ведя мышью и глядя на лист.
   Поворот ползунком при этом убран — угол называют числом (B7) */
.pp-range { flex: 1 1 auto; min-width: 0; height: 18px; padding: 0; border: 0; background: transparent; accent-color: var(--accent); }

.pp-f.narrow { flex: 0 0 76px; }
.pp-f.deg { flex: 0 0 76px; }
/* Под подписью поле стоит в КОЛОНКЕ, и `flex-basis` там значит высоту, а не
   ширину: поле угла вырастало до 76 px в высоту. В колонке поле не тянется */
.pp-col > .pp-f { flex: 0 0 auto; }
.pp-f.off { opacity: .5; }
/* Смешанное значение: «—» вместо числа, «Разные» вместо цвета (B15) */
.pp-f .pp-in.mix, .pp-f.mix, .pp-cv.mix { color: var(--muted); }

.pp-sel { padding-right: 2px; }
.pp-sel > select.pp-in {
  appearance: none; -webkit-appearance: none;
  padding-right: 14px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 5px center, right 1px center;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  color: var(--text);
}
.pp-sel > select.pp-in option { background: var(--panel-2); color: var(--text); }

/* ------------------------------- Кнопки ----------------------------------- */

.pp-ic {
  width: 26px; height: 26px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  color: var(--text); cursor: pointer; padding: 0;
}
.pp-ic svg { width: 15px; height: 15px; }
.pp-ic:hover { background: var(--hover); }
.pp-ic.on { background: var(--accent); border-color: var(--accent); color: #fff; }
/* Бледная кнопка — та, что не про действие, а про состояние: глаз, замок
   пропорций, «убрать». Кромки у неё нет, иначе ряд читается как забор */
.pp-ic.ghost { background: transparent; border-color: transparent; color: var(--muted); }
.pp-ic.ghost:hover { background: var(--hover); color: var(--text); }
.pp-ic[disabled] { opacity: .35; pointer-events: none; }

.pp-btn {
  height: 26px; min-height: 26px; flex: 1 1 auto; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  color: var(--text); font: inherit; font-size: 12.5px; padding: 0 8px; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-btn:hover { background: var(--hover); }
.pp-btn.pri { background: var(--accent); border-color: var(--accent); color: #fff; }
.pp-btn.pri:hover { background: var(--accent-2); }
.pp-btn.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.pp-btn.wide { flex: 1 1 100%; }
.pp-btn.narrow { flex: 0 0 auto; min-width: 30px; padding: 0 6px; }
.pp-btn[disabled] { opacity: .38; pointer-events: none; }

.pp-check {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--muted); font-size: 12.5px; cursor: pointer;
}
.pp-check input { margin: 0; }
#props > .pp-sec > .pp-check { margin-bottom: 6px; }

/* --------------------------- Ряд переключателей ---------------------------- */

.pp-seg { display: flex; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 8px; flex: none; }
.pp-seg .pp-ic { width: 24px; height: 20px; border: 0; background: transparent; border-radius: 6px; }
.pp-seg .pp-ic svg { width: 14px; height: 14px; }
.pp-seg.wide { flex: 1 1 auto; min-width: 0; }
.pp-seg.wide .pp-ic { flex: 1 1 0; width: auto; min-width: 0; }

/* ------------------------------ Строка цвета ------------------------------- */

/* Образец, значение, прозрачность, глаз, «−» — одинаково у заливки, обводки,
   текста, подложки и фона страницы (B10) */
.pp-sw {
  width: 22px; height: 22px; flex: none; padding: 0;
  border-radius: 5px; border: 1px solid var(--line); cursor: pointer;
  background: repeating-conic-gradient(var(--chip-b) 0 25%, var(--chip-a) 0 50%) 0 0 / 8px 8px;
}
/* «Цвета нет» — красная черта наискось, как в палитрах Illustrator */
.pp-sw.none {
  background: linear-gradient(135deg, transparent 45%, #e0322c 45%, #e0322c 55%, transparent 55%),
              var(--panel-2);
}
.pp-sw.mix { background: linear-gradient(135deg, var(--panel-2) 50%, var(--hover) 50%); }

.pp-cv {
  flex: 1 1 0; min-width: 0; height: 26px;
  display: flex; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  padding: 0 7px; color: var(--text); font: inherit; font-size: 12.5px;
  cursor: pointer; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-cv:hover { background: var(--hover); }
/* Значение, по которому не щёлкают: имя эффекта, размер исходника, профиль */
.pp-cv.static { cursor: default; color: var(--muted); }
.pp-cv.static:hover { background: var(--panel-2); }
.pp-cv.grow { flex: 1 1 auto; }

/* --------------------------- Мелочи и подсказки ---------------------------- */

.pp-note { color: var(--muted); font-size: 12px; line-height: 1.45; margin: 4px 0 6px; }
/* Чип «+ Тень»: кнопка, а не подпись (UI-AUDIT 89). Пунктир говорит
   «этого ещё нет», рядом с плотными строками включённых эффектов */
.pp-add {
  height: 24px;
  padding: 0 9px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.pp-row.wrap { flex-wrap: wrap; gap: 5px 6px; }
.pp-add:hover { background: var(--hover); color: var(--text); border-style: solid; }

/* Метка эффективного разрешения (C8): цвет говорит быстрее числа */
.pp-chip {
  display: inline-flex; align-items: center; gap: 6px; flex: 1 1 auto; min-width: 0;
  font-size: 12.5px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-chip > i { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--muted); }
.pp-chip.good > i { background: #3f9a5a; }
.pp-chip.warn > i { background: #e0a020; }
.pp-chip.bad > i { background: #e0322c; }

/* «?» у заголовка раздела: абзац по наведению, щелчок закрепляет (лист
   «Подсказки»). Строк панели подсказка не занимает — раньше такие абзацы
   съедали до трети колонки */
.pp-help { position: relative; display: inline-flex; }
.pp-q {
  width: 16px; height: 16px; padding: 0; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--muted);
  font: 700 10px/1 inherit; cursor: help; text-transform: none;
}
.pp-help:hover .pp-q, .pp-help.pinned .pp-q { color: #fff; background: var(--accent); border-color: var(--accent); }
.pp-pop {
  position: absolute; top: 20px; right: 0; z-index: 40;
  width: 232px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
  color: var(--text); font: 400 12px/1.45 inherit; text-transform: none; letter-spacing: 0;
  display: none;
}
.pp-help:hover .pp-pop, .pp-help.pinned .pp-pop { display: block; }

/* Меню по «+» и «⋯»: список строк поверх всего, как всплывающие списки полосы */
.popover.pp-menu { padding: 4px; min-width: 168px; }
.pp-menu-list { display: flex; flex-direction: column; gap: 1px; }
.pp-menu-item {
  text-align: left; background: transparent; border: 0; border-radius: 6px;
  color: var(--text); font: inherit; font-size: 12.5px; padding: 6px 8px; cursor: pointer;
}
.pp-menu-item:hover { background: var(--hover); }
.pp-menu-item[disabled] { opacity: .38; pointer-events: none; }

/* Ручки эффекта в поповере у шестерёнки: там живут старые контролы, поэтому
   ширину задаём им, а не переписываем каждый */
.pp-fx-pop { width: 244px; }
.pp-fx-pop .row { margin-bottom: 6px; }
