/* Серый — основная тема, с 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;
  /* Ширина колонки инструментов у левого края (решение владельца 5 сентября
     2026). Кнопка 30, по 5 воздуха с боков и место под шеврон гнезда: узко,
     как в Figma и InDesign, а не в две колонки, как было у прежнего рельса до
     27 августа. */
  --rail-w: 44px;
  /* Шеврон «вниз» для знака состояния панели. Лежит переменной, потому что
     маску нельзя собрать из currentColor — это картинка, и её приходится
     писать целиком */
  --chev-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path d="M2.5 4.5 6 8l3.5-3.5" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  /* Кнопка и значок инструмента. Колонка остаётся 44 — её ширину владелец
     менять не велел, — а сам знак растёт: «в фотошопе при меньшей ширине
     колонки инструменты кажутся крупнее» (6 сентября 2026). Так и есть:
     дело не в колонке, а в том, сколько в ней занимает сам значок. Было
     30/18 — знак сидел в кнопке размером в треть её площади. */
  --tool-btn: 34px;
  --tool-icon: 21px;
  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;
}

/* Серый студийный — самый светлый из ряда: панели в середине шкалы, поле
   вокруг листов заметно темнее их.

   Просьба владельца 6 сентября 2026: «цвет интерфейса давай текущий оставим
   как вариант, но добавим серый как в фш (только назовём без фш)». Двух
   имевшихся серых мало: оба — тёмные (панели #212121 и #333333), а речь была
   про средний, при котором лист на экране выглядит листом, а не единственным
   светлым пятном в темноте. Так же устроена мерка у типографов: белое судят
   на среднесером окружении, а не на чёрном.

   Линии тут ТЕМНЕЕ панелей, а не светлее, — на среднем сером светлая черта
   не читается вовсе; это единственная тема, где ряд перевёрнут.
   Имя в настройках — «Светло-серый», без ссылок на чужие программы:
   владелец просил об этом ещё 31 августа. */
:root[data-ui="gray-studio"] {
  --bg: #3f3f3f;
  --panel: #4b4b4b;
  --panel-2: #565656;
  --line: #383838;
  --text: #f0f0f0;
  --muted: #bcbcbc;
  --stage: #282828;
  --checker-a: #333333;
  --checker-b: #3c3c3c;
  --ruler-bg: #4b4b4b;
  --ruler-line: #383838;
  --ruler-text: #bcbcbc;
  --ruler-tick: #838383;
  --hover: #5e5e5e;
  --scroll: #717171;
  --scroll-hover: #848484;
  --chip-a: #525252;
  --chip-b: #5c5c5c;
}

* { 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; }
/* Курсоры соседей при совместной правке в портале (ui/live.js) */
.live-cursors { position: absolute; inset: 0; pointer-events: none; z-index: 40; overflow: hidden; }
.live-cursor { position: absolute; left: 0; top: 0; display: flex; align-items: flex-start; gap: 2px;
  will-change: transform; transition: transform .08s linear; }
.live-cursor span { color: #fff; font: 600 11px/1.4 system-ui, sans-serif; padding: 1px 6px;
  border-radius: 8px; white-space: nowrap; margin-top: 12px; }

#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` нет ни в разметке, ни в скриптах.
   Оставлено на день перестройки интерфейса и уйдёт следующей уборкой. */
.floating-bar {
  position: absolute; left: 50%; bottom: 32px; 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;
}
/* В окнах места хватает: столбец подписей шире, чем в колонке свойств, и
   «Скругление, мм», «Заголовок» не режутся многоточием, а поля по-прежнему
   начинаются от одного края (второй разбор интерфейса, 28 сентября 2026) */
.modal .row > label { flex-basis: 108px; }
/* `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; }
/* Чем хорош выбранный формат — строкой под списком, вровень с полем (подпись
   строки 82 + просвет 8). Разбор 28 сентября 2026, п. 4 */
/* Отступ — столбец подписей окна (108) и зазор строки (8): пояснение стоит
   ровно под списком форматов */
.ex-fmt-hint { margin: -4px 0 10px 116px; }
/* Подзаголовок внутри секции свойств: у группы кнопок есть своё имя, но своей
   секции она не заслуживает. Заведён под подгонку изображения — «во фрейме» и
   «по странице» это две разные работы, и различаться они должны словом, а не
   памятью человека о том, какая кнопка что делает. */
.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 {
  /* По нижнему краю и с отступом снизу — чтобы стоять в одном ряду с
     вкладками, а не на два пикселя выше них (7 сентября 2026) */
  flex: 0 0 auto; align-self: flex-end; margin-bottom: 3px;
  display: flex; align-items: center; gap: 5px;
  height: 21px; padding: 0 7px; margin-left: 6px;
  border: 1px solid var(--line); border-radius: 0;
  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; }

/* Готовое число в полосе опций: измеритель показывает, а не спрашивает */
.tool-options .to-read {
  font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; white-space: nowrap;
}
/* Табло без числа (измеритель до первой протяжки, «Без масштаба»,
   «Замечаний нет») — приглушённо: место то же, но это ещё не ответ */
.tool-options .to-read.dim { color: var(--muted); font-weight: 400; }
/* Отпечаток кисти: показать форму нарисованной, а не тремя числами */
.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); }
/* Окно, которое меняет рост по ходу (экспорт — от формата к формату,
   настройки — от раздела к разделу), стоит от верха, а не по центру: иначе
   оно прыгало вверх-вниз целиком, и список «Формат» уезжал из-под курсора.
   Так стоят палитра команд и окна Linear (второй разбор интерфейса) */
.modal-backdrop.top { place-items: start center; padding-top: 8vh; }
.modal-backdrop.top .modal { max-height: 86vh; }

/* --- Окно создания документа ---------------------------------------------
   Слева форматы вкладками, справа параметры — так устроены «Создать» в
   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; margin-bottom: 0; }
.nd-size .row > label { flex: 0 0 auto; }
.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; align-self: center; }
.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` с 27 августа 2026 прятал и все
   «призрачные» кнопки-значки панели свойств (`.pp-ic.ghost`) — плюс нового
   стиля, дискету, шестерёнку, глазок и минус у цвета. Кнопки были на месте,
   но невидимы и не нажимались. Найдено вторым разбором интерфейса 28 сентября */
.row.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;
}
/* Клавиша — по своей ширине и к описанию, а не плашкой во весь столбец:
   «V» в коробке на 150 точек читалась полем ввода (второй разбор) */
.keys-list .row > kbd { justify-self: end; white-space: nowrap; }
.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; }
/* Карточки — кнопки (29 сентября 2026): до них доходит Tab, Enter и пробел
   выбирают, фокус виден. Раньше это были div — с клавиатуры не выбрать */
button.layout-card { font: inherit; color: var(--text); width: 100%; min-width: 0; }
.layout-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.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); }
/* Два пути PDF в окне вывода — первым выбором, двумя карточками: что человек
   получит, крупно, и чем это сделано, мелко (решение владельца 24.09.2026) */
.ex-paths { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 10px 0 8px; }
.ex-path {
  appearance: none; font: inherit; color: var(--fg); text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
  padding: 9px 10px; display: flex; flex-direction: column; gap: 3px;
}
.ex-path:hover { border-color: var(--accent); }
.ex-path.on { border-color: var(--accent); background: #26314a; }
.ex-path .name { font-size: 13px; font-weight: 600; }
.ex-path .sub { font-size: 11.5px; color: var(--muted); line-height: 1.25; }
.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; }
/* Внутри портала LinesERP: «Ссылка» и «Закрыть» справа в шапке вместо полосы
   портала, перед ними — кто ещё в файле, кружками с буквой (см. ui/portal.js). */
.topbar .portal-group { margin-left: auto; }
.topbar .portal-people { display: inline-flex; gap: 3px; margin-right: 4px; }
.topbar .portal-people:empty { display: none; }
.topbar .portal-man {
  width: 20px; height: 20px; border-radius: 50%; color: #fff; font-size: 10px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
}
.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; }
/* Знак программы перед названием (владелец, 6 сентября 2026). Пропорции у него
   листовые — 352×248, — поэтому ширина и высота разные: квадратная коробка
   сплющила бы уголок. Скругления и тени с иконки сняты: в полосе на 32 точки
   они читаются грязью, а знак узнаётся и без них. */
.topbar .brand .brand-logo {
  width: 17px; height: 12px; flex: none;
  margin-right: 1px;
}

/* ------------------------ Переключателей режимов нет ---------------------- */
/*
   Их было два, и оба сняты решением владельца 5 сентября 2026: вкладки
   инструментов («Дизайн · Рисование») — потому что все инструменты теперь
   стоят разом, колонкой слева и панелью справа; вид документа («Полотно ·
   Издание») — потому что у программы остался один вид, издание.

   Класс `.modes` вместе с ними ушёл из разметки и из скриптов. Разбор, из
   которого режимы когда-то выросли, — в UI.md.
*/

/* ---------------------------- Рельс инструментов -------------------------- */
/*
   Рельс рисуется из каталога (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); }
/* Узкое окно (разбор 28 сентября 2026, п. 9): на 1280 свойства и страницы
   брали 288 + 240 точек, и холсту оставалось чуть больше половины окна.
   Ширина, натянутая человеком, остаётся его, но в окне уже 1366 колонки не
   шире пятой (свойства, не меньше 260 — два поля в строку ещё встают) и
   шестой части окна (страницы, не меньше 220 — три плитки в ряд и с полосой прокрутки). Ещё уже,
   меньше 1200, правая колонка сворачивается в полосу сама
   (`AUTO_FOLD_BELOW` в ui/docks.js) */
@media (max-width: 1365px) {
  .dock-left:not(.collapsed) { width: min(var(--left-w, 240px), max(260px, 20vw)); }
  .dock-right:not(.collapsed) { width: min(var(--right-w), max(220px, 16.5vw)); }
}
.dock.hidden { display: none; }

/* Ручка ширины колонки.
   
   Обработчик на неё был написан давно (`bindColumnGrips` в app.js: протяжка,
   двойной щелчок «вернуть обычную», память между запусками), а СТИЛЯ не было
   НИ ОДНОЙ строки — и голый `div` в строке флексбокса выходил нулевой ширины.
   То есть тянуть было нечего и не за что, и колонки годами стояли по 180
   точек. Владелец 6 сентября 2026: «вроде мы собирались регулировать ширину
   колонок правой и левой перетаскиванием, надо эту функцию добавить».

   Полоса захвата 7 точек и уходит в отрицательные поля: рисованной границей
   остаётся кромка самой колонки, а место под курсор берётся у соседей —
   иначе ручка съедала бы у холста по семь точек с каждой стороны. */
.col-grip {
  flex: 0 0 7px;
  margin: 0 -3px;
  position: relative; z-index: 4;
  cursor: col-resize;
  background: none;
}
.col-grip.hidden { display: none; }
/* Подсветка — тонкой чертой по месту границы, как у ползунка между панелями */
.col-grip::after {
  content: ''; position: absolute; inset: 0 3px;
  background: transparent;
}
.col-grip:hover::after, .col-grip.dragging::after { background: var(--accent); }
/* Пока тянут, курсор держится над всем окном, а не только над полоской */
body.col-resizing { cursor: col-resize; user-select: none; }

/* Колонка под курсором во время переноса */
/* Колонка-цель обведена тонко: главное сообщение теперь несёт черта места
   вставки, а обводка только говорит, в какую из колонок попадём */
.dock.drop { outline: 1px solid var(--accent); outline-offset: -1px; }
/* Черта места вставки: панель встанет ровно сюда. Та же мысль и тот же цвет,
   что у вставки строки в списке слоёв (6 сентября 2026) */
.dock-dropline {
  flex: 0 0 auto;
  height: 2px; margin: -1px 0;
  background: var(--accent);
  border-radius: 2px;
  pointer-events: none;
}
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.
   Холст получает всю ширину, а палитры остаются в одном щелчке. */
/* Ширина 40, а не 30: значки в полосе стали крупнее вместе с тем, что по ним
   теперь ОТКРЫВАЮТ — см. блок «Свёрнутая колонка: панель выпадает окошком»
   в конце файла. */
.dock.collapsed { width: 40px !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). */
/* Размер 32/20, а не 24/17: по значку теперь не разворачивают колонку, а
   открывают саму панель, и это уже не корешок, а кнопка — см. блок
   «Свёрнутая колонка: панель выпадает окошком» в конце файла. */
.dock-tab {
  width: 32px; height: 32px; padding: 0;
  display: grid; place-items: center; margin: 0 auto 3px;
}
.dock-tab svg { width: 20px; height: 20px; }
/* Корешка «группа целиком» со значками столбиком больше нет: с 25 сентября
   2026 у каждой панели группы своя кнопка, такая же, как у одиночной
   (владелец увидел в прежнем «один странный значок»). */

/* Переключателя вида документа («Полотно · Издание») больше нет нигде:
   решение владельца 5 сентября 2026 — «Режим „Полотно“ мы тоже убираем,
   у нас только режим „Издание“». Вместе с ним ушли его правила и здесь,
   и в панели страниц. */

/* Масштаб по строкам колонок больше не кочует: с 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.objects { flex: 30 1 0; min-height: 90px; border-top: 1px solid var(--line); }
.panel.layers { flex: 20 1 0; min-height: 90px; border-top: 1px solid var(--line); }
/* Дополнительные инструменты: растровые гнёзда сеткой значков. Место ей
   нужно ровно по содержимому — шесть-восемь кнопок в два-три ряда, — и
   расти за счёт свойств и слоёв она не должна. */
.panel.extratools { flex: 0 0 auto; 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: 8px 12px 12px;
  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; }
/* Куча одинаковых замечаний (разбор 28 сентября 2026, п. 6): строка сводки
   раскрывается списком. Треугольник справа — где раскрывать, число — сколько */
.pf-bunch > summary { list-style: none; cursor: pointer; border-radius: 6px; padding: 2px 4px; margin: -2px -4px; }
.pf-bunch > summary::-webkit-details-marker { display: none; }
.pf-bunch > summary:hover { background: var(--panel-2); }
.pf-bunch > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.pf-count {
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 1px 6px; border-radius: 8px; background: var(--panel-2); color: var(--text);
}
.pf-more { margin-left: auto; width: 0; height: 0; border: 4px solid transparent; border-top-color: var(--muted); margin-top: 4px; transition: transform .12s; }
.pf-bunch[open] > summary .pf-more { transform: rotate(180deg); margin-top: -4px; }
.pf-bunch-list { margin: 4px 0 0 16px; }
.pf-bunch-list .pf-item:last-child { padding-bottom: 0; }

/* ----------------------------- Панель страниц ----------------------------- */

/* Появляется только когда страниц больше одной — как полоса вкладок.
   Одностраничный документ выглядит ровно как раньше. */
.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; }
/* Заголовок раздела листов — пара «Мастер-макетам» (разбор 28 сентября 2026,
   п. 3). Отбивка сверху: две шапки подряд без воздуха читались одной */
.pg-list-head { margin-top: 4px; }
/* Крупность миниатюр ленты — три ступени справа в заголовке */
.pg-zoom { margin-left: auto; display: inline-flex; gap: 2px; }
.pg-zoom-b {
  width: 20px; height: 18px; padding: 0; display: grid; place-items: center;
  background: none; border: 0; border-radius: 4px; cursor: pointer; color: var(--muted);
}
.pg-zoom-b i { display: block; border: 1.2px solid currentColor; border-radius: 1px; }
.pg-zoom-b:hover { background: var(--hover); color: var(--text); }
.pg-zoom-b.on { color: var(--accent); }
/* Раздел документа — подписью над первой страницей раздела */
.pg-section {
  grid-column: 1 / -1; padding: 8px 4px 3px; font-size: 11px; font-weight: 600;
  /* С overflow: hidden строка сетки ужимается ниже текста — держим высоту */
  min-height: 27px; box-sizing: border-box; flex: none;
  color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pg-section:first-child { padding-top: 2px; min-height: 21px; }
.pg-masters.no-masters .mp-list { display: none; }
/* «нет» — не заголовок, а ответ: без разрядки и прописных, которые несёт само
   слово «Мастер-макеты» */
.pg-masters-none { font-weight: 400; letter-spacing: 0; text-transform: none; }
/* Кнопка «+» видна только в пустой строке: в полосе под списком у неё есть
   близнец (значок шаблона), и вдвоём они звали бы одну команду дважды */
/* «+» рядом с «Мастер-макеты · нет».

   Был текстовым плюсом в сетке 18×18 — и косил: глиф плюса у шрифта стоит
   выше середины строки, а рядом с ним не было ни рамки, ни фона, по которым
   глаз выровнял бы его на место. Владелец 6 сентября 2026: «этот плюсик сделан
   в виде максимально уродливой кнопки, которая перекосила».

   Теперь это обычная кнопка-значок, как «+» у вкладок: тот же символ
   `#i-plus`, та же оправа, тот же размер. Рисованный знак стоит ровно по
   середине сам, без подгонки. */
.pg-masters-add {
  margin-left: auto; flex: 0 0 auto;
  width: 20px; height: 20px; padding: 0;
  display: none; place-items: center;
  border: 1px solid transparent; border-radius: 5px;
  background: none; color: var(--muted);
}
.pg-masters-add svg { width: 13px; height: 13px; display: block; }
.pg-masters-add:hover { background: var(--panel-2); color: var(--text); }
.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: 2px 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: 1px; }
.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-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; }

/* Сетка плиток (ui/pages.js, `GRID_FROM`): лента шире трёх плиток идёт не
   строками, а рядами, как «Pages» в InDesign. Под миниатюрой — номер, имя и
   размер — в подсказке плитки. Прежняя строка на 56 точек показывала
   четыре листа из двадцати четырёх; ряд плиток на 66 точек несёт три. */
.pg-list.grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(62px * var(--pg-k, 1)), 1fr));
  align-content: start; gap: 4px 3px;
}
:is(.pg-list.grid, .pg-spread) .pg-row {
  grid-template-columns: auto 1fr;
  grid-template-areas: "thumb thumb" "num name";
  gap: 1px 3px; padding: 3px 3px 2px; border-radius: 6px;
}
:is(.pg-list.grid, .pg-spread) .pg-thumb {
  grid-area: thumb; width: auto;
  background: none; border: 0; border-radius: 0;
}
:is(.pg-list.grid, .pg-spread) .pg-canvas { box-shadow: 0 0 0 1px var(--line); }
/* Разворот (core/spreads.js): черта у корешка — справа у левой страницы,
   слева у правой. Лента показывает страницы по одной; сторона видна чертой,
   номер разворота — в подсказке */
.pg-row.pg-left .pg-canvas { box-shadow: 0 0 0 1px var(--line), 2px 0 0 0 var(--muted); }
.pg-row.pg-right .pg-canvas { box-shadow: 0 0 0 1px var(--line), -2px 0 0 0 var(--muted); }
:is(.pg-list.grid, .pg-spread) .pg-num { grid-area: num; min-width: 0; text-align: left; font-size: 10.5px; }
:is(.pg-list.grid, .pg-spread) .pg-meta { grid-area: name; }
/* Под плиткой только номер: «1 Страница 1» повторяло его дважды. Владелец
   24 сентября: «Подпись в сетке оставь только номер». Имя — в подсказке
   плитки, переименовать — в строках (узкая колонка); поле правки, если оно
   открыто, остаётся видно. */
:is(.pg-list.grid, .pg-spread) .pg-name { display: none; }
/* Номер занимает всю строку подписи: он же ручка переименования (двойной
   щелчок), а цифра «3» шириной в шесть точек — не мишень. Когда открыто поле
   правки имени, номер уступает ему место справа */
:is(.pg-list.grid, .pg-spread) .pg-num { grid-column: 1 / -1; grid-row: 2; cursor: text; }
:is(.pg-list.grid, .pg-spread) .pg-row:has(.pg-rename) .pg-num { grid-column: 1; }
:is(.pg-list.grid, .pg-spread) .pg-row.sel .pg-num { color: var(--text); }
:is(.pg-list.grid, .pg-spread) .pg-sub { display: none; }
/* Место броска в сетке — черта слева или справа от плитки, а не над ней */
:is(.pg-list.grid, .pg-spread) .pg-row.drop-before::before,
:is(.pg-list.grid, .pg-spread) .pg-row.drop-after::after {
  top: 2px; bottom: 2px; width: 2px; height: auto;
}
:is(.pg-list.grid, .pg-spread) .pg-row.drop-before::before { left: -3px; right: auto; }
:is(.pg-list.grid, .pg-spread) .pg-row.drop-after::after { right: -3px; left: auto; }
/* Развороты парой (`doc.facing`, ui/pages.js): левая и правая страница стоят
   плитками вплотную, миниатюры сходятся у корешка. Первая страница — одна
   справа, место левой пустое: корешки всех пар на одной линии. В сетке пара
   занимает две клетки, в строках — стоит посередине ленты */
.pg-spread { display: flex; justify-content: center; }
.pg-list.grid .pg-spread { grid-column: span 2; }
.pg-spread > .pg-row, .pg-spread > .pg-spread-gap { flex: 0 1 64px; min-width: 0; }
.pg-list.grid .pg-spread > .pg-row, .pg-list.grid .pg-spread > .pg-spread-gap { flex: 1 1 0; }
.pg-spread > .pg-row.pg-left { padding-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.pg-spread > .pg-row.pg-right { padding-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.pg-spread > .pg-row.pg-left .pg-thumb { justify-content: flex-end; }
.pg-spread > .pg-row.pg-right .pg-thumb { justify-content: flex-start; }
.pg-spread > .pg-row.pg-left .pg-num { text-align: right; padding-right: 3px; }
.pg-spread > .pg-row.pg-right .pg-num { padding-left: 3px; }

/* Значок макета: доли страницы прямоугольниками — текст и картинка разным
   рисунком, чтобы макет узнавался с одного взгляда */
.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 точки */
/* Полоса под списком слоёв: что со слоями делают. Прижата к низу панели и
   не прокручивается вместе со списком — до неё должно быть одинаково далеко
   и на трёх слоях, и на сотне */
/* Полоса действий под списком — одна на все панели колонки.
 *
 * У слоёв и страниц она устроена одинаково, и выглядеть должна одинаково:
 * значки посередине, просветы равные, разделители одной длины, кнопка
 * 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; }
.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-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; }
/* Объект на запертом слое документа: строкой не берётся (28 сентября 2026) */
.lay-row.layer-locked { cursor: not-allowed; }
.lay-row.layer-locked .lay-name { font-style: italic; opacity: .6; }
.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; }
/* Значок раздела у команды без своего — бледнее своего (разбор 28 сентября
   2026, п. 8): колонка значков сплошная, а свои картинки не тонут */
.pal-ico.dim { opacity: .38; }
.pal-row.on .pal-ico.dim { opacity: .6; }
.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; }
/* Пункт с клавишей: «Закончить контур    Enter» — клавиша справа и тише, как
   в меню программы (меню пера, 25 сентября 2026) */
.ctx-item.ctx-keyed { display: flex; align-items: center; gap: 18px; }
.ctx-key { margin-left: auto; color: var(--muted); font-size: 12px; }
.ctx-item:hover .ctx-key { color: inherit; opacity: .85; }
/* Строка с подменю: «Выровнять ▸». Знак — общий шеврон, повёрнутый вправо;
   заводить ради него отдельный символ незачем (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; }
.export-row.with-thumb { height: 42px; }
.export-row .thumb { flex: none; border-radius: 2px; box-shadow: 0 0 0 1px var(--line); background: #fff; }
.export-list:has(.with-thumb) { max-height: 260px; }

/* Подпись над набором кнопок в шапке: одно слово на несколько выходов.
   Мельче и тусклее самих кнопок — она называет, а не предлагает нажать. */
/* Экспорт — кнопка со стрелкой (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; }
/* Подпись переносится, а не режется: «Типографика при наб…» обрезалась при
   свободном месте справа (разбор 28 сентября 2026, п. 7). В настройках строка
   одна на настройку, и вторая строка подписи ничего не сдвигает */
.settings .row label { flex: 0 0 136px; line-height: 1.3; white-space: normal; overflow: visible; }
.settings .row .field { flex: 1 1 auto; min-width: 0; }
.settings .row + .opt-hint { margin-left: 144px; }
/* Подсказка под списком держится своей строки: при прежних 8 точках снизу и
   4 сверху она читалась подписью к следующей настройке (второй разбор) */
.settings .row:has(+ .opt-hint) { margin-bottom: 4px; }
.settings .row + .opt-hint { margin-bottom: 14px; }
/* Сверху отбивка больше, чем снизу: подсказка предыдущей настройки иначе
   упирается в следующую галочку, и глазом они читаются как один блок */
.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.flush { margin-left: 0; }
.settings .conn-get { margin-top: 12px; }
.settings a.btn { text-decoration: none; display: inline-flex; align-items: center; }
.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); }

/* -------------------------------- Вкладки --------------------------------- */

/* Рабочая область между колонками: полоса параметров инструмента сверху,
   холст под ней. Строка состояния сюда БОЛЬШЕ НЕ ВХОДИТ — она стоит под всем
   окном, во всю его ширину (решение владельца 5 сентября 2026, см. ниже). */
.stagewrap { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.stagewrap > #stage { flex: 1 1 auto; min-height: 0; }

/* ---------------------------- Строка состояния ---------------------------- */
/*
   Во всю ширину ОКНА, под колонками, 28 точек.

   Решение владельца 5 сентября 2026: «Строка состояния внизу (координаты,
   подсказки, листалка страниц „3 из 3“, масштаб, единицы, кнопки сеток) должна
   занимать всю ширину окна, а колонки стоять над ней, а не по бокам. Сейчас
   она сжата между колонками и в неё ничего не помещается». До этого дня она
   лежала внутри стопки холста: при окне 1280 с двумя раскрытыми колонками ей
   доставалось около семисот точек, и половина её содержимого уезжала за край.
   В InDesign и Photoshop она стоит так же — под всем.

   Заведена 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; }
/* Половины строки (второй разбор интерфейса, 28 сентября 2026): левая
   делит место поровну с правой и ужимается, правая не уже своего
   содержимого — значки вида не обрезаются ни в каком окне. Середина между
   ними стоит на месте, что бы ни писало сообщение слева */
.statusbar > .sb-side {
  display: flex; align-items: center; gap: 12px;
  min-width: 0; overflow: hidden;
}
.statusbar > .sb-l { flex: 1 1 0; }
.statusbar > .sb-r { flex: 1 1 0; min-width: max-content; justify-content: flex-end; }
.sb-side > * { flex: 0 0 auto; }
/* Числа моноширинные: иначе от «9» к «188,5» строка дёргается на каждом
   движении руки, а глаз ловит именно движение.

   Ширина держится снизу (п. 98, 4 сентября 2026): от «X 9 · Y 9 мм» к
   «X 1234,5 · Y 1234,5 мм» коробка росла на добрую сотню точек и толкала
   вправо всё, что за ней, — подсказку и сообщение. Пол взят по самому
   длинному значению, какое здесь бывает; ниже него координаты не ужимаются
   ни при какой тесноте, а ужимаются они вторыми — после подсказки, но раньше
   сообщения. */
/* Версия программы — первым в строке состояния, на месте прежних координат.
   Маленькая «v» и номер, как просил владелец 6 сентября 2026. Кнопкой она
   остаётся: щелчок проверяет обновления, и сюда же служба обновлений пишет
   «Загрузка 42 %» — поэтому ширина не задана, строка то короткая, то длинная. */
.sb-version {
  flex: 0 0 auto;
  border: 0; background: none; color: var(--muted); font: inherit;
  font-size: 12px; font-weight: 500; font-variant-numeric: tabular-nums;
  padding: 2px 6px; border-radius: 5px; cursor: pointer;
}
/* Разбор 28 сентября 2026, п. 10: номер «почти не читался» — 11,5 точки
   приглушённым цветом, да ещё «v» с прозрачностью .6 курсивом. Номер теперь
   цветом подписей строки и в кегль строки, приглушена одна «v» */
.sb-version::before { content: 'v'; opacity: .75; margin-right: 2px; }
.sb-version:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.sb-version:hover { background: var(--panel-2); color: var(--text); }
.sb-version:empty { display: none; }

.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.stale { opacity: .55; transition: opacity .4s; }
.sb-msg.stale:hover { opacity: 1; }
.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); }

/* Живой режим коннектора: снаружи правят этот документ.
   Спокойное и заметное разом — точка и два слова, без мигания и без красного:
   происходящее не беда, но и не мелочь, и знать о нём человек обязан
   постоянно. Приглушённый вид — слушатель включён, никто не подключён; яркий
   с синей точкой — Клод подключён. Щелчок выключает живой режим. */
.sb-conn {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  height: 20px; padding: 0 8px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel-2); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.sb-conn::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--muted);
}
.sb-conn.hidden { display: none; }
.sb-conn:hover { background: var(--hover); color: var(--text); }
.sb-conn.live { color: var(--text); border-color: var(--accent); }
.sb-conn.live::before { background: var(--accent); }

/* Полоса хода долгой работы. Одна на всю работу — вместо череды сообщений
   «страница 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;
}
/* Путь вывода в шапке — два положения, «Экран · RGB | Печать · CMYK»
   (редизайн 29 сентября 2026). Печать с включённой цветопробой — точка
   акцентом: экран показывает цвета печати, и человек видит почему */
.purpose-seg {
  display: inline-flex; align-items: center; gap: 2px; padding: 2px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  -webkit-app-region: no-drag;
}
.topbar .purpose-seg .purpose-opt {
  height: calc(var(--top-btn) - 6px); padding: 0 9px; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted); font-size: 12px; gap: 6px;
}
.topbar .purpose-seg .purpose-opt:hover { color: var(--text); }
.topbar .purpose-seg .purpose-opt.on { background: var(--hover); color: var(--text); font-weight: 600; }
.purpose-seg .purpose-opt.proof::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none;
}
/* Кнопка показа — рядом с «Экспортом», словом: второй выход документа */
.topbar .present-btn svg { width: 16px; height: 16px; }
/* Поиск команд — похож на поле, а открывает палитру (Ctrl+K) */
.topbar .cmd-search {
  height: var(--top-btn); min-width: 180px; padding: 0 6px 0 9px;
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  color: var(--muted); font: inherit; font-size: 12.5px; cursor: pointer;
}
.topbar .cmd-search:hover { color: var(--text); border-color: var(--scroll); }
.topbar .cmd-search svg { width: 14px; height: 14px; flex: none; }
.topbar .cmd-search kbd {
  margin-left: auto; font: 500 10.5px ui-monospace, Consolas, monospace; color: var(--muted);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px;
}
/* В тесном окне поиск сжимается до значка: вкладкам место нужнее */
@media (max-width: 1180px) {
  .topbar .cmd-search { min-width: 0; width: var(--top-btn); padding: 0; justify-content: center; }
  .topbar .cmd-search span, .topbar .cmd-search kbd { display: none; }
}
@media (max-width: 1000px) {
  .topbar .present-btn span { display: none; }
}
.sb-view { display: flex; align-items: center; gap: 8px; }
.sb-view .vt-group { display: flex; gap: 2px; align-items: center; }
/* Подпись группы переключателей — мелко и серым; в тесном окне уходит */
.sb-view .vt-label { font-size: 10.5px; color: var(--muted); margin-right: 3px; letter-spacing: .02em; }
@media (max-width: 1360px) { .sb-view .vt-label { display: none; } }
.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; }
/* Один язык на ВСЕ переключатели строки состояния: включённое — синим,
   выключенное — приглушено. Исключений нет ни у линеек, ни у привязки
   (владелец 5 сентября 2026: «Нужно, чтобы все были либо белая, либо серая,
   либо синим выделялись, потому что они сейчас ведут себя по-разному»).
   С 29 сентября 2026 синим горит САМ ЗНАЧОК на лёгкой подложке, а не белый
   значок на синей плашке: семь сплошных синих плашек подряд читались одной
   полосой, и включённое не отличалось от выключенного с первого взгляда */
.sb-view .btn.active { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.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; gap: 4px;
  /* Вкладки прижаты ВЛЕВО, к тому месту, где кончаются кнопки файла и отмены.
     Решение владельца 6 сентября 2026: «вкладки нужно по левой стороне
     выровнять». Посередине они стояли с 4 сентября и читались плохо: при
     одном документе широкая плашка висела ровно под серединой окна, ни к чему
     не привязанная, — глаз принимал её за поле ввода имени, а не за вкладку.
     Слева она стоит там же, где вкладки в браузере, InDesign и Photoshop. */
  justify-content: flex-start;
  /* По НИЖНЕМУ краю, а не по середине: вкладки садятся на дно шапки, и кнопка
     списка с «плюсом» стоят в одном ряду с ними. Пока середина ровняла всё
     подряд, обе кнопки висели на два-три пикселя выше вкладок — ряд читался
     не рядом, а тремя вещами, сложенными рядом. */
  align-items: flex-end;
  padding: 0 6px;
}
/* Из перетаскивания окна исключено то, по чему щёлкают: иначе щелчок по
   вкладке ловило бы окно, а не она. Пустая середина рядом с вкладками при
   этом остаётся ручкой окна. */
.tab, .tab-list, .tab-new { -webkit-app-region: no-drag; }

/*
   Три ступени яркости: шапка → неактивная вкладка → активная.

   Считаются от цвета панелей, а не берутся готовыми токенами, — и в этом вся
   правка 7 сентября 2026. Прежде неактивная брала `--chip-a`, активная
   `--panel-2`, и молча предполагалось, что первый темнее второго. Ни в одной
   из четырёх тем это не так: в серой они СОВПАДАЮТ до байта (оба #2b2b2b), в
   остальных расходятся на две-четыре ступени из 255. Ряд вкладок читался одной
   сплошной полосой, а какая из них открыта, выдавала только синяя черта
   сверху — то есть редизайн 6 сентября держался на одной детали из трёх.

   Здесь ступени заданы РАССТОЯНИЕМ, а не совпадением имён: неактивная стоит
   посередине между шапкой и активной, активная поднята над панелью подмесом
   текста, наведённая — между ними. Новой теме доопределять их не нужно: они
   пересчитаются сами от её `--panel`, `--panel-2` и `--text`.
*/
:root {
  --tab-off: color-mix(in srgb, var(--panel-2) 55%, var(--panel));
  --tab-on: color-mix(in srgb, var(--text) 5%, var(--panel-2));
  --tab-hover: color-mix(in srgb, var(--tab-on) 60%, var(--tab-off));
}

/*
   Прокручивается ЛЕНТА, а не всё гнездо: кнопка со списком проектов и «+»
   стоят рядом с ней и уезжать вместе с вкладками не должны.

   Вкладки — ВСЕГДА вкладки, и при одном документе тоже. 5 сентября 2026
   владелец допускал для одиночного документа плашку-кнопку; 6-го, посмотрев,
   отменил: «если открыть один документ, нужно всё равно показывать вкладку,
   только одну, потому что иначе это выглядит плохо». И правда: одинокая
   плашка ни к чему не примыкала и висела в шапке сама по себе, а стоило
   открыть второй документ — вид менялся под рукой.

   Отсюда всё остальное: лента прижата к низу шапки, низа у вкладок нет —
   вкладка «садится» на шапку.

   С 24 сентября 2026 — как в Photoshop. Владелец: «меня раздражает, как
   сейчас выглядит вкладка. У неё жирная полоска сверху, зачем она нужна —
   непонятно. Надо как в фотошопе, лаконичнее. И скруглённые углы убрать, где
   они не нужны». Синяя черта сверху снята: открытую вкладку и так видно по
   фону, а черта повторяла то же самое вторым языком. Углы прямые. Вкладки
   стоят стык в стык, соседей разделяет волосяная черта справа, — как ряд
   документов в Photoshop; щель в 2 точки (7 сентября) была нужна, пока
   скруглённые плашки иначе слипались в одну кнопку.
*/
.tab-strip {
  flex: 0 1 auto; min-width: 0;
  align-self: stretch;
  display: flex; align-items: flex-end; gap: 0;
  padding-top: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tab-strip::-webkit-scrollbar { display: none; }
/*
   Ширина вкладки — ПО ИМЕНИ, а не зашитым числом. Предел: 240 обычно, 360
   когда документ открыт один.

   Правило владельца 4 сентября 2026 в силе — «пусть, если документ открыт
   один, вкладка будет широкой, чтобы имя максимально влезало; при открытии
   второй они уже будут меньше», — но исполняется оно пределом, а не шириной.
   Зашитые 220 и 360 давали пустую плашку в треть шапки под коротким «Без
   имени»: имя стояло в ней крохотным пятном посередине, и вся вещь читалась
   полем ввода. Имя влезает целиком точно так же, а лишнего места вкладка не
   занимает (редизайн 6 сентября 2026).

   Ужимает вкладки флексбокс: `min-width` — предел сжатия. Когда не помещаются
   и по 96, лента прокручивается, появляется кнопка со списком, а выбранная
   вкладка сама подъезжает в видимое (`revealActiveTab` в app.js).
*/
.tab {
  flex: 0 1 auto;
  width: auto; max-width: 240px; min-width: 96px;
  height: 100%;
  display: flex; align-items: center; gap: 5px;
  padding: 0 5px 0 7px;
  border: 0; border-right: 1px solid var(--line);
  border-radius: 0;
  background: var(--tab-off);
  color: var(--muted);
  font-size: 12.5px;
  cursor: pointer;
  user-select: none;
}
/* Документ один — предел шире: длинное имя вроде «Подача Заказчику финал.trts»
   должно влезать целиком */
.tab-strip.one .tab { max-width: 360px; }
.tab:not(.active):hover { background: var(--tab-hover); color: var(--text); }
.tab.active {
  background: var(--tab-on);
  color: var(--text);
}
/* Вкладка в руке: полупрозрачна — видно, что её ведут */
.tab.dragging { opacity: .65; }
/* Крестик — на наведённой и на активной. У остальных его нет: в ленте из шести
   вкладок шесть крестиков спорят с шестью именами за одно и то же место, а
   закрывают всегда ту, на которую смотрят. Так же в браузере. Место под него
   занято всегда (`visibility`, а не `display`) — иначе ряд дёргался бы под
   курсором. */
.tab .tab-x { visibility: hidden; }
.tab:hover .tab-x, .tab.active .tab-x { visibility: visible; }
/* Знак документа перед именем — как favicon у вкладки браузера. По нему ряд
   читается вкладками с одного взгляда, ещё до того как прочтёшь имена. */
.tab-face { flex: 0 0 auto; width: 13px; height: 13px; opacity: .75; }
.tab.active .tab-face { opacity: 1; }
.tab-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Несохранённое — точкой НА МЕСТЕ знака документа, а не хвостом у имени.

   Точка `•` дописывалась к имени через `::after` и стояла у правого края —
   там же, где крестик. Два кружка подряд спорили за одно место, и при узкой
   вкладке точка съедала последнюю букву имени. В браузере несохранённое
   показывают слева, вместо значка, и рука это знает. */
.tab.dirty .tab-face { display: none; }
.tab-dot {
  flex: 0 0 auto; width: 13px; height: 13px;
  display: none; place-items: center;
}
.tab.dirty .tab-dot { display: grid; }
.tab-dot::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}
.tab-x {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  display: grid; place-items: center;
  border: none; border-radius: 0;
  background: transparent; color: inherit;
  font-size: 14px; line-height: 1;
  cursor: pointer; opacity: .5;
}
.tab-x:hover { background: var(--line); opacity: 1; }
/* «+» — новый документ. Стоит справа от вкладок, как в любом браузере и в
   Photoshop: рядом с тем, к чему прибавляет. Из шапки за ним ушла отдельная
   кнопка «Новый документ» — два входа в одно дело в одной полосе.
   `margin-bottom` ставит его в один ряд с вкладками, а не над ними. */
.tab-new {
  flex: 0 0 auto;
  width: 22px; height: 22px; padding: 0;
  margin-bottom: 3px;
  display: grid; place-items: center;
  border: 1px solid transparent; border-radius: 0;
  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; }



/* Ручки кисти по правой кнопке: строки-ползунки внутри контекстного меню */
.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; }

/* -------------------- Полоса опций активного инструмента ------------------- */

/* Полоса переносится на вторую строку, а не уезжает вбок.
   Горизонтальная прокрутка прятала половину параметров за краем окна: увидеть
   их можно было, только прокрутив полосу, о чём ничто не говорило. Двух строк
   хватает на любой инструмент; всё, что не поместилось и в них, прокручивается
   уже по вертикали — там полоса хотя бы видна целиком. */
/* Свойства инструмента: полоса ПОД ШАПКОЙ, над холстом, во всю ширину рабочей
   области между колонками.

   Решение владельца 5 сентября 2026: «Контекстное меню, которое у нас сейчас
   в виде второй строчки снизу, возникает и меняется от инструментов, оно у нас
   теперь в верхнем баре должно быть. То есть у нас должен быть верхний
   контекстный бар со свойствами, как это сделано во многих программах». Так
   стоит options bar в Photoshop и панель свойств контекста в InDesign.

   Полоса не плавает и ничего не закрывает: она обычная строка стопки холста и
   отдаёт ему свою высоту, когда у инструмента настроек нет вовсе
   (`renderToolOptions` ставит `hidden` на пустую). Прежняя плавающая версия
   висела над панелью инструментов внизу и закрывала нижний край макета. */
/* Высота полосы ФИКСИРОВАНА и не зависит от инструмента.

   Владелец 6 сентября 2026: «когда я выбираю разные инструменты, скачет
   высота контекстного меню, она должна быть фиксирована». Скакала она по двум
   причинам: `min-height` пускала полосу расти под высокий элемент (ползунок,
   отпечаток кисти), а у инструмента без параметров полоса пряталась целиком —
   и холст прыгал на её высоту вверх-вниз при каждой смене инструмента.

   Теперь высота ровно 34 и полоса стоит ВСЕГДА, даже пустая, — как options bar
   в Photoshop. Пустая полоса лучше прыгающего холста: место под неё всё равно
   отведено, а неподвижная рамка вокруг листа дороже двадцати точек. */
.tool-options {
  flex: 0 0 auto;
  display: flex; align-items: center;
  gap: 4px 10px;
  height: 34px;
  padding: 3px 10px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  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: flex; }
/* Всё, что в неё кладут, обязано влезать в её высоту, а не растягивать её */
.tool-options > * { max-height: 28px; }

/* Слева — кто сейчас в руке. 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; }
/* Числовое поле с единицей (толщина, кегль) — текстовое, и общий
   `flex: 1 1 0` растягивал его на полторы сотни точек под «0,26»
   (второй разбор интерфейса, 28 сентября 2026) */
.tool-options .row input[inputmode="decimal"].field { width: 64px; flex: 0 0 64px; }
.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; }
/* Кнопки полосы со словом («Заменить», «¶ Заголовок ▾») — по своему тексту */
.sel-actions .btn.small:not(.icon) { width: auto; height: 26px; padding: 0 8px; gap: 5px; white-space: nowrap; }
.sel-actions .btn.small:not(.icon) svg { width: 15px; height: 15px; flex: none; }
.sel-actions .btn.has-chev:not(.icon) { width: auto; max-width: 180px; }
.sel-actions .btn.has-chev:not(.icon) > span { overflow: hidden; text-overflow: ellipsis; }
/* Меню выравнивания: две строки значков — шесть по краям и три по просветам.
   Столбиком из девяти строк оно было бы вдвое выше самого объекта */
.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;
}
/* «Дополнительные инструменты (временно)» — единственный заголовок из четырёх
   слов, и в одну строку он не влезал НИКОГДА: прописные с разрядкой просят 355
   точек, а колонка даёт 161. Человек всегда читал «ДОПОЛНИТЕЛЬНЫ…».
   Сокращать нечего: слово «временно» здесь не украшение, а обещание владельца
   самому себе — эти инструменты отсюда уйдут. Поэтому переносим в две строки
   и слегка убираем разрядку (6 сентября 2026). */
.panel.extratools > .panel-head { height: auto; min-height: 26px; padding-top: 5px; padding-bottom: 5px; }
.panel.extratools > .panel-head > span:first-child {
  white-space: normal; overflow: visible; line-height: 1.25; letter-spacing: .06em;
}
.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; }

/* Знак состояния слева от названия: раскрыта панель или свёрнута.

   Был треугольником из четырёх рамок — приём старый и здесь он подвёл:
   треугольник висел в воздухе без всякой оправы, стоял не по центру строки
   (`vertical-align: 1px` подгонялся руками) и при повороте на 90° уезжал, для
   чего к нему был приписан ещё и `translateY`. Владелец 6 сентября 2026:
   «кнопка сворачивания панелей — сейчас странная такая стрелочка, которая
   кнопкой не является, немного выглядит нехорошо».

   Теперь это КНОПКА: своя площадка 16×16 с фоном под курсором, знак нарисован
   двумя штрихами через `mask` и потому поворачивается вокруг своей середины,
   без подгонок. Раскрыта — вниз, свёрнута — вправо, как у папок в любом
   дереве. */
.panel-head > span:first-child::before {
  content: '';
  flex: 0 0 auto;
  display: inline-block;
  width: 16px; height: 16px;
  margin-right: 4px;
  vertical-align: -4px;
  background: currentColor;
  opacity: .6;
  border-radius: 4px;
  -webkit-mask: var(--chev-mask) center / 9px 9px no-repeat;
  mask: var(--chev-mask) center / 9px 9px no-repeat;
  transition: transform .12s ease, opacity .12s ease;
}
.panel-head:hover > span:first-child::before { opacity: 1; }
.panel.collapsed .panel-head > span:first-child::before {
  transform: rotate(-90deg);
}
@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; }
/* Значок цепочки перетекания: связь плюс своё место в ней — «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: лист в своих пропорциях,
   имя, размер. Рисуем тем же способом, что и карточки в окне создания, —
   один визуальный язык на две двери в одну и ту же вещь. */
/* --- Колонка инструментов слева -----------------------------------------
   Узкая вертикальная колонка у самого края окна, левее панелей страниц и
   слоёв. Решение владельца 5 сентября 2026: «Вместо нижнего бара, в котором
   у нас основные инструменты, мы делаем левую панель. Просто левую узкую
   колонку, как во всех программах».

   Так стоит рельс в Figma, InDesign и Photoshop: один столбец значков,
   гнёзда с шевроном, цвета внизу. Плавающая полоса внизу холста (27 августа —
   5 сентября 2026) отсюда ушла вместе с переключателем вкладок: она стояла
   поперёк макета и закрывала его нижний край, а вкладок больше нет вовсе. */
.toolrail {
  flex: 0 0 auto;
  width: var(--rail-w);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 0 7px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  /* Инструментов двадцать одно гнездо — столько же, сколько в Photoshop, — и
     в низком окне колонка перестаёт помещаться: при 800 точках ей нужно 881, и
     за нижний край уходят цвета кисти и фона.

     Полоса прокрутки ПОКАЗАНА. Прежде она была спрятана (`scrollbar-width:
     none`), и это была самая дорогая беда прежнего рельса: инструменты за
     краем были, а признака, что там что-то есть, не было ни одного — человек
     на ноутбуке просто не знал о существовании пипетки (разбор 24 августа
     2026, UI.md). Полоса узкая и видна только при наведении, но она есть. */
  overflow: hidden;
}
/* Прокручиваются ИНСТРУМЕНТЫ, а цвета прибиты ко дну колонки.

   Пока прокручивалась вся колонка, за нижний край уезжали цвета кисти и
   фона — а они не инструмент: ими пользуется каждый растровый инструмент
   сразу, и уехать они не имеют права. Ровно этим была плоха и прежняя
   спрятанная полоса прокрутки (разбор 24 августа 2026): человек не находил
   не только пипетку, но и цвет, которым рисует.

   Свод инструментов 7 сентября (выделение в одно гнездо, штамп прочь,
   четыре ретушёра в одну кнопку) уменьшил колонку на пять кнопок, но при
   окне 800 ей всё равно нужно 798 точек против 706. Значит прокрутка
   остаётся — но прокручивать надо то, чего много, а не то, что нужно
   всегда. */
.toolrail > #tb-tools {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  scrollbar-width: thin; scrollbar-color: transparent transparent;
}
.toolrail > #tb-tools:hover { scrollbar-color: var(--scroll) transparent; }
.toolrail > #tb-tools::-webkit-scrollbar { width: 5px; }
.toolrail > #tb-tools::-webkit-scrollbar-thumb { background: transparent; border-radius: 3px; }
.toolrail > #tb-tools:hover::-webkit-scrollbar-thumb { background: var(--scroll); }
/* Цвета, разделители и пачка хода по документу не сжимаются ничем */
.toolrail > .swatches, .toolrail > .tb-sep, .toolrail > #tb-nav { flex: 0 0 auto; }
.toolrail .tb-group { display: flex; flex-direction: column; align-items: center; gap: 2px; }
/* Разделитель между пачками — теперь ГОРИЗОНТАЛЬНАЯ черта во всю ширину
   колонки: в столбце вертикальная не отделяет ничего. Рисует их сам рельс
   (`render` в ui/rail.js), по тем же тире каталога. */
.toolrail .tb-sep { height: 1px; width: 22px; margin: 4px 0; background: var(--line); flex: 0 0 auto; }
/* `flex: 0 0 auto` не украшение: без него кнопки сжимались, когда набор
   инструментов не помещался в высоту колонки. Не помещается — колонка
   прокручивается, а не плющит значки. */
.toolrail .btn.tool {
  flex: 0 0 auto;
  width: var(--tool-btn); height: var(--tool-btn); padding: 0;
  justify-content: center; background: transparent; border-radius: 8px;
}
.toolrail .btn.tool:hover { background: var(--panel-2); }
.toolrail .btn.tool.active { background: var(--accent); color: #fff; }
.toolrail .btn.tool svg { width: var(--tool-icon); height: var(--tool-icon); }
/* Низкое окно — кнопки колонки мельче, чтобы она влезала без прокрутки
   (29 сентября 2026). С новым порядком и без растровых инструментов колонка
   помещается уже в окно высотой 720; ниже — ступенями, прокрутка остаётся
   последним ходом, если не хватит и этого */
@media (max-height: 700px) {
  :root { --tool-btn: 28px; --tool-icon: 18px; }
  .toolrail .tb-sep { margin: 2px 0; }
}
@media (max-height: 560px) {
  :root { --tool-btn: 25px; --tool-icon: 16px; }
}

/* Шеврон гнезда — как в Figma (E2, решение владельца 3 сентября 2026).
   Не отдельная кнопка, а узкая зона, прижатая к значку и без своего фона:
   фон появляется только под курсором. В вертикальной колонке он стоит
   СПРАВА ВНИЗУ значка — там же, где треугольнички Photoshop, — а не сбоку
   отдельной кнопкой: колонка узкая, и вторая колонка кареток в неё не лезет. */
.toolrail .tool-pair { position: relative; display: flex; align-items: center; }
.toolrail .tool-chev {
  position: absolute; right: 0; bottom: 0;
  width: 12px; height: 12px; padding: 0;
  display: grid; place-items: center;
  background: transparent; border: 0; border-radius: 4px;
  color: var(--muted); cursor: pointer;
}
/* 8 px — тот размер, при котором шеврон читается стрелкой и не спорит со
   значком инструмента. Рисуется своим символом (`i-chev-slot`): общий
   `i-chev` собран в сетке 24 и на этом размере теряет штрих */
.toolrail .tool-chev svg { width: 8px; height: 8px; }
.toolrail .tool-chev:hover { background: var(--panel-2); color: var(--text); }
.toolrail .btn.tool.active + .tool-chev { color: #fff; }

/* Цвет кисти и фона: две плашки внахлёст, СРАЗУ ЗА ПОСЛЕДНИМ ИНСТРУМЕНТОМ,
   через разделитель. Владелец 5 сентября 2026: «Надо показывать её после всех
   инструментов, где-то посередине она получится». Пружины, прибивавшей пару к
   низу колонки, больше нет.
   Прежде пара лежала в полосе и показывалась только во вкладке «Рисование»;
   вкладок больше нет, и прятать её не от чего — цвет нужен и фигуре, и кисти.
   Сама пара размечена ниже (`.swatches`) и работает как была: квадрат 34×34
   с плашками внахлёст, обменом и сбросом по углам. */
.toolrail .swatches { margin-top: 2px; }

/* --- Полосы прокрутки ----------------------------------------------------
   Лежат поверх холста, как линейки: полоса появляется и исчезает по ходу
   работы, и пересчитывать из-за неё размер холста — лишний повод для дрожания
   картинки. Тонкие и всегда видимые, а не всплывающие: их задача — постоянно
   отвечать, где ты в документе. */
.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;
}
/* Карточками с первой страницей (29 сентября 2026): подачу узнают глазами */
.empty-recent .rec-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.empty-recent .rec-grid .rec {
  flex-direction: column; align-items: stretch; gap: 3px; padding: 6px;
  border: 1px solid transparent;
}
.empty-recent .rec-grid .rec:hover { border-color: var(--line); }
.empty-recent .rec-face {
  display: grid; place-items: center; aspect-ratio: 1.414; border-radius: 5px; overflow: hidden;
  background: var(--panel-2); margin-bottom: 3px;
}
.empty-recent .rec-face img { width: 100%; height: 100%; object-fit: contain; display: block; }
.empty-recent .rec-blank { width: 34%; aspect-ratio: .75; border: 1.4px solid var(--muted); border-radius: 2px; opacity: .6; }
.empty-recent .rec-grid .rec .where { direction: ltr; }

/* Миниатюра в строке слоя — на месте прежнего значка типа */
.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;
}

/* ------------------- Дополнительные инструменты (временно) ---------------- */
/* Растровые гнёзда — те, что меняют пиксели слоя. Стоят СЕТКОЙ, а не
   столбцом: панель широкая (288 точек), и столбец из восьми значков занял бы
   всю её высоту ради одного ряда содержимого.

   Панель заведена решением владельца 5 сентября 2026 и названа его словами:
   «Дополнительные инструменты (временно)». Она же — ответ на вопрос, куда
   девать растр, не занимая им левую колонку. */
.extra-tools {
  display: flex; flex-wrap: wrap; gap: 2px;
  padding: 6px 8px 8px;
}
.extra-tools .tool-pair { position: relative; display: flex; align-items: center; }
.extra-tools .btn.tool {
  flex: 0 0 auto;
  width: 30px; height: 30px; padding: 0;
  justify-content: center; background: transparent; border-radius: 8px;
}
.extra-tools .btn.tool:hover { background: var(--panel-2); }
.extra-tools .btn.tool.active { background: var(--accent); color: #fff; }
.extra-tools .btn.tool svg { width: var(--tool-icon); height: var(--tool-icon); }
.extra-tools .tool-chev {
  position: absolute; right: 0; bottom: 0;
  width: 12px; height: 12px; padding: 0;
  display: grid; place-items: center;
  background: transparent; border: 0; border-radius: 4px;
  color: var(--muted); cursor: pointer;
}
.extra-tools .tool-chev svg { width: 8px; height: 8px; }
.extra-tools .tool-chev:hover { background: var(--panel-2); color: var(--text); }
.extra-tools .btn.tool.active + .tool-chev { color: #fff; }
/* Разделители каталога в сетке не нужны: гнёзд немного, и пачка одна */
.extra-tools .tb-sep { display: none; }

/* Вторая строка панели слоёв: сколько нашлось и кнопка «взять всё найденное».
   Нужна там, где список отобран фильтром: без неё полсотни штрихов подряд
   приходилось брать по одному (владелец 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; }
/* Стиль объекта в шапке — «без стиля ▾» или имя стиля (редизайн 29 сентября
   2026). Отличается объект от стиля — точка у имени, как «+» в InDesign */
.pp-head-style {
  flex: 0 1 auto; min-width: 0; max-width: 45%; height: 22px;
  display: inline-flex; align-items: center; gap: 3px;
  padding: 0 4px 0 7px; border: 1px solid transparent; border-radius: 5px;
  background: transparent; color: var(--muted); font: inherit; font-size: 11.5px; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pp-head-style:hover { background: var(--hover); color: var(--text); }
.pp-head-style.set { color: var(--text); border-color: var(--line); }
.pp-head-style svg { width: 12px; height: 12px; flex: none; opacity: .7; }
.pp-head-style .pp-moved { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: none; }
.pp-menu-sep { height: 1px; background: var(--line); margin: 4px 2px; }
.pp-menu-item.on { color: var(--accent); }
.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: 10px 0 12px; }
.pp-sec + .pp-sec { border-top: 1px solid var(--line); }
#props > .pp-sec:first-child { padding-top: 4px; }
/* Заголовок раздела — обычным регистром, цветом текста, одной строкой
   (редизайн 29 сентября 2026). Серый капс с разрядкой читался ярлыком, а не
   именем, и «ПОЛОЖЕНИЕ И РАЗМЕР» в колонке 260 переносился на две строки */
/* Имя #props в селекторе — чтобы перебить старое общее "#props h3" (капс) */
.pp-sec > h3, #props .pp-sec > h3 {
  margin: 0 0 8px; min-height: 22px; font-size: 12.5px; text-transform: none; letter-spacing: 0;
  color: var(--text); font-weight: 600;
  display: flex; align-items: center; gap: 4px;
  white-space: nowrap;
}
/* Пустой раздел — одна строка: имя серым и «+» справа, как Stroke в Figma */
.pp-sec.pp-empty { padding: 7px 0; }
.pp-sec.pp-empty > h3, #props .pp-sec.pp-empty > h3 { margin: 0; color: var(--muted); }
.pp-sec.pp-empty > h3 > .pp-ic { margin-left: auto; }
/* Редкие разделы (обтекание, ссылка, экспорт), пока пусты, — метками внизу */
.pp-sec.pp-tagged { display: none !important; }
.pp-tags { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 0 4px; border-top: 1px solid var(--line); }
.pp-tag {
  height: 24px; padding: 0 10px; border-radius: 12px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer;
}
.pp-tag:hover { background: var(--hover); color: var(--text); }
/* «+», «⋯» и «?» прижаты к правому краю заголовка: слева имя, справа то, что
   с разделом делают */
.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: 8px; margin-bottom: 8px; }
.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: 8px; margin-bottom: 8px; }
/* Общая сетка панели (редизайн 29 сентября 2026): две равные колонки и
   столбец 28 точек под кнопку. Все строки чисел стоят на ней, и края полей
   совпадают сверху донизу — раньше каждая строка делила ширину по-своему */
.pp-g3 {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 28px;
  gap: 8px; margin-bottom: 8px; align-items: center;
}
.pp-g3.bot { align-items: end; }
.pp-g3:last-child { margin-bottom: 0; }
.pp-g4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 6px; }
/* Четыре числа в ряд — самая тесная сетка в программе: на колонке 180 точек
   ячейке достаётся 33. Отступы внутри оправы урезаны вдвое: каждая точка тут
   идёт полю, а не воздуху по краям */
.pp-g4 .pp-f { padding: 0 4px; gap: 2px; }

/* Узкая колонка: ряды чисел СКЛАДЫВАЮТСЯ, а не режут единицу.

   Решение владельца 7 сентября 2026 на выбор из трёх: не поднимать нижний
   предел ширины колонки (он остаётся 180), а ряд из четырёх полей при нехватке
   места класть в два по два. До этого дня «Верх · Низ · Слева · Справа» на
   пределе доставалось по 33 точки на ячейку, и значок единицы получал ДВЕ из
   восемнадцати — то есть исчезал совсем. Правило `.pp-f` ниже так и задумано:
   в тесноте жертвуют единицей, а не полем. Правильный ответ — не доводить до
   тесноты: два ряда по два дают ячейке 68 точек, и целы обе вещи.

   Меряется САМ РАЗДЕЛ, а не окно: колонку тянут за ручку, и ширина её к
   размеру окна отношения не имеет. Отсюда `@container`, а не `@media`.

   Пороги считаны от нужды поля: 24 точки под две цифры плюс оправа плюс
   значок единицы («мм» — 18). Четырём таким нужно 226, трём в обычной
   оправе — 192. */
.pp-sec { container-type: inline-size; }
@container (max-width: 225px) {
  .pp-g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Общая сетка в самой узкой колонке (у минимума 180 точек): поле на строку,
   кнопка — под ним слева. Порог — две ячейки по 80 точек («X 125,5 мм») и
   столбец кнопки: выше него обе колонки целы */
@container (max-width: 190px) {
  .pp-g3 { grid-template-columns: minmax(0, 1fr); }
  .pp-g3 > .pp-nil { display: none; }
  .pp-g3 > .pp-ic { justify-self: start; }
}
@container (max-width: 191px) {
  /* «Колонки · Средник · Вылет»: те же два столбца, третье поле уходит вниз
     на левое место, а не растягивается на всю ширину */
  .pp-row.wrap2 {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end; gap: 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; overflow: hidden; text-overflow: ellipsis; }
.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: 28px; min-width: 0; flex: 1 1 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 0 8px;
  /* В тесноте лишним оказывается ЗНАЧОК ЕДИНИЦЫ, а не поле. Пока оправа
     ничего не обрезала, «мм» держалось своей шириной и выдавливало поле в
     НОЛЬ: в разделе «Поля и колонки» четыре числа — Верх, Низ, Слева, Справа —
     стояли в ячейках по 33 точки, и человек видел четыре серых «мм» подряд, а
     самих полей не видел вовсе и править их не мог (замер 6 сентября 2026).
     Средник и вылет доставались по 7,5 точки — полторы цифры. */
  overflow: hidden;
}
.pp-f:hover { border-color: var(--scroll); }
.pp-f:focus-within { border-color: var(--accent); }
/* Подпись внутри поля (X, Y, Ш, В, ∠, R, L) — серая, слева, она же ручка
   скраба. Столбец постоянной ширины: числа под ней встают столбиком */
.pp-f.lab { padding-left: 0; }
.pp-f > .pp-l {
  flex: 0 0 22px; align-self: stretch; display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 11.5px; line-height: 1;
}
.pp-f > .pp-in {
  /* Место поля не отдаётся никому: 24 точки — это две цифры, ниже начинается
     обман. Не хватило ширины — уходит единица, см. `.pp-u` ниже.

     Основа сжатия НОЛЬ, а не `width: 100%`. Пока поле требовало все сто
     процентов оправы, строка была переполнена ВСЕГДА — и единица ужималась
     тоже всегда, на любой ширине колонки: замер 7 сентября 2026 давал «мм»
     15 точек из 18 при ячейке в 102, где места хватало с избытком. Человек
     видел это как «мм» без второй буквы и «px» без хвоста у «x» — мелко, но
     во всех числовых полях программы сразу. С основой в ноль поле берёт
     ОСТАТОК после единицы, а ужимать её начинает лишь когда само упёрлось
     в свои 24 точки, — то есть ровно тогда, когда и задумано. */
  flex: 1 1 0; min-width: 24px; width: auto;
  background: transparent; border: 0; outline: none; padding: 0;
  color: var(--text); font: inherit; font-size: 12.5px; height: 100%;
  font-variant-numeric: tabular-nums;
}
.pp-f > .pp-in::-webkit-inner-spin-button { display: none; }
/* Единица и короткая метка — серым, мельче и в набор не мешаются */
.pp-f > .pp-u {
  color: var(--muted); font-size: 11.5px; margin-left: auto; padding-left: 2px;
  /* Ужимается и обрезается первой: единица подсказывает, а число — работа */
  flex: 0 1 auto; min-width: 0; overflow: hidden;
}
.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: 28px; height: 28px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  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; }
/* Точка привязки подгонки — девять точек 3 × 3, как «Выравнивание» в
   «Параметрах подгонки фрейма» InDesign (28 сентября 2026) */
.pp-anchor { display: grid; grid-template-columns: repeat(3, 14px); grid-template-rows: repeat(3, 14px); gap: 2px;
  padding: 2px; border: 1px solid var(--line); border-radius: 4px; margin-left: auto; }
.pp-anchor-pt { width: 14px; height: 14px; padding: 0; border: 0; background: transparent; cursor: pointer; position: relative; }
.pp-anchor-pt::after { content: ''; position: absolute; inset: 4px; border-radius: 1px; background: var(--muted); opacity: .55; }
.pp-anchor-pt:hover::after { opacity: 1; background: var(--text); }
.pp-anchor-pt.on::after { inset: 2px; background: var(--accent); opacity: 1; }

.pp-btn {
  height: 28px; min-height: 28px; 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: 6px;
  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-cf {
  display: flex; align-items: center; gap: 6px; height: 28px; min-width: 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 0 4px 0 5px;
}
.pp-cf:hover { border-color: var(--scroll); }
.pp-cf > .pp-sw { width: 18px; height: 18px; border-radius: 4px; }
.pp-cf > .pp-cv { border: 0; background: none; height: 26px; padding: 0 2px; }
.pp-cf > .pp-cv:hover { background: none; color: var(--accent); }
.pp-cr { display: flex; align-items: center; gap: 4px; min-width: 0; }
.pp-cr > .pp-f { flex: 1 1 0; }
.pp-cr > .pp-ic { width: 24px; }

.pp-cv {
  flex: 1 1 0; min-width: 0; height: 28px;
  display: flex; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  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); }
/* Значение, по которому не щёлкают: имя эффекта, размер исходника, профиль.
   Оно ничего не делает — значит и оправа ему не нужна: рамка и подложка
   обещают кнопку или поле. Заодно строка перестала обрываться: «4961 × 3508
   px» просит сотню точек, а в паре с полем dpi ей достаётся семьдесят, и без
   оправы (14 точек отступов и 2 рамки) она наконец влезает целиком, а если
   нет — переносится на вторую строку (6 сентября 2026). */
.pp-cv.static {
  cursor: default; color: var(--muted);
  background: none; border-color: transparent; padding: 0 2px;
  height: auto; min-height: 26px;
  white-space: normal; line-height: 1.2;
}
.pp-cv.static:hover { background: none; }
.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; }

/* -------------- Свёрнутая колонка: панель выпадает окошком ---------------- */

/* Владелец 6 сентября 2026: «Нужно иметь возможность при свёрнутой колонке —
   если сейчас нажать на маленькую иконку панели, которая в этой колонке была,
   то оно всё разворачивается целиком. Я думаю, что лучше сделать, как в
   фотошопе, чтобы при нажатии на иконку конкретный инструмент выпадал в виде
   отдельного окошка сбоку, как это сделано в фотошопе. И в этом случае
   свёрнутая колонка должна занимать больше места, то есть эти иконки должны
   быть больше.»

   Прежде щелчок по значку разворачивал ВСЮ колонку: чтобы заглянуть в слои,
   человек отдавал холсту обратно двести сорок точек ширины со всеми соседними
   панелями, а потом сворачивал колонку заново. Свёрнутая колонка ради этого и
   существует — холст во всю ширину, — и разворачивать её на каждый вопрос
   значит её не иметь.

   Сама панель при этом НИКУДА ИЗ КОЛОНКИ НЕ УХОДИТ (в отличие от `.panel-float`,
   куда её выселяют насовсем): это тот же узел колонки, только вставший
   `position: fixed` рядом с полосой. Поэтому свой значок в полосе у него
   остаётся — им же окошко и закрывают. Разбор — в `openFly` (src/ui/docks.js).

   Размеры в полосе (`.dock.collapsed`, `.dock-tab` выше) выросли с 30/24/17 до
   40/32/20: по значку теперь ОТКРЫВАЮТ панель, а не разворачивают колонку, —
   это кнопка, и целиться в неё приходится точно. */
.dock.collapsed > .dock-fly {
  display: flex; flex-direction: column;
  position: fixed; z-index: 36;
  min-height: 0;
  /* Доли высоты колонки окошку не хозяева: app.js пишет каждой панели свой
     `flex` прямо в разметку, и без `!important` инлайновая строка победила бы */
  flex: none !important;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .5);
  overflow: hidden;
}
/* Заголовок в окошке остаётся ручкой панели: за него её вытаскивают плавающим
   окном, и незачем этому разучиваться оттого, что колонка свёрнута */
.dock.collapsed > .dock-fly > .panel-head { cursor: grab; }

/* Значок, которым окошко открыто. Без пометки человек не знает, на что жать,
   чтобы закрыть: панель стоит сбоку и на полосу ничем не показывает. Правило
   идёт ПОСЛЕ `.dock-tab:hover` нарочно — при равной силе побеждает последнее,
   и открытый значок остаётся отмеченным даже под курсором. */
.dock-tab.open { background: var(--accent); color: #fff; }

/* Панель, свёрнутую до заголовка (её сворачивает щелчок по шапке — см.
   `applyCollapsed` в app.js), окошко обязано ужать по ней. Иначе на холсте
   висела бы пустая коробка в 360 точек с полоской наверху: высоту окошку
   пишет `placeFly` прямо в разметку, и без `!important` инлайновая строка
   победила бы. Запрещать сворачивание внутри окошка не стали нарочно —
   в колонке оно работает, и разучиваться ему тут не с чего. */
.dock.collapsed > .dock-fly.collapsed { height: auto !important; }

/* Окошко группы вкладок показывает ОДНУ панель — ту, чью кнопку нажали, — с
   её собственным заголовком, без корешков (25 сентября 2026). Корешки в
   окошке переключали вкладку пересборкой раскладки и закрывали окошко;
   соседнюю панель теперь открывают её кнопкой в полосе. */
.dock.collapsed > .panel-group.dock-fly > .group-tabs { display: none; }
.dock.collapsed > .panel-group.dock-fly > .panel > .panel-head { display: flex; }

/* Ручки размера окошка (`flyGrips` в ui/docks.js): нижний край — высота,
   дальний от полосы нижний угол — ещё и ширина. Размер помнится по панели. */
.dock-fly > .fly-size {
  position: absolute; left: 0; right: 0; bottom: 0; height: 7px;
  cursor: ns-resize; z-index: 3;
}
.dock-fly > .fly-size.fly-corner { width: 16px; height: 16px; }
.dock-right > .dock-fly > .fly-corner { left: 0; right: auto; cursor: nesw-resize; }
.dock-left > .dock-fly > .fly-corner { left: auto; right: 0; cursor: nwse-resize; }
.dock-fly > .fly-corner::after {
  content: ''; position: absolute; bottom: 4px; width: 7px; height: 7px;
  border-bottom: 2px solid var(--muted); opacity: .55;
}
.dock-right > .dock-fly > .fly-corner::after { left: 4px; border-left: 2px solid var(--muted); }
.dock-left > .dock-fly > .fly-corner::after { right: 4px; border-right: 2px solid var(--muted); }
.dock-fly > .fly-corner:hover::after { opacity: 1; }

/* Окно «Найти и заменить» (ui/textedit/findpanel.js): немодальное, в правом
   верхнем углу полотна — найденное подсвечено на листах, и смотреть на него
   надо, не закрывая окна. */
.find-panel {
  position: absolute; top: 10px; right: 12px; z-index: 40;
  width: 320px; max-width: calc(100% - 24px);
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 9px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
  color: var(--text);
  font-size: 12px;
}
.find-panel[hidden] { display: none; }
.find-panel .find-row { display: flex; align-items: center; gap: 6px; }
.find-panel .find-row > .field { flex: 1 1 auto; min-width: 0; }
.find-panel .find-opts { flex-wrap: wrap; gap: 4px 10px; }
.find-panel .find-opts label { display: inline-flex; align-items: center; gap: 4px; }
.find-panel .find-opts select { flex: 1 1 100%; }
.find-panel .find-actions { justify-content: flex-end; flex-wrap: wrap; }
.find-panel .find-count { color: var(--muted); white-space: nowrap; min-width: 48px; text-align: right; }
.find-panel .find-count.none { color: #e8715a; }
.find-panel .find-close {
  border: 0; background: transparent; color: var(--muted);
  font-size: 16px; line-height: 1; padding: 2px 4px; cursor: pointer;
}
.find-panel .find-close:hover { color: var(--text); }
/* Найденное списком по страницам (поиск по документу, 28 сентября 2026) */
.find-panel .find-results {
  max-height: min(42vh, 360px); overflow: auto;
  margin: 0 -4px; padding: 2px 0;
  border-top: 1px solid var(--line);
}
.find-panel .find-results[hidden] { display: none; }
.find-panel .find-group {
  display: flex; justify-content: space-between; gap: 6px;
  padding: 6px 6px 2px; color: var(--muted); font-weight: 600;
  position: sticky; top: 0; background: var(--panel);
}
.find-panel .find-group-n { font-weight: 400; }
.find-panel .find-hit {
  display: flex; gap: 6px; align-items: baseline;
  padding: 3px 6px; border-radius: 5px; cursor: pointer;
}
.find-panel .find-hit:hover { background: rgba(127, 127, 127, .14); }
.find-panel .find-hit.current { background: rgba(255, 140, 0, .22); }
.find-panel .find-kind { flex: 0 0 auto; color: var(--muted); font-size: 11px; min-width: 64px; }
.find-panel .find-snip { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.find-panel .find-snip mark { background: rgba(255, 205, 0, .45); color: inherit; border-radius: 2px; }
.find-panel .find-more { padding: 4px 6px; color: var(--muted); }

/* ------------------------ Слои документа (InDesign) ------------------------
 * Задание владельца 25 сентября 2026. Строка слоя — как в InDesign: глаз,
 * замок, квадратик цвета, имя, а справа квадратик «здесь выделенное». Его
 * тянут на другой слой — выделенное переезжает туда. Строки рисует
 * ui/layerpanel.js.
 */
.ly-list { flex: 1 1 auto; overflow-y: auto; padding: 3px 0 8px; }
.ly-row {
  display: flex; align-items: center; gap: 5px;
  height: 26px; padding: 0 6px 0 4px;
  border-left: 2px solid transparent;
  cursor: default; user-select: none;
}
.ly-row:hover { background: var(--panel-2); }
/* Активный слой — тот, куда ложится новое: подсвечен, как выбранная строка */
.ly-row.on { background: #26314a; border-left-color: var(--accent); }
.ly-row.off .ly-name { opacity: .42; }
.ly-row.dragging { opacity: .45; }
.ly-row.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.ly-row.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.ly-row.drop-into { box-shadow: inset 0 0 0 1px var(--accent); }
.ly-swatch {
  width: 12px; height: 12px; flex: 0 0 12px; padding: 0;
  border: 1px solid rgba(0, 0, 0, .35); border-radius: 2px; cursor: pointer;
}
.ly-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px;
}
/* «Здесь выделенное»: пустое место той же ширины, когда выделенного на слое
   нет, — иначе имена прыгали бы при каждом щелчке по листу */
.ly-sel { width: 10px; height: 10px; flex: 0 0 10px; border-radius: 2px; }
.ly-sel.has { cursor: grab; }
.ly-colors {
  position: fixed; z-index: 90;
  display: grid; grid-template-columns: repeat(5, 22px); gap: 4px;
  padding: 6px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
}
.ly-colors button {
  width: 22px; height: 22px; padding: 0; border-radius: 4px; cursor: pointer;
  border: 1px solid rgba(0, 0, 0, .35);
}
.ly-colors button.on { box-shadow: 0 0 0 2px var(--text); }
/* Выбранные строки (Ctrl и Shift) — для «Слить слои»: светлее активной */
.ly-row.pick { background: #202a3d; }
.ly-row.on.pick { background: #26314a; }
/* «Параметры слоя…»: та же палитра, что у квадратика, но в окне, а не поверх */
.ly-colors.lo-colors { position: static; box-shadow: none; grid-template-columns: repeat(9, 22px); margin: 2px 0 10px; }
.lo-color-name { font-size: 13px; color: var(--muted); }
.ly-foot { justify-content: space-between; }
.ly-foot .panel-bar-sep { flex: 1 1 auto; width: auto; background: transparent; margin: 0; }

/* Слой объекта в списке «Объекты» — квадратиком его цвета, как в InDesign */
.lay-layer { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 2px; }

/* Фильтр выделения в строке состояния: «Выделяются только: текст ×» */
.sb-pick {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  height: 20px; padding: 0 8px; border: 1px solid var(--accent); border-radius: 10px;
  background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.sb-pick.hidden { display: none; }
.sb-pick:hover { background: var(--hover); }

/* Подсказка-карточка колонки инструментов (ui/rail.js, 29 сентября 2026):
   имя и клавиша, строка о деле инструмента, соседи по гнезду */
.tool-tip {
  position: fixed; z-index: 3000; max-width: 260px; min-width: 180px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .4);
  padding: 10px 12px; font-size: 12.5px; line-height: 1.45; pointer-events: none;
}
.tool-tip .tt-head { display: flex; align-items: center; gap: 10px; justify-content: space-between; }
.tool-tip .tt-head b { font-weight: 600; }
.tool-tip .tt-key {
  font: 500 11px ui-monospace, Consolas, monospace; color: var(--muted);
  border: 1px solid var(--line); border-radius: 4px; padding: 0 5px; margin-left: auto;
}
.tool-tip .tt-hint { color: var(--muted); margin-top: 4px; }
.tool-tip .tt-more { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 6px; display: grid; gap: 3px; }
.tool-tip .tt-lab { color: var(--muted); font-size: 11.5px; }
.tool-tip .tt-row { display: flex; align-items: center; gap: 8px; color: var(--text); }
.tool-tip .tt-row svg { width: 15px; height: 15px; color: var(--muted); flex: none; }

/* «Подача из изображений» — широкой кнопкой над быстрым запуском: четыре
   плитки сеткой, как лягут визуализации (29 сентября 2026) */
.quick-deck-wide {
  display: flex; align-items: center; gap: 14px; width: 100%; margin-bottom: 18px;
  padding: 12px 16px; text-align: left; cursor: pointer; font: inherit; color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 10px;
}
.quick-deck-wide:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); border-color: var(--accent); }
.quick-deck-wide .qd-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.quick-deck-wide b { font-size: 13px; font-weight: 600; color: var(--accent); }
.quick-deck-wide .sub { font-size: 11.5px; color: var(--muted); }
.quick-deck-wide .quick-deck {
  flex: none; display: grid; grid-template-columns: repeat(2, 16px); grid-template-rows: repeat(2, 11px); gap: 3px;
  padding: 4px; border: 1.4px solid var(--accent); border-radius: 3px;
}
.quick-deck-wide .quick-deck i { background: color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 1px; }
.quick-deck-wide:hover .quick-deck i { background: var(--accent); }
