@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/literata-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/literata-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/literata-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/literata-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/manrope-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/manrope-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/manrope-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/manrope-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light;
  /* Pastel palette from the supplied Pantone reference. */
  --marys-rose: #f6d2d4;
  --gossamer-green: #b3d0be;
  --pastel-yellow: #f2e8b3;
  --orchid-petal: #c3b7cf;
  --heavenly-pink: #f4dee3;
  --cappuccino-foam: #f5f5e9;
  /* Цвет человека в кружке «Поручить» (12.11.2026): у каждого свой, буква белая. */
  --person-1: #5b8f6e;
  --person-2: #c0717a;
  --person-3: #7b6aa6;
  --person-4: #c48c33;
  --person-5: #4f86a8;
  --person-6: #a0745a;
  --person-ink: #ffffff;
  --hushed-violet: #d2bebf;
  --ink: #000000;
  --paper: #ffffff;

  /* Бумажная основа: насыщенная пастель осталась плиткам этапов, фон стал тише. */
  --bg: #faf8f2;
  --panel: var(--paper);
  --panel-2: #f7f4ec;
  --line: #ece6d9;
  --text: #3b3227;
  /* Приглушённый текст светлой темы затемнён с #8a8071 (17.09.2026).
     Прежнее значение давало контраст 3.4–3.9 на трёх фонах, где стоит
     (--paper, --panel-2, --accent-dim), — ниже нормы 4.5 для мелкого текста.
     Этим цветом набраны не только подписи: им же неактивные вкладки фабрик,
     «Ещё N без заказов» и «готовность: —», то есть текст, который читают.
     Тёмная тема норму держала давно (--muted: #a39a8b, 4.3–7). Оттенок тот
     же, светлота на 15% ниже: 4.5–5.1 на всех трёх фонах. */
  --muted: #756d60;
  --accent: var(--gossamer-green);
  --accent-dim: #e4efe8;
  --ok: var(--gossamer-green);
  --warn: var(--pastel-yellow);
  --danger: var(--marys-rose);
  --ink-green: #2f4238;
  --ink-rose: #7a3339;
  --ink-yellow: #5d5326;
  --font-display: Literata, Georgia, "Times New Roman", serif;
  --radius: 12px;
  --radius-sm: 10px;
  --gap: 10px;
  --pad: 12px;
  --pad-lg: 16px;

  /* Токены, вынесенные из захардкоженных значений (тёмная тема переопределяет их ниже). */
  --c-d4a514-l: #d4a514;
  --c-c96a70-l: #c96a70;
  --c-rgba-80-66-48-1-s: rgba(80, 66, 48, .1);
  --c-rgba-47-66-56-16-s: rgba(47, 66, 56, .16);
  --c-rgba-122-51-57-12-s: rgba(122, 51, 57, .12);
  --c-d4a514-t: #d4a514;
  --c-rgba-20-12-16-82-s: rgba(20, 12, 16, .82);
  --hover: #f6f3ea;
  --tile-violet-bg: #efeaf4;
  --c-46405a-t: #46405a;
  --c-a3c6b0-s: #a3c6b0;
  --c-f4f1e8-s: #f4f1e8;
  --c-rgba-60-50-35-08-s: rgba(60, 50, 35, .08);
  --c-eef2e9-s: #eef2e9;
  --panel-3: #f4f1e7;
  --text-2: #5f5648;
  --c-rgba-255-255-255-7-s: rgba(255, 255, 255, .7);
  --tile-rose-bg-3: #fbe6e7;
  --tile-rose-text-2: #5b3a3d;
  --tile-yellow-bg: #f8f3d8;
  --tile-yellow-text: #5d5326;
  --tile-blush-bg: #f1e8e8;
  --tile-blush-text: #59464a;
  --tile-violet-text: #4c4459;
  --tile-green-bg: #e4efe8;
  --tile-green-text-2: #33463b;
  --c-f8f6ef-s: #f8f6ef;
  --c-fdf3f4-s: #fdf3f4;
  --tile-cream-bg: #fdfaea;
  --c-faf5f5-s: #faf5f5;
  --tile-violet-bg-2: #f8f6fa;
  --tile-green-bg-2: #f2f8f4;
  --c-f7f5ef-s: #f7f5ef;
  --c-eef4f0-s: #eef4f0;
  --c-rgba-120-104-80-18-l: rgba(120, 104, 80, .18);
  --c-rgba-255-255-255-72-s: rgba(255, 255, 255, .72);
  --c-rgba-120-104-80-3-l: rgba(120, 104, 80, .3);
  --c-rgba-80-66-48-06-s: rgba(80, 66, 48, .06);
  --c-e3dbc9-s: #e3dbc9;
  --c-rgba-80-66-48-08-s: rgba(80, 66, 48, .08);
  --c-ddb0b4-s: #ddb0b4;
  --c-9c9282-t: #9c9282;
  --text-3: #6b6151;
  --c-fbf5da-s: #fbf5da;
  --tile-rose-bg-2: #fadfe1;
  --c-ece7d8-s: #ece7d8;
  --c-rgba-90-74-55-08-s: rgba(90, 74, 55, .08);
  --c-fdf9ee-s: #fdf9ee;
  --line-4: #f0eade;
  --c-f3efe4-s: #f3efe4;
  --panel-6: #f5f2e8;
  --c-a09684-t: #a09684;
  --panel-5: #fbf9f3;
  --c-rgba-80-66-48-05-s: rgba(80, 66, 48, .05);
  --c-d8b26a-t: #d8b26a;
  --c-e2dccc-t: #e2dccc;
  --c-rgba-255-255-255-66-s: rgba(255, 255, 255, .66);
  --c-ddd3e6-l: #ddd3e6;
  --c-cfe3d7-l: #cfe3d7;
  --c-c0b6a2-t: #c0b6a2;
  --c-6f7f74-t: #6f7f74;
  --c-eef2f6-s: #eef2f6;
  --c-4a5866-t: #4a5866;
  --c-f3eef8-s: #f3eef8;
  --c-574a66-t: #574a66;
  --c-eef2ec-s: #eef2ec;
  --c-47563f-t: #47563f;
  --c-f1ece0-s: #f1ece0;
  --c-a9cdb8-s: #a9cdb8;
  --c-f6f2e6-s: #f6f2e6;
  --c-f4efe3-l: #f4efe3;
  --c-fdfbf5-s: #fdfbf5;
  --c-f2ecdd-l: #f2ecdd;
  --c-d9b96a-s: #d9b96a;
  --c-b8515d-s: #b8515d;
  --c-4a7c59-l: #4a7c59;
  --c-3f6b4c-t: #3f6b4c;
  --c-a94550-l: #a94550;
  --c-f9ecee-s: #f9ecee;
  --c-8e3a44-t: #8e3a44;
  --c-fdf3d8-s: #fdf3d8;
  --c-e6d3a3-l: #e6d3a3;
  --c-6d5620-t: #6d5620;
  --c-c96a74-l: #c96a74;
  --panel-raw: #fff;
  --on-accent: #fff;
  --on-accent-strong: var(--ink-green);
  --card: var(--panel);
  /* Пустая звезда видна на белом (3 : 1, аудит 03.11.2026, Р-С-17); в тёмной теме — своя. */
  --star-off: var(--c-9c9282-t);
  --rule: var(--line);
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --shadow-soft: rgba(80, 66, 48, .16);
  --guide-scrim: rgba(40, 33, 25, .55);
  /* Окно обрезки фото (04.11.2026): тень вне рамки, рамка и сетка третей. */
  --crop-shade: rgba(20, 16, 12, .55);
  --crop-line: #fff;
  --crop-grid: rgba(255, 255, 255, .45);
  --guide-arrow: #e5484d;
  --guide-arrow-halo: rgba(255, 255, 255, .95);
  --warn-ink: var(--ink-yellow);
  --accent-ink: var(--ink-green);
  --c-a5454f-s: #a5454f;
  --c-ece0e2-l: #ece0e2;
  --c-e8d6d9-l: #e8d6d9;
  --c-fff8f9-s: #fff8f9;
  --c-a08b6f-t: #a08b6f;
  --tile-rose-text: #8a2f34;
  --tile-rose-bg: #fbe1e3;
  --tile-rose-line: #f1c6ca;
  --c-fff9f9-s: #fff9f9;
  --c-eef3ec-s: #eef3ec;
  --tile-green-text: #2f4238;
  --c-dbe6d9-l: #dbe6d9;
  --tile-yellow-line: #ece3bf;
  --c-rgba-40-34-28-14-s: rgba(40, 34, 28, .14);
  --c-rgba-40-34-28-10-s: rgba(40, 34, 28, .10);
  --tile-yellow-line-2: #d9c98a;
  --c-rgba-255-255-255-18-s: rgba(255, 255, 255, .18);
  --c-rgba-255-255-255-35-l: rgba(255, 255, 255, .35);
  --c-rgba-40-34-28-12-s: rgba(40, 34, 28, .12);
  --line-3: #e8e2d4;
  /* Стрелки схемы «что из чего вышло» в «Логе» (30.09.2026): линия-ствол и
     стрелка «CRM разнесла следом». Прямое действие рисуется акцентом. */
  --jr-line: #cdc3ad;
  --c-ddd5c4-s: #ddd5c4;
  --c-rgba-80-66-48-12-s: rgba(80, 66, 48, .12);
  --c-d9b96a-l: #d9b96a;
  --c-rgba-59-50-39-72-s: rgba(59, 50, 39, .72);
  /* Подписи плашек актора в «Логе» («Вы», «Агент», «Авторазбор») — на своих
     цветных подложках. Норма AA для мелкого текста 4.5; «Вы» её держал (4.59),
     а два других нет: агент 4.44, авторазбор 3.85 при кегле 10,5 px. Оттенок
     оставлен тот же, светлота опущена ровно до нормы. */
  --c-4a7c59-t: #4a7c59;
  --c-7c6a92-t: #7b6991;
  --c-a8742f-t: #996a2b;
  --c-f6e3dd-s: #f6e3dd;
  --c-a8422a-t: #a8422a;
  --line-2: #e2e0d9;
  --panel-4: #fbfaf7;
  --c-7fae8c-l: #7fae8c;
  --c-d0a43f-l: #d0a43f;
  --c-c9c7bf-l: #c9c7bf;
  --c-c47a63-l: #c47a63;
  --c-f6ecd4-s: #f6ecd4;
  --c-7a5c12-t: #7a5c12;
  --c-f4e2dc-s: #f4e2dc;
  --c-8f4028-t: #8f4028;
  --c-b9cdbf-l: #b9cdbf;
  --c-ece7f1-s: #ece7f1;
  --c-b3d0be-l: #b3d0be;
  --c-cfcabb-l: #cfcabb;
  --c-0e5d59-l: #0e5d59;
  --c-rgba-80-66-48-16-s: rgba(80, 66, 48, .16);
  --c-f2ede2-s: #f2ede2;
  --c-e6d9a3-l: #e6d9a3;
  --c-fbf9fd-s: #fbf9fd;
  --c-bfd8c7-l: #bfd8c7;
  --c-eef6f0-s: #eef6f0;
  --c-d7eadc-s: #d7eadc;
  --c-2f6941-t: #2f6941;
  /* Подпись источника в ленте «Процесса работы» («образец О-026»): 10.5px на
     БЕЛОМ фоне досье. Прежний #a89e8d одинаков в обеих темах — на тёмном он
     даёт 6.6, а на светлом 2.64 при норме 4.5, и в «Продуктах» так не читался
     61 элемент: сама подпись и номера-ссылки внутри неё, которые цвет
     наследуют (аудит 22.09.2026). Тёмной теме прежнее значение оставлено. */
  --c-a89e8d-t: #7d7364;
  --tile-violet-bg-3: #efe8f2;
  --c-rgba-80-66-48-22-s: rgba(80, 66, 48, .22);
  --c-ece9e3-s: #ece9e3;
  --c-55504a-t: #55504a;
  --c-b8860b-s: #b8860b;
  --c-b8860b-t: #b8860b;
  --c-2f7d4f-t: #2f7d4f;
  --c-b3261e-t: #b3261e;
  --c-7a9-s: #7a9;
  --c-2a7-t: #2a7;
  /* Превью листа книги в «Таблицах»: бумага, сетка, шапка с буквами колонок,
     рамка и уголок заметки. Значения — те, какими их показывает Google. */
  --sheet-paper: #ffffff;
  --sheet-ink: #1f2328;
  --sheet-grid: #e0e2e6;
  --sheet-head: #f1f3f4;
  --sheet-head-ink: #5f6368;
  --sheet-frame: #b9bcc2;
  --sheet-note: #f2a33c;
  /* Что ещё не уехало в Google: новая строка и изменённая ячейка. Цвета тоже
     «бумажные» — они лежат на листе и в тёмной теме не темнеют. */
  --sheet-new: #e3f6e6;
  --sheet-new-edge: #34a853;
  --sheet-new-ink: #ffffff;
  --sheet-changed: #fdf2c8;
  --sheet-changed-edge: #e0a800;
  /* «Финансы» (04.10.2026): шкала к цели — один зелёный тон тремя ступенями.
     Дорожка — светлая ступень, «сейчас» — тёмная (контраст к дорожке 3,3),
     «к месяцу прогноза» — средняя, штриховкой. */
  --fin-track: #e4efe8;
  --fin-now: #5e8c71;
  --fin-later: #a9c9b5;
  /* «Финансы» (09.10.2026): графики — три цвета по порядку, проверены на
     различимость при нарушениях цветового зрения против белой панели:
     вложено и прогноз — синий, потрачено и нужный темп — оранжевый, займы —
     бирюзовый (контраст 2,8 — у его полос всегда есть подпись). Остаток —
     дорожка, не серия. */
  --fin-c1: #2a78d6;
  --fin-c2: #eb6834;
  --fin-c3: #1baf7a;
  --fin-rest: #ebe5d8;
  /* «План недели» (14.10.2026, просьба владелицы: «разные типы задач разных
     оттенков», «задачи с подзадачами — другим цветом», «субботу — цветом
     опционального рабочего дня»). Полоса слева и мягкий фон пункта. */
  --tw-own-line: #a3c6b0;
  --tw-rec-bg: #f2eff9;
  --tw-rec-line: #9b8bc4;
  --tw-crm-bg: #ebf3f9;
  --tw-crm-line: #6fa3c4;
  --tw-cal-bg: #f9f3e3;
  --tw-cal-line: #d4b163;
  --tw-subs-bg: #e4f4f0;
  --tw-subs-line: #4fa892;
  --tw-sat-bg: #fdf6e6;
  --tw-sat-line: #e3bf72;
  --tw-sat-ink: #8a6420;
  /* Отпуск сотрудника (21.10.2026, её слово: «дни отпусков — другим цветом»):
     розовый, которого нет ни у одного вида задач. */
  --tw-vac-bg: #fcebef;
  --tw-vac-line: #df8ca1;
  --tw-vac-ink: #9c3b56;
  /* Выполненное — плашкой под днём плана (22.10.2026, её слово: «выделяя
     отдельным цветом»): зелёный ярче и теплее «своих» задач. */
  --tw-done-bg: #e7f5e2;
  --tw-done-line: #6cb062;
  --tw-done-ink: #2f6a29;
}

/* Единый вид всех полей ввода: одна рамка, один радиус, один отступ. */
input, select, textarea {
  background: var(--paper);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  font: inherit;
  outline: none;
}
/* ОДИН ОТСТУП ЕЩЁ НЕ ЗНАЧИТ ОДНА ВЫСОТА (аудит 24.09.2026). При одинаковых
   `padding: 7px 10px` и `font-size: 13px` браузер строил три разных поля:
   текстовое 34.8 px, `select` 36.0, `input[type=date]` 36.8 — у каждого своя
   строка содержимого. В форме они стоят рядом («Номер заказа» · «Статус» ·
   «Дата размещения» в окне «Новый заказ»), и ряд полей выглядел ступенькой.
   Высоту строки назначаем сами — 20 px, — и тогда высота считается
   арифметикой, а не нравом элемента: 20 + 14 отступа + 2 рамки = 36 у всех.
   Полям даты и времени убавляем по пикселю сверху и снизу: их внутренний
   редактор («01.02.2026» со стрелками и значком календаря) на пиксель выше
   обычной строки, и без поправки они снова вырастали до 38. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
select { line-height: 20px; }
input[type="date"], input[type="time"], input[type="month"],
input[type="week"], input[type="datetime-local"] { padding-top: 6px; padding-bottom: 6px; }
input:focus, select:focus, textarea:focus { border-color: var(--accent); }
input:disabled, select:disabled, textarea:disabled { opacity: .6; }
textarea { resize: vertical; }
input[type="checkbox"] { padding: 0; }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.hidden { display: none !important; }
.muted { color: var(--muted); font-weight: 400; }

/* ── стартовая страница: бренды ─────────────────────────── */

.gate {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  background: var(--bg);
  padding: 24px;
  overflow: auto;
}
.gate-inner { width: min(720px, 100%); text-align: center; }
.gate-logo { width: 72px; height: 72px; border-radius: 18px; object-fit: cover; }
.gate-title { margin: 14px 0 4px; font-size: 26px; letter-spacing: .2px; }
.gate-sub { margin: 0 0 26px; color: var(--muted); }
.gate-buttons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.gate-btn {
  padding: 26px 18px;
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.gate-btn:hover { border-color: var(--accent); background: var(--panel-2); }
.gate-brand { position: relative; display: grid; }
.gate-brand > .gate-btn { width: 100%; }
.gate-brand-gear { position: absolute; top: 6px; right: 6px; opacity: .55; }
.gate-brand:hover .gate-brand-gear, .gate-brand-gear:focus-visible { opacity: 1; }

/* Общие режимы и создание бренда: один ряд мелких розовых кнопок под брендами. */
.gate-extra {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.gate-link {
  padding: 8px 16px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--heavenly-pink);
  border: 1px solid var(--hushed-violet);
  border-radius: 999px;
  cursor: pointer;
}
.gate-link:hover { border-color: var(--accent); }

/* «Архив брендов» (20.10.2026): свёртка под брендами — бренды, с которыми
   работали; открыть посмотреть, вернуть в работу, удалить навсегда. */
.gate-archive { margin-top: 22px; text-align: left; }
.gate-archive-head {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer; color: var(--muted); font-size: 13px; list-style: none;
}
.gate-archive-head::-webkit-details-marker { display: none; }
.gate-archive-head::before {
  content: ''; width: 0; height: 0;
  border-left: 5px solid currentColor; border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s;
}
.gate-archive[open] > .gate-archive-head::before { transform: rotate(90deg); }
.gate-archive-count {
  min-width: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); text-align: center;
}
.gate-archive-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--gap); margin-top: 12px;
}
.gate-archive-card {
  display: flex; flex-direction: column; gap: 4px;
  padding: 14px 16px; border-radius: var(--radius);
  background: var(--panel); border: 1px dashed var(--line);
}
.gac-name { display: flex; align-items: center; gap: 6px; font-size: 16px; font-weight: 600; color: var(--text); }
.gac-when { font-size: 12px; color: var(--muted); }
.gac-nums { font-size: 13px; color: var(--text); }
.gac-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* Открыт бренд из архива: полоска «только просмотр» под шапкой. */
.archive-note {
  display: flex; align-items: center; gap: 12px;
  margin: 0 16px 8px; padding: 8px 14px; border-radius: var(--radius-sm);
  background: var(--warn); color: var(--warn-ink); font-size: 13px; font-weight: 500;
}
.archive-note .grow { flex: 1; }
.brand-delete-save { margin: 12px 0 4px; font-size: 13px; color: var(--muted); }

/* ── Обучалка «Как работать в CRM» (18.10.2026, `ui/guide.js`) ─────────────
   Карточка на стартовом окне, окно с главами и подсветка места на экране.
   Окно выше окон CRM (40) и панели Гермеса (56): его открывают поверх всего. */
.guide-gate {
  display: flex; align-items: center; gap: 14px; width: min(460px, 100%);
  margin: 26px auto 0; padding: 14px 18px; text-align: left;
  font: inherit; color: var(--text);
  background: var(--panel); border: 1px dashed var(--accent); border-radius: var(--radius);
  cursor: pointer;
}
.guide-gate:hover { background: var(--accent-dim); border-style: solid; }
.guide-gate-icon {
  display: inline-grid; place-items: center; flex: none; width: 42px; height: 42px;
  border-radius: var(--radius); background: var(--accent-dim); color: var(--accent-ink);
}
.guide-gate-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.guide-gate-title { font-size: 16px; font-weight: 600; }
.guide-gate-sub { font-size: 13px; color: var(--muted); }

.guide-overlay { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 16px; }
.guide-overlay.hidden { display: none; }
.guide-bg { position: absolute; inset: 0; background: var(--guide-scrim); }
.guide-panel {
  position: relative; display: grid; grid-template-columns: 240px minmax(0, 1fr);
  width: min(1180px, 100%); max-height: min(900px, calc(100vh - 32px));
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  overflow: hidden; box-shadow: 0 18px 50px var(--shadow-soft);
}
.guide-toc {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--bg); border-right: 1px solid var(--line);
}
.guide-toc-head { padding: 18px 16px 12px; }
.guide-toc-title { font-size: 16px; font-weight: 700; }
.guide-toc-sub { margin-top: 2px; font-size: 12px; color: var(--muted); }
.guide-bar { height: 6px; margin-top: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.guide-bar-fill { height: 100%; border-radius: 999px; background: var(--accent); }
.guide-toc-list { list-style: none; margin: 0; padding: 0 8px 12px; overflow: auto; }
.guide-toc-item {
  display: flex; align-items: center; gap: var(--gap); width: 100%;
  padding: 8px 10px; margin: 1px 0; text-align: left;
  font: inherit; font-size: 13px; color: var(--text);
  background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.guide-toc-item:hover { background: var(--panel-2); }
.guide-toc-item.on { background: var(--accent-dim); font-weight: 600; }
.guide-toc-icon { display: inline-grid; place-items: center; flex: none; color: var(--muted); }
.guide-toc-item.on .guide-toc-icon { color: var(--accent-ink); }
.guide-toc-name { flex: 1; min-width: 0; }
.guide-toc-done { color: var(--accent-ink); font-weight: 700; }

.guide-main { display: flex; flex-direction: column; gap: 14px; min-height: 0; padding: 18px 22px 16px; overflow: auto; }
.guide-main-head { display: flex; align-items: flex-start; gap: 12px; }
.guide-chapter-icon {
  display: inline-grid; place-items: center; flex: none; width: 40px; height: 40px;
  border-radius: var(--radius); background: var(--accent-dim); color: var(--accent-ink);
}
.guide-titles { flex: 1; min-width: 0; }
.guide-chapter { font-size: 12px; color: var(--muted); }
.guide-step-title { margin: 2px 0 0; font-size: 21px; font-weight: 700; }
.guide-close { flex: none; }
.guide-text { margin: 0; font-size: 16px; line-height: 1.5; }
.guide-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: auto; }
.guide-dots { display: flex; gap: 6px; }
.guide-dot {
  width: 9px; height: 9px; padding: 0; border-radius: 50%;
  background: var(--line); border: 0; cursor: pointer;
}
.guide-dot.on { background: var(--accent); width: 22px; border-radius: 999px; }
.guide-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
.guide-count { font-size: 12px; color: var(--muted); text-align: right; }

/* Кадр шага — снимок настоящего экрана CRM, рамка и стрелка на нужное место
   (20.10.2026: «нужен скрин и стрелочка»). Высота кадра — не больше половины
   окна: ширину тогда задаёт высота, и текст шага остаётся на экране. */
.guide-shot {
  --shot-h: min(58vh, 600px);
  --shot-ratio: 1.6; /* у кадра своё — ставит guide.js */
  position: relative; flex: none; align-self: center;
  width: min(100%, calc(var(--shot-h) * var(--shot-ratio)));
  margin: 0; overflow: hidden; cursor: zoom-in;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
}
.guide-shot:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.guide-shot img { display: block; width: 100%; height: 100%; object-fit: contain; user-select: none; }
.guide-shot-marks { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.guide-ring-halo { fill: none; stroke: var(--guide-arrow-halo); }
.guide-ring { fill: none; stroke: var(--guide-arrow); animation: guide-ring 1.8s ease-in-out infinite; }
.guide-arrow-halo { fill: var(--guide-arrow-halo); stroke: var(--guide-arrow-halo); stroke-linecap: round; stroke-linejoin: round; }
path.guide-arrow-halo { fill: none; }
.guide-arrow { fill: none; stroke: var(--guide-arrow); stroke-linecap: round; }
.guide-arrow-head { fill: var(--guide-arrow); }
@keyframes guide-ring { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .guide-ring { animation: none; } }
.guide-shot-none {
  display: grid; place-items: center; flex: none; min-height: 150px;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); color: var(--accent-ink);
}
/* Видео шага (30.10.2026) — плеер Rutube на месте снимка, той же высоты. */
.guide-video {
  --shot-h: min(58vh, 600px);
  position: relative; flex: none; align-self: center;
  width: min(100%, calc(var(--shot-h) * 16 / 9)); aspect-ratio: 16 / 9;
  overflow: hidden; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
}
.guide-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.guide-video-shot { align-self: flex-start; }
.guide-video-owner { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.guide-video-input { flex: 1 1 260px; min-width: 0; }
/* Крупно — поверх окна обучения, во весь экран; нажатие или Escape закрывают. */
.guide-zoom {
  position: fixed; inset: 0; z-index: 82; display: grid; place-items: center; padding: 20px;
  background: var(--guide-scrim); cursor: zoom-out;
}
.guide-zoom .guide-shot { --shot-h: calc(100vh - 40px); cursor: zoom-out; box-shadow: 0 18px 50px var(--shadow-soft); }

/* Подсветка места на экране и подсказка рядом. */
.guide-spot {
  position: fixed; z-index: 79; pointer-events: none; border-radius: var(--radius);
  box-shadow: 0 0 0 3px var(--accent), 0 0 0 9999px var(--guide-scrim);
  transition: left .15s, top .15s, width .15s, height .15s;
}
.guide-spot-none { inset: 0; border-radius: 0; box-shadow: none; background: var(--guide-scrim); }
.guide-tip {
  position: fixed; z-index: 81; width: min(340px, calc(100vw - 24px)); padding: 14px 16px 12px;
  background: var(--panel); border: 1px solid var(--accent); border-radius: var(--radius);
  box-shadow: 0 14px 40px var(--shadow-soft);
}
.guide-tip-step { font-size: 12px; color: var(--muted); padding-right: 22px; }
.guide-tip-title { margin-top: 2px; font-size: 16px; font-weight: 700; }
.guide-tip-text { margin: 6px 0 0; font-size: 14px; line-height: 1.45; }
.guide-tip-note { margin: 6px 0 0; font-size: 13px; color: var(--muted); }
.guide-tip-foot { display: flex; justify-content: space-between; gap: 8px; margin-top: 12px; }
.guide-tip-close { position: absolute; top: 8px; right: 8px; }

@media (max-width: 760px) {
  .guide-panel { grid-template-columns: 1fr; max-height: calc(100vh - 32px); }
  .guide-toc { border-right: 0; border-bottom: 1px solid var(--line); max-height: 150px; }
  .guide-toc-list { display: flex; gap: 4px; overflow-x: auto; padding-bottom: 8px; }
  .guide-toc-item { white-space: nowrap; width: auto; }
}

/* ── каркас: боковое меню + рабочая область ─────────────── */

.shell { display: flex; flex: 1; min-height: 0; }

.sidebar {
  flex: 0 0 224px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 14px 12px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow-y: auto;
}
.side-head { display: flex; align-items: center; gap: var(--gap); }
.side-head-text { min-width: 0; }
.side-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); margin-bottom: 6px;
}
.side-brands { display: flex; flex-direction: column; gap: 4px; }
.side-brand {
  text-align: left; padding: 7px 10px; border-radius: var(--radius-sm); font: inherit;
  border: 1px solid transparent; background: transparent; color: var(--text); cursor: pointer;
}
.side-brand:hover { background: var(--panel-2); }
.side-brand.active { background: var(--panel-2); border-color: var(--line); font-weight: 600; }
.side-brand-all { background: var(--accent); border-color: var(--accent); font-weight: 600; }
.side-brand-all.active { border-color: var(--ink); }

.side-nav { display: flex; flex-direction: column; gap: 3px; }
.side-item {
  display: flex; align-items: center; gap: 8px;
  text-align: left; padding: 9px 10px; border-radius: var(--radius-sm); font: inherit;
  border: 1px solid transparent; background: transparent; color: var(--text); cursor: pointer;
}
.side-item:hover { background: var(--panel-2); }
.side-item.active { background: var(--gossamer-green); border-color: var(--line); font-weight: 600; }
.side-item .badge { margin-left: auto; }
.side-item-brand { margin-top: 14px; color: var(--muted); border-top: 1px solid var(--line); border-radius: 0; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ── topbar ─────────────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
  flex-wrap: wrap;
}

.brand { display: flex; align-items: center; gap: var(--gap); min-width: 210px; }

.logo {
  width: 36px; height: 36px;
  display: block;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.brand-name { font-weight: 600; letter-spacing: .2px; }
.brand-sub {
  font-size: 11px; line-height: 1.35; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.brand-sub.stale { color: var(--ink); background: var(--warn); border-radius: 4px; padding: 1px 4px; }

.filters { display: flex; gap: 8px; flex: 1 1 200px; min-width: 0; }

.filters input { flex: 1; min-width: 0; max-width: 420px; }

.actions { display: flex; gap: 8px; align-items: center; flex: 0 0 auto; }
/* Узкое окно (аудит 27.10.2026): кнопки, часы и тема шапки шли одной строкой ~540 px и на
   телефоне вылезали за экран во всех разделах — переносим их строками. Широкое окно не задето. */
@media (max-width: 640px) {
  .actions { flex-wrap: wrap; flex: 1 1 100%; min-width: 0; }
}

/* Кнопка — размер и шрифт здесь; фон, рамка, скругление и цвета вида `.btn`,
   `.btn-ghost`, `.btn-primary`, `.btn-danger` — ОДНИМ местом ниже, в блоке «шапка и
   вкладки производств» (аудит 03.11.2026, Р-С-06: прежние значения тут были мёртвыми). */
.btn {
  border: 1px solid var(--line);
  color: var(--text);
  padding: 7px 13px;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.btn:disabled { opacity: .5; cursor: default; }
/* МАЛАЯ КНОПКА — 30 px, И ЭТО ОБЩИЙ РАЗМЕР МАЛОГО ЭЛЕМЕНТА (аудит
   24.09.2026). Раньше высота получалась сама собой (28.8 px), и всё, что
   вставало с такой кнопкой в один ряд, с ней не сходилось: выпадашка в
   «Таблицах» («Все производства») была на 7.5 px выше соседей, переключатель
   вкладок в «Ревью» — на 5.5. Круглое число позволяет собрать ряд из разных
   элементов и получить ровную линию. */
.btn-sm { padding: 4px 9px; font-size: 13px; min-height: 30px; }

.badge {
  display: inline-grid; place-items: center;
  min-width: 19px; height: 19px; padding: 0 5px;
  background: var(--warn); color: var(--ink);
  border-radius: var(--radius-sm); font-size: 11px; font-weight: 700;
}

/* ── tabs: одно производство = один таб ─────────────────── */

.tabs {
  display: flex;
  gap: 4px;
  padding: 8px 14px 0;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  flex: 0 0 auto;
}
.tabs-scroll {
  display: flex;
  gap: 4px;
  min-width: 0;
  flex: 1 1 auto;
  overflow-x: auto;
  scrollbar-width: thin;
  /* ОБРЕЗАННОЕ СЛОВО ДОЛЖНО ЧИТАТЬСЯ КАК «ПРОКРУТИ», А НЕ КАК ПОЛОМКА
     (аудит 24.09.2026). Полоса производств шире своего места (у MD Group —
     2660 px против 1029), и последняя видимая вкладка обрывалась на
     полуслове вплотную к кнопке «Скрипты»: со стороны это выглядело как
     наехавшие друг на друга элементы. Растворение края прямо говорит, что
     там продолжение; когда вкладки помещаются целиком, маски нет вовсе.

     Цвет в маске — это НЕПРОЗРАЧНОСТЬ, а не краска: браузер читает у неё
     только альфу, поэтому `black` здесь значит «видно целиком», тёмного
     двойника ему не нужно, и токеном он не становится. */
  mask-image: linear-gradient(to right, black calc(100% - 28px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 28px), transparent 100%);
}
/* Вкладки помещаются целиком или полоса докручена до конца — край снова
   чёткий: гасить нечего. Класс ставит `markTabsScrollEnd` в `ui/app.js`. */
.tabs-scroll.at-end { mask-image: none; -webkit-mask-image: none; }
.tabs > .tab { flex: 0 0 auto; }

.tab {
  border: 1px solid transparent;
  border-bottom: none;
  background: transparent;
  color: var(--muted);
  padding: 7px 13px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: -1px;
}
.tab:hover { color: var(--text); }
.tab.script-tab { color: var(--ink); background: var(--gossamer-green); font-weight: 600; }
.tab.script-tab:hover { background: var(--accent-dim); }

/* «Выбрать производство»: тот же список фабрик, только выпадашкой с поиском.
   Панель лежит в `body` и позиционируется по кнопке — у самой полосы стоит
   `overflow: hidden`, и внутри неё список был бы обрезан по нижнему краю. */
.tab-pick { flex: 0 0 auto; display: flex; align-items: center; }
.tab-pick-btn { white-space: nowrap; }
.tab-pick-btn.on { color: var(--text); background: var(--hover); }
.tab-pick-panel { position: fixed; z-index: 60; width: 280px; }
.tab.active {
  background: var(--bg);
  border-color: var(--line);
  color: var(--text);
  font-weight: 600;
}
.tab .n {
  background: var(--panel-2);
  border-radius: var(--radius-sm);
  padding: 0 6px;
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
}
.tab.active .n { background: var(--accent); color: var(--ink); }
.tab-sep { width: 1px; background: var(--line); margin: 6px 6px 8px; flex: 0 0 auto; }

/* ── переключатель вида ─────────────────────────────────── */

/* Переключатель вида стоит в одном ряду с малыми кнопками («Правила агента»
   в «Ревью», «Скрипты по образцам» в «Продуктах»), поэтому и высота у него
   та же — 30 px. */
/* Фон, рамка и скругление — одним местом в блоке «шапка и вкладки производств»
   (аудит 03.11.2026, Р-С-06). */
.viewswitch {
  display: flex; align-items: stretch; min-height: 30px;
  padding: 2px;
}
.vbtn {
  display: inline-flex; align-items: center;
  border: none; background: transparent; color: var(--muted);
  padding: 0 11px; font: inherit; cursor: pointer;
}
.vbtn.active { color: var(--text); font-weight: 600; }

/* ── таблица ────────────────────────────────────────────── */

.otable { width: 100%; border-collapse: collapse; font-size: 13px; }
.otable th, .otable td { padding: 7px 10px; text-align: left; border-bottom: 1px solid var(--line); }
.otable th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel); color: var(--muted); font-weight: 600;
  font-size: 12px; cursor: pointer; white-space: nowrap;
}
.otable th:hover { color: var(--text); }
.otable th .arrow { opacity: .5; font-size: 10px; }
.otable tbody tr:hover { background: var(--panel-2); }
.otable td.num { text-align: right; font-variant-numeric: tabular-nums; }
.otable .code { font-weight: 600; cursor: pointer; }
.otable .code:hover { color: var(--ink); background: var(--gossamer-green); }
.otable select { padding: 3px 7px; font-size: 12px; }
.otable tr.sel { background: var(--accent-dim); }
.bulkbar {
  position: sticky; bottom: 0; z-index: 3;
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: 9px 12px; margin-top: 10px;
}

/* ── формы редактирования ───────────────────────────────── */

.edit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--gap); }
.edit-grid label { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--muted); }
.edit-grid label.wide { grid-column: 1 / -1; }
.edit-grid input, .edit-grid select, .edit-grid textarea { font-size: 13px; }
.row-actions { display: flex; gap: 8px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
/* Текстовое поле в строке действий тянется, иначе placeholder обрезается. */
.row-actions > input:not([type='checkbox']) { flex: 1 1 220px; min-width: 0; }

/* ── управление производствами ──────────────────────────── */

.subtabs { display: flex; gap: 4px; margin-bottom: 14px; border-bottom: 1px solid var(--line); }
.subtab {
  border: none; background: transparent; color: var(--muted);
  padding: 7px 13px; font: inherit; cursor: pointer; border-bottom: 2px solid transparent;
}
.subtab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }

.srow, .crow {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 9px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  margin-bottom: 7px; background: var(--panel-2);
}
.srow.arch, .crow.arch { opacity: .55; }
/* ВСЁ В СТРОКЕ ПРОИЗВОДСТВА ОДНОГО РОСТА (аудит 24.09.2026). Строка тут
   плотная нарочно — их два десятка подряд, — и выпадашки с кнопкой набраны
   мелко (30 px). Поле имени осталось от общего вида полей, 36 px, и на
   каждой строке торчало на шесть пикселей выше соседей: список читался как
   гребёнка. */
.srow input.nm { flex: 1; min-width: 150px; font-size: 12px; padding: 5px 8px; }
.srow select, .crow select { font-size: 12px; padding: 5px 8px; }
/* Печатаемая выпадашка в строке производства («объединить с…»): у неё нет
   собственной ширины, как у <select> по самой длинной строке, — задаём сами,
   иначе поле схлопывается в узкую полоску. */
.srow .combo, .crow .combo { flex: 0 0 auto; width: 168px; }
.srow .combo .combo-input, .crow .combo .combo-input { font-size: 12px; padding: 5px 24px 5px 8px; }
.crow .nm { flex: 1; min-width: 160px; }
.crow small { color: var(--muted); }

/* «Производства» в шестерёнке (02.10.2026): производства и их чаты одним
   списком, группами по брендам. Строка — как у прежних «Чатов»: имя и справа
   переключатель «Гермес читает»; читаемая строка обведена зелёным. Сетка у
   строки, у строчек «чат 1 / чат 2» и у шапки группы одна — переключатели
   стоят столбиком, а подпись колонки ровно над ними. */
.sup-top { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.sup-add { display: flex; gap: 8px; align-items: center; flex: 1; }
.sup-add input { flex: 1; min-width: 0; }
.sup-group { margin-bottom: 18px; }
.sup-group-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 34px; gap: var(--gap);
  align-items: end; padding: 0 8px 6px 12px;
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}
.sup-group-title { display: inline-flex; align-items: center; gap: 4px; }
.sup-group-col { font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none; }
.sup-fold > summary.sup-group-head { display: list-item; cursor: pointer; padding-bottom: 8px; }
.sup-fold > summary.sup-group-head:hover { color: var(--text); }
.sup-row {
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
  margin-bottom: 6px;
}
.sup-row.on { border-color: var(--accent); background: var(--panel); }
.sup-row.arch { opacity: .65; }
.sup-line {
  display: grid; grid-template-columns: minmax(0, 1fr) 44px 34px; gap: var(--gap);
  align-items: center; min-height: 40px; padding: 5px 8px 5px 12px;
}
.sup-name {
  font: inherit; font-weight: 600; color: var(--text); text-align: left;
  background: none; border: none; padding: 0; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
span.sup-name { cursor: default; }
.sup-row:not(.on) .sup-name { font-weight: 500; color: var(--muted); }
.sup-name:hover { text-decoration: underline; text-underline-offset: 3px; }
span.sup-name:hover { text-decoration: none; }
.sup-line .switch { justify-self: center; }
.sup-chat { min-height: 32px; padding-top: 0; }
.sup-chat-name { font-size: 12px; color: var(--muted); padding-left: 14px; }
.sup-more { min-height: 26px; padding: 0 8px; color: var(--muted); letter-spacing: .08em; }
.sup-row.editing .sup-more { background: var(--hover); color: var(--text); }
.sup-edit {
  display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: flex-end;
  padding: 10px 12px 12px; border-top: 1px dashed var(--line);
}
.sup-edit .form-field { display: flex; flex-direction: column; gap: 3px; margin: 0; }
.sup-edit .form-field.wide { flex: 1 1 200px; min-width: 160px; }
.sup-edit .sup-edit-name { font-size: 13px; padding: 5px 8px; }
.sup-edit select { font-size: 12px; padding: 5px 8px; }
.sup-edit .combo { flex: 0 0 auto; width: 180px; }
.sup-edit .combo .combo-input { font-size: 12px; padding: 5px 24px 5px 8px; }
.switch {
  flex: 0 0 auto; width: 38px; height: 22px; border-radius: var(--radius-sm); padding: 0;
  border: 1px solid var(--line); background: var(--panel-2); position: relative;
  cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.switch .switch-knob {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--muted); transition: transform .15s ease, background .15s ease;
}
.switch.on { background: var(--accent); border-color: var(--accent); }
.switch.on .switch-knob { transform: translateX(16px); background: var(--panel); }
.switch:disabled { opacity: .5; cursor: default; }
/* Производство с неразобранным хвостом длиннее выбранного окна. */
.plan-gap {
  display: inline-block; margin-top: 3px; padding: 1px 6px; border-radius: 4px;
  background: var(--warn); color: var(--ink);
}
.script-text {
  margin: 0;
  padding: 12px;
  max-height: 48vh;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: 13px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace;
  user-select: text;
}

/* ── board ──────────────────────────────────────────────── */

.board {
  flex: 1;
  display: flex;
  gap: 12px;
  padding: 14px;
  overflow-x: auto;
  overflow-y: hidden;
  align-items: flex-start;
}

.board.history-view {
  display: block;
  overflow: auto;
  align-items: initial;
}
.history-wrap { width: min(1180px, 100%); margin: 0 auto; }
.history-body { display: flex; flex-direction: column; gap: 14px; }
.history-toolbar {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
.history-back { align-self: flex-start; }
.history-list { display: flex; flex-direction: column; gap: 8px; }
.history-empty {
  padding: 24px; border: 1px dashed var(--line); border-radius: var(--radius);
  color: var(--muted); text-align: center;
}

/* Свёрнутое производство: строка-раскрывашка, внутри последние заказы. */
.history-group {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.history-group.open { border-color: var(--accent); }
.history-group-head {
  display: flex; align-items: center; gap: var(--gap); width: 100%;
  padding: 12px 14px; border: none; background: transparent; color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
}
.history-group-head:hover { background: var(--panel-2); }
.history-caret { color: var(--muted); font-size: 11px; width: 12px; flex: 0 0 auto; }
.history-group-name { font-size: 15px; flex: 1; min-width: 0; }
.history-group-meta { display: flex; align-items: center; gap: var(--gap); font-size: 12px; flex: 0 0 auto; }

.history-group-body {
  display: flex; flex-direction: column; gap: 2px;
  padding: 4px 10px 12px; border-top: 1px solid var(--line);
}
.history-row {
  display: flex; align-items: baseline; gap: 12px; width: 100%;
  padding: 7px 8px; border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.history-row:hover { background: var(--panel-2); }
.history-row-code { flex: 0 0 auto; }
.history-row-title { flex: 1; min-width: 0; color: var(--muted); font-size: 12px; }
.history-row-facts { display: flex; align-items: center; gap: 8px; font-size: 12px; flex: 0 0 auto; }
.history-more { align-self: flex-start; margin: 8px 0 0 8px; }

/* Карточка на странице фабрики: полная хронология процессов. */
.history-order {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; cursor: pointer;
}
.history-order:hover { border-color: var(--accent); }
.history-order-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 10px; flex-wrap: wrap;
}
.history-order-facts { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.history-code { display: block; font-size: 15px; }
.history-title { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
/* Пять этапов воронки — пять колонок; при четырёх последний уезжал на строку ниже. */
.process-history { display: grid; grid-template-columns: repeat(5, minmax(140px, 1fr)); gap: var(--gap); }
.process-step {
  position: relative; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 9px 10px; min-width: 0;
}
.process-step:not(:last-child)::after {
  content: '→'; position: absolute; right: -10px; top: 50%; z-index: 1;
  color: var(--muted); transform: translateY(-50%); font-size: 12px;
}
.process-step.missing { opacity: .58; }
.process-label {
  font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .35px;
}
.process-date { margin-top: 3px; font-weight: 600; font-size: 13px; }
.process-days {
  display: inline-block; margin-top: 6px; color: var(--ink); background: var(--gossamer-green);
  border-radius: 4px; padding: 1px 5px; font-size: 12px;
}
@media (max-width: 760px) {
  .history-toolbar { align-items: stretch; flex-direction: column; }
  .history-picker select { width: 100%; min-width: 0; }
  .process-history { grid-template-columns: 1fr 1fr; }
  .process-step::after { display: none; }
  .history-group-head { flex-wrap: wrap; }
}

.col {
  flex: 0 0 268px;
  /* Ширину колонки задаёт ТОЛЬКО `flex-basis`, и `min-width: 0` — не
     украшение, а то, что заставляет его работать. У элемента гибкой строки
     минимальная ширина по умолчанию равна ширине его содержимого, поэтому
     одна длинная причина отказа в карточке («Текущий вариант не
     соответствует требованиям, принт у воротника не запрашивался», у неё
     стоит `white-space: nowrap`) раздувала колонку с 236 до 494 px, а
     соседние колонки уезжали за правый край окна: на доске образцов 24.09.2026
     «Завершено» было видно наполовину, «Архив» — не видно вовсе. Теперь
     длинная строка обрезается многоточием, как и задумано, а колонка стоит
     на своём месте. */
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  max-height: 100%;
  display: flex;
  flex-direction: column;
}
.col.drop { border-color: var(--accent); background: var(--accent-dim); }
.col.terminal { opacity: .72; }

/* Свёрнутая колонка («Отгружен» по умолчанию): показывает плитку с числом и
   кнопку разворота, а карточки не строит вовсе — их там со временем сотни.
   Уже колонки: свёрнутая занимает столько, сколько нужно её плитке. */
.col.folded { flex: 0 0 200px; }
.col-fold {
  margin: 0 8px 8px; padding: 5px 8px;
  border: 1px dashed var(--line); border-radius: var(--radius-sm);
  background: transparent; color: var(--muted); font: inherit; font-size: 12px;
  cursor: pointer;
}
.col-fold:hover { border-color: var(--accent); color: var(--ink); }

.col-head {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600;
}
.col-head .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; }
.col:nth-child(4n + 1) .col-head .dot { background: var(--marys-rose); }
.col:nth-child(4n + 2) .col-head .dot { background: var(--pastel-yellow); }
.col:nth-child(4n + 3) .col-head .dot { background: var(--orchid-petal); }
.col:nth-child(4n) .col-head .dot { background: var(--gossamer-green); }
.col-head .count { margin-left: auto; color: var(--muted); font-weight: 400; }

.col-body { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
/* ПУСТУЮ КОЛОНКУ НАЗЫВАЕТ ЕЁ СОБСТВЕННЫЙ НОЛЬ (аудит 24.09.2026). Под
   плиткой с крупным «0» стояло ещё и слово «пусто» — тот же факт вторым
   почерком, и на доске MD Group он повторялся пять раз подряд. Слово ушло, а
   МЕСТО осталось: пустая колонка — это мишень для перетаскивания карточки
   (правило «пустая статусная колонка с доски не пропадает»), и без запаса
   высоты она схлопнулась бы до одной плитки, в которую нечем целиться. */
.col-body:empty { min-height: 56px; }

.card {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--gap);
  cursor: grab;
}
.card:hover { border-color: var(--accent); }
.card.dragging { opacity: .45; }

.card-code { font-weight: 600; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.card-title { color: var(--muted); font-size: 12px; margin-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.shipping-date { color: var(--muted); }
.shipping-date-card { font-size: 12px; margin-top: 3px; }
.shipping-date-history { font-size: 12px; margin-top: 2px; }
.shipping-date-modal { margin-top: 2px; }
.shipping-date.shipping-alert {
  display: inline-block;
  padding: 4px 7px;
  border: 1px solid var(--c-d4a514-l);
  border-radius: 6px;
  background: var(--warn);
  color: var(--ink);
  font-weight: 600;
}
.shipping-date.shipping-overdue {
  border-color: var(--c-c96a70-l);
  background: var(--danger);
}
.shipping-countdown { margin-top: 2px; font-size: 11px; line-height: 1.25; }
.card-meta { display: flex; gap: 8px; margin-top: 7px; font-size: 11px; color: var(--muted); flex-wrap: wrap; }
.chip { background: var(--bg); border: 1px solid var(--line); border-radius: 5px; padding: 1px 6px; }
.chip.warn { color: var(--ink); border-color: var(--warn); background: var(--warn); }
/* Чья это строка. Показывается только в общих просмотрах — «Все бренды» и
   «Без бренда», — где данные двух компаний лежат рядом. Внутри бренда метка
   была бы повторением заголовка, поэтому её там нет. */
.chip.chip-brand { font-weight: 600; letter-spacing: .01em; }
/* Заказ идёт дольше, чем эта фабрика обычно тратит. */
.chip.danger { color: var(--ink); border-color: var(--danger); background: var(--danger); }
.otable td.stale-cell { background: var(--warn); font-weight: 600; }

/* ── задачи ─────────────────────────────────────────────── */

.task-list { display: flex; flex-direction: column; gap: 8px; }

.task-done { opacity: .7; }
.task-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.task-text { font-size: 15px; line-height: 1.4; overflow-wrap: anywhere; }
.task-done .task-text { text-decoration: line-through; }
.task-meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px;
}

.task-source { font-size: 12px; color: var(--muted); }
.task-source summary { cursor: pointer; }
/* Сообщение фабрики приходит как есть: ссылка или артикул без пробелов не
   должны распирать строку списка. */
.task-source-text { margin-top: 4px; white-space: pre-wrap; overflow-wrap: anywhere; }
.task-source-ru {
  margin-top: 3px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere;
}

.task-actions { display: flex; gap: 6px; flex: 0 0 auto; }

/* ── чек-листы карточки ─────────────────────────────────── */

/* `min(…, 100%)`: в месте уже 260 px жёсткая колонка не ужимается и вылезает
   за край — так чек-лист выходил за боковую панель карточки юнита. */
.checklists { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }

.checklist {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  padding: 10px 12px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.checklist.complete { border-color: var(--accent); background: var(--gossamer-green); }

.checklist-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.checklist-title { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.checklist-title small { color: var(--muted); font-size: 11px; }
.checklist-count { font-size: 12px; color: var(--muted); white-space: nowrap; }

/* Полоса — как `.tw-bar.sm` «Плана недели»: тонкая, с круглыми концами. У
   закрытого списка заливка тёмно-зелёная, а не чёрная (20.10.2026): на зелёном
   фоне `var(--ink)` читалась толстой чёрной (в тёмной теме — белой) чертой, а
   `var(--accent)` в светлой теме совпадает с фоном и пропала бы. */
.checklist-bar { height: 4px; border-radius: 999px; background: var(--paper); overflow: hidden; }
.checklist-fill { height: 100%; border-radius: 999px; background: var(--accent); transition: width .18s ease; }
.checklist.complete .checklist-fill { background: var(--ink-green); }

.checklist-items { display: flex; flex-direction: column; gap: 2px; }
.checklist-item {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 4px 6px; border-radius: 6px; cursor: pointer; font-size: 13px; line-height: 1.35;
}
.checklist-item:hover { background: var(--paper); }
.checklist-item input { margin: 2px 0 0; flex: 0 0 auto; }
.checklist-label { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.checklist-item.done .checklist-label { text-decoration: line-through; opacity: .55; }
.checklist-date { font-size: 11px; color: var(--muted); white-space: nowrap; }
/* «Узнать размерную таблицу»: стоит у своего пункта, пока он не отмечен. */
.checklist-ask { flex: 0 0 auto; margin-left: auto; white-space: nowrap; }
/* Подзадачи пункта (13.10.2026): две галочки под пунктом, с отступом под его
   галочку. Те же строки стоят в задаче ассистентке (`.task-subitems`). */
.checklist-subitems { display: flex; flex-direction: column; gap: 1px; margin: 0 0 4px 26px; }
.checklist-sub {
  display: flex; align-items: center; gap: 8px;
  padding: 2px 6px; border-radius: 6px; cursor: pointer; font-size: 13px; line-height: 1.35;
}
.checklist-sub:hover { background: var(--paper); }
.checklist-sub input { margin: 0; flex: 0 0 auto; }
.checklist-sub .checklist-label { color: var(--text-2); }
.checklist-sub.done .checklist-label { text-decoration: line-through; opacity: .55; }
.task-subitems { margin: 6px 0 2px; }
.task-subitems .checklist-subitems { margin-left: 0; }
.task-subitems-head { font-size: 12px; color: var(--muted); margin-bottom: 2px; }
/* Готовый запрос фабрике правится прямо в окне — поле во всю его ширину.
   Без этого `textarea` берёт родную ширину в 20 знаков и стоит узким
   столбиком у левого края, а две трети окна справа остаются пустыми. Правило
   одно на оба окна со скриптом-текстом: размерная таблица и вопрос о посылке;
   высоту каждое задаёт своим числом строк. */
.ask-script-text { width: 100%; line-height: 1.5; }

.checklist-badges { display: flex; flex-wrap: wrap; gap: 4px; }
.chip.ok-chip { background: var(--gossamer-green); border-color: var(--accent); }
.dev-table-checks { min-width: 190px; }

/* ── итог разбора ───────────────────────────────────────── */
/* Живёт внутри <pre> с логом, поэтому переносы возвращаем к обычным. */
.digest { display: flex; flex-direction: column; gap: 14px; font-family: inherit; white-space: normal; }
.digest-head { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.digest-group { display: flex; flex-direction: column; gap: 6px; }
.digest-title {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: 4px;
}
.digest-items { display: flex; flex-wrap: wrap; gap: 6px; }
.digest-item {
  display: flex; align-items: baseline; gap: 8px;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--text); font: inherit; cursor: pointer;
  text-align: left;
}
.digest-item:hover { border-color: var(--accent); background: var(--panel-2); }
/* Задача, которую Гермес закрыл сам: она уже снята, а не ждёт (22.09.2026). */
.digest-item.digest-done .digest-detail { text-decoration: line-through; color: var(--muted); }
.digest-detail { color: var(--muted); font-size: 13px; }
.digest-at { color: var(--muted); font-size: 12px; }

/* ── modals ─────────────────────────────────────────────── */

/* ОКНО НЕ УЕЗЖАЕТ ПОД ПАНЕЛЬ ГЕРМЕСА (24.09.2026).
   Панель разговора висит справа (`.chat-panel`, 400 px, z-index 56) ПОВЕРХ
   окна, а окно центрируется по всему экрану — и правая его часть оказывалась
   под панелью. На узком окне это незаметно, а на широком (`.modal-wide`,
   до 1580 px) под панелью пропадала целая колонка: в «Запросить КИЗы» — ТНВЭД.
   Считаем панель занятым местом: окно центрируется в остатке и в него же
   вписывает свою ширину. Окна-панели (`#order-modal`, `.as-drawer`) это не
   трогает — их `.modal-panel` позиционируется от экрана, а не отсюда. */
:root { --chat-room: 0px; }
@media (min-width: 900px) { body.chat-open { --chat-room: 400px; } }
.modal {
  position: fixed; inset: 0 var(--chat-room) 0 0; z-index: 40;
  display: grid; place-items: center;
}
.modal-bg {
  position: absolute;
  inset: 0;
  background: var(--hushed-violet);
  opacity: .78;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.modal-panel {
  position: relative;
  width: min(860px, calc(94vw - var(--chat-room)));
  max-height: 88vh;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal-narrow { width: min(480px, 94vw); }
/* Срочное окно CRM (11.11.2026, A11-Q3 «Срочное первым»): красная полоса слева — «Кончились
   лимиты Гермеса», «От фабрик нет новых сообщений», ключ от копий, просьба о КИЗах, спор правки. */
.modal.win-urgent .modal-panel { border-left: 5px solid var(--ink-rose); }

.modal-head {
  padding: var(--pad) var(--pad-lg);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}
/* Заголовок окна — гибкий элемент, и без `min-width: 0` он не даёт себя сжать:
   длинное имя контрагента одним словом уезжало за правый край боковой панели и
   обрезалось вместе с половиной названия. */
.modal-head > div { min-width: 0; }
.modal-code { font-weight: 700; font-size: 16px; overflow-wrap: anywhere; }
.modal-title { color: var(--muted); font-size: 13px; margin-top: 2px; }
/* Окно без подзаголовка не держит под названием пустую строку с отступом. */
.modal-title:empty { display: none; }
.modal-body { padding: var(--pad-lg); overflow-y: auto; }

.card-section { margin-bottom: 20px; }
.card-section:last-child { margin-bottom: 0; }
.card-section h3 { font-size: 13px; margin: 0 0 10px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }

.fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--gap); margin-bottom: 14px; }
.field-label { font-size: 11px; color: var(--muted); }
.field-value { font-weight: 500; margin-top: 1px; }

.status-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.status-row label { font-size: 12px; color: var(--muted); }
.status-row input { flex: 1; min-width: 180px; }
.hint { font-size: 12px; color: var(--muted); margin-top: 8px; }
/* Подсказка, которую заполняют позже (итог, пропущенные чаты), до этого места не занимает. */
.hint:empty { display: none; }
.hint code { background: var(--panel-2); padding: 1px 5px; border-radius: 4px; }

/* «ⓘ» — объяснение по нажатию (24.09.2026).
   Значок маленький нарочно: он стоит рядом с названием и не должен спорить с
   ним за взгляд. Плашка выше окон (`z-index` доски — 40, панели Гермеса — 56):
   значок бывает и внутри окна. */
.info-dot {
  position: relative;
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 13px; height: 13px; margin-left: 5px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 9px; font-weight: 600; font-style: italic; line-height: 1;
  cursor: pointer; flex: none;
}
/* ЗНАЧОК МАЛЕНЬКИЙ НАРОЧНО, А ПОПАДАТЬ В НЕГО НАДО С ПЕРВОГО РАЗА
   (аудит 24.09.2026). Тринадцать пикселей — это размер РИСУНКА, а не мишени:
   целиться в него мышью так же трудно, как в значок календаря у поля даты, с
   которого и началось правило `NadosPicker`. Невидимая накладка расширяет
   область нажатия до 25 px во все стороны и на разметку не влияет вовсе. */
.info-dot::after { content: ''; position: absolute; inset: -6px; border-radius: 50%; }
.info-dot:hover,
.info-dot[data-open="1"] { color: var(--text); border-color: var(--muted); }
/* В гибком ряду расстояние держит его собственный `gap`, а свой отступ
   значка прибавлялся сверху: в шапке «Ревью» между «Правилами агента» и «ⓘ»
   выходило 13 px против 8 у остальной пары, и значок читался как оторванный
   от ряда. */
.actions > .info-dot,
.row-actions > .info-dot,
.section-actions > .info-dot,
.filters > .info-dot { margin-left: 0; }
/* Внутри гибких подписей отступ даёт сам `gap` — второй съедал бы ширину и
   отправлял значок на свою строку. */
.metric-name .info-dot { margin-left: 4px; }
.metric-name-text { display: inline; }
.info-pop {
  position: fixed; z-index: 90; max-width: 280px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--text);
  font-size: 12px; line-height: 1.45; box-shadow: 0 8px 24px var(--shadow-soft);
}

/* timeline */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  position: relative; padding: 0 0 14px 18px; border-left: 2px solid var(--line);
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
  content: ""; position: absolute; left: -5px; top: 4px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted);
}
.timeline li.manual::before { background: var(--accent); }
.timeline li.agent::before { background: var(--ok); }
.ev-head { font-size: 13px; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.ev-note { color: var(--muted); font-size: 12px; margin-top: 2px; white-space: pre-wrap; }
.src { font-size: 10px; text-transform: uppercase; letter-spacing: .5px; padding: 1px 5px; border-radius: 4px; border: 1px solid var(--line); }
.src.manual { color: var(--ink); border-color: var(--accent); background: var(--gossamer-green); }
.src.agent { color: var(--ink); border-color: var(--ok); background: var(--gossamer-green); }

/* messages */
.msgs { display: flex; flex-direction: column; gap: 6px; }
.msg { background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 7px 10px; }
.msg.out { border-left: 3px solid var(--accent); }
.msg-head { font-size: 11px; color: var(--muted); display: flex; gap: 8px; flex-wrap: wrap; }
.msg-text { font-size: 13px; margin-top: 3px; white-space: pre-wrap; word-break: break-word; }
/* Перевод живёт под оригиналом и никогда его не заменяет. */
/* Вложение под сообщением: имя файла и две кнопки — открыть и сохранить. */
.msg-attach {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--line);
}
.msg-attach-name {
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.msg-ru {
  font-size: 13px;
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px dashed var(--line);
  color: var(--muted);
  white-space: pre-wrap;
  word-break: break-word;
}
.msg-ru::before { content: "RU  "; font-size: 10px; letter-spacing: .5px; color: var(--ink); background: var(--gossamer-green); font-weight: 600; }

/* Файлы заказа: строка на вложение, слева — снимок-миниатюра. */
.order-files { display: flex; flex-direction: column; gap: 6px; }
.order-file {
  display: flex; align-items: center; gap: var(--gap);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 7px 10px;
}
.order-file-rel { border-left: 3px solid var(--accent); }
.order-file-info { flex: 1; min-width: 0; }
.order-file-head { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.order-file-name { font-size: 13px; font-weight: 600; word-break: break-word; }
.order-file-thumb {
  width: 44px; height: 44px; object-fit: cover; border-radius: 6px;
  border: 1px solid var(--line); cursor: pointer; flex: none;
}
.order-file-locked {
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; color: var(--muted); cursor: default; background: var(--panel);
}
/* Документ вместо миниатюры — плашка с расширением: имя файла бывает
   машинным («purchaseorder image (1)-00041.xls»), а формат человек узнаёт
   с одного взгляда. */
.order-file-ext {
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; letter-spacing: .4px;
  color: var(--muted); background: var(--panel); cursor: default;
}
.order-file-meta { font-size: 12px; }
.order-file-actions { display: flex; align-items: center; gap: 4px; flex: none; }
.order-file-none { font-size: 11px; }
/* Рабочие документы производства — свёрнуты: не мусор, но и не про этот заказ. */
.order-files-more > summary {
  cursor: pointer; font-size: 13px; color: var(--muted);
  padding: 6px 2px; list-style: revert;
}
.order-files-more .order-files-list {
  display: flex; flex-direction: column; gap: 6px; padding-top: 4px;
}
/* Снимок и pdf — на весь просмотр, а не миниатюрой. */
.attach-image { max-width: 100%; max-height: 76vh; display: block; margin: 0 auto; border-radius: var(--radius-sm); }
.attach-pdf { width: 100%; height: 76vh; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2); }
/* Лист Excel — таблицей, а не простынёй с табами: в `<pre>` колонки
   разъезжались тем сильнее, чем длиннее название товара. */
.attach-sheet { margin-top: 8px; max-height: 64vh; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.attach-sheet .otable { font-size: 12px; border-collapse: collapse; width: max-content; min-width: 100%; }
.attach-sheet td { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 4px 7px; vertical-align: top; }
.attach-sheet-head { font-weight: 600; background: var(--panel-2); }
/* Что ещё лежит в архиве — ссылками, а не строкой через запятую. */
/* В архиве заказа шестьдесят файлов; список не должен занимать всё окно —
   он прокручивается, а таблица остаётся видна. */
.attach-entries {
  display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0 10px;
  max-height: 116px; overflow-y: auto;
}
.attach-entry {
  padding: 4px 9px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel-2); color: var(--ink); font: inherit; font-size: 12px;
  cursor: pointer; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.attach-entry:hover { border-color: var(--accent); background: var(--panel); }
/* Текст открытого файла — в окне, моноширинно, со скроллом. */
.attach-text {
  margin-top: 8px; max-height: 60vh; overflow: auto;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px; font-size: 13px; white-space: pre-wrap; word-break: break-word;
}

/* Состав заказа: блок виден всегда, даже когда состава нет. */
.items-actions { margin-top: 10px; }

/* review inbox */
.review {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px; margin-bottom: 10px; background: var(--panel-2);
}
/* Плашки шапки вопроса переносятся (аудит 27.10.2026): в узком окне дата уезжала за край. */
.review-head { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; font-size: 12px; color: var(--muted); }
.review-question { margin: 9px 0 5px; font-size: 15px; font-weight: 650; color: var(--text); }
.review-context { margin: 0 0 9px; color: var(--muted); font-size: 12px; white-space: pre-wrap; }
.review-why-label {
  margin-bottom: 3px; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
/* Основание пишется абзацами и списками — переносы в нём смысловые: у спора об
   импорте это строка на каждое расхождившееся поле. Без `pre-wrap` весь список
   слипался в один абзац. */
.review-why-text { color: var(--text); font-size: 13px; white-space: pre-wrap; }
/* Пары «образец → товар» перед кнопкой «Да, привязать»: строка на пару, номер
   слева колонкой — так видно, что именно подтверждаешь. */
.review-pairs { display: flex; flex-direction: column; gap: 3px; }
.review-pair {
  display: flex; gap: 6px; align-items: baseline;
  color: var(--text); font-size: 13px;
}
.review-pair > strong { flex: 0 0 auto; min-width: 58px; }
.review-message { margin: 0 0 9px; }
.review-message > summary {
  cursor: pointer; font-size: 13px; color: var(--muted); user-select: none;
}
.review-message > summary:hover { color: var(--text); }
.review-message[open] > summary { margin-bottom: 6px; }
/* Цифра на кнопке ответа: что нарисовано, то и нажимается с клавиатуры. */
.review-key {
  display: inline-flex; align-items: center; justify-content: center;
  /* Не сжимается и не тянется: колонка цифры одинакова у всех кнопок ряда. */
  flex: 0 0 auto; margin-top: 1px;
  min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 4px; background: var(--c-rgba-80-66-48-1-s); color: var(--muted);
  font-size: 10px; font-weight: 700; line-height: 1;
}
.btn-primary .review-key { background: var(--c-rgba-47-66-56-16-s); color: var(--on-accent-strong); }
.btn-danger .review-key { background: var(--c-rgba-122-51-57-12-s); color: var(--ink); }

/* Плашка, которая ведёт в карточку заказа или в раздел: выглядит как чип,
   ведёт себя как ссылка. */
.chip-link { font: inherit; font-size: 12px; cursor: pointer; }
.chip-link:hover { border-color: var(--accent); }

/* Что агент решает сам: панель сохранённых правил над очередью. */
.review-rules {
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px;
  margin-bottom: 12px; background: var(--panel-2);
}
.review-rule-row {
  display: flex; gap: var(--gap); align-items: center; padding: 7px 0;
  border-top: 1px solid var(--line);
}
.review-rule-row:first-of-type { border-top: none; }
.review-rule-text { flex: 1; min-width: 0; font-size: 13px; }
.review-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; min-width: 0; }
.review-feedback {
  width: 100%; min-height: 68px; margin: 10px 0 8px; resize: vertical;
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 9px 10px;
  color: var(--text); background: var(--panel); font: inherit;
}
.review-image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.review-image {
  width: 100%; height: 110px; object-fit: cover; border-radius: var(--radius-sm);
  border: 1px solid var(--line); cursor: zoom-in; background: var(--panel);
}
.review-image.unavailable { opacity: .35; }

/* Пара «снимок из переписки / кандидаты» — вопрос, который решают глазами.
   Требование пользователя 23.09.2026: увидел два фото рядом и нажал, без
   поиска артикула и переходов. Снимок из чата крупнее кандидатов: он тот
   самый, про который спрашивают, а справа — с чем сравнить. */
.review-compare {
  display: flex; gap: 12px; align-items: flex-start;
  margin-top: 8px; padding: 10px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel);
}
.review-compare-side { flex: 0 0 168px; }
.review-compare-options {
  flex: 1 1 auto; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px;
}
.review-compare-option {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 6px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: inherit; font: inherit;
}
.review-compare-option:hover { border-color: var(--accent); }
.review-compare-option:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.review-compare-label { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.review-compare-photo {
  width: 100%; height: 150px; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel);
}
.review-compare-option .review-compare-photo { height: 104px; cursor: pointer; }
.review-compare-side .review-compare-photo { cursor: zoom-in; }
.review-compare-empty {
  height: 104px; display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line); border-radius: var(--radius-sm);
  font-size: 12px; color: var(--muted);
}
.review-compare-code { margin-top: 4px; font-size: 12px; color: var(--muted); }

/* ЦЕНА БЕЗ АДРЕСА: слева названная цена и слова фабрики, справа плитки образцов.
   Левая сторона шире обычной пары «снимок / кандидаты» — там снимок в 168 px, а
   здесь читают китайскую фразу с условием и её перевод: «单价：42 含广东省内运费不含
   税，含吊牌，标签，码标» в узкую колонку не встаёт. */
.review-price .review-compare-side { flex: 0 0 280px; }
.review-price-figure { font-size: 22px; font-weight: 700; margin-bottom: 6px; }
.review-price .msg { margin: 0; }

/* Узкое окно: пара встаёт в столбик, иначе снимки сжимаются до нечитаемого. */
@media (max-width: 720px) {
  .review-compare { flex-direction: column; }
  .review-compare-side { flex: 1 1 auto; width: 100%; }
}

/* АЛЬБОМ: вопрос о фотографиях решается глазами.
   Требование пользователя 23.09.2026 после вопроса № 192 — «я не вижу, к какому
   артикулу меня просят прикрепить эти фотографии… всё это должно быть
   визуально видно». Слева пришедшее из переписки, справа лежащее в карточке;
   плитка — кнопка, выбранная отмечена галочкой и рамкой акцента. */
.review-album {
  margin-top: 8px; padding: 10px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel);
}
.review-album-head {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.review-album-face { display: flex; align-items: center; gap: var(--gap); flex: 1 1 auto; min-width: 0; }
.review-album-avatar {
  width: 56px; height: 56px; object-fit: cover; flex: 0 0 auto;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel-2); cursor: zoom-in;
}
.review-album-name { min-width: 0; }
.review-album-title { font-weight: 700; overflow-wrap: anywhere; }
.review-album-cols {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 10px;
}
.review-album-col { min-width: 0; }
.review-album-labels { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.review-album-label { font-weight: 600; font-size: 13px; min-width: 0; }
.review-album-hint { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.review-album-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 6px;
}
.review-album-tile {
  position: relative; display: block; width: 100%; padding: 3px; cursor: pointer;
  border: 2px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: inherit; font: inherit;
}
/* Взятая плитка отмечена и рамкой, и галочкой: одного цвета мало — выбор
   должен читаться и при беглом взгляде, и в чёрно-белом снимке экрана. */
.review-album-tile.on { border-color: var(--accent); background: var(--accent-dim); }
.review-album-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.review-album-photo {
  width: 100%; height: 76px; object-fit: cover; border-radius: 6px; display: block;
  background: var(--panel-2);
}
/* Невыбранная плитка приглушена — видно, что она отложена, а не просто стоит. */
.review-album-tile:not(.on) .review-album-photo { opacity: .45; }
.review-album-mark {
  position: absolute; top: 6px; left: 6px; width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1; border-radius: 50%;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink-green);
}
.review-album-tile.on .review-album-mark { border-color: var(--accent); }
.review-album-zoom {
  position: absolute; top: 6px; right: 6px; width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; line-height: 1; border-radius: 4px; cursor: zoom-in;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
}
.review-album-note { font-size: 11px; color: var(--muted); padding: 2px 0 0; }
/* Кадр, который положить нельзя, не нажимается вовсе: сохранение упало бы
   целиком из-за одного снимка. Курсор и бледность говорят об этом до нажатия. */
.review-album-tile.locked { cursor: not-allowed; border-style: dashed; }
.review-album-tile.locked .review-album-photo { opacity: .3; }
.review-album-tile.locked .review-album-note { color: var(--ink-rose); }
.review-album-gone {
  height: 76px; display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line); border-radius: 6px; font-size: 11px; color: var(--muted);
}
.review-album-count { margin: 10px 0 8px; font-size: 13px; color: var(--muted); }
.review-album-count.over { color: var(--ink-rose); font-weight: 600; }
/* Разбор суммы: галочек бывает больше, чем прибавится снимков. */
.review-album-why { margin: -4px 0 8px; font-size: 12px; color: var(--muted); }
/* ОТВЕТ СЛОВАМИ (29.09.2026): плитка — снимок с номером, а не кнопка. Номер
   стоит там же, где стояла галочка, и на него ссылаются в ответе. */
.review-album-tile.view { cursor: default; border-width: 1px; }
.review-album-tile.view .review-album-photo { opacity: 1; cursor: zoom-in; }
.review-album-no {
  position: absolute; top: 6px; left: 6px; min-width: 18px; height: 18px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; line-height: 1; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
}
.review-album-others { margin-top: 6px; }
/* Номер на снимке вопроса — тот же «снимок N», что в тексте (28.10.2026). */
.review-photo-numbered { position: relative; display: block; min-width: 0; }
div.review-compare-option { cursor: default; }
div.review-compare-option:hover { border-color: var(--line); }
div.review-compare-option .review-compare-photo { cursor: zoom-in; }
.review-answer-actions { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.review-answer-state { margin: 10px 0 8px; display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.review-answer-state.failed .review-why-label { color: var(--ink-rose); }
.review-answer-state.needs_owner .review-why-label { color: var(--ink-yellow); }
.review-answer-state.replied .review-why-label { color: var(--ink-yellow); }
.review-answer-said { font-size: 13px; white-space: pre-wrap; overflow-wrap: anywhere; }
/* Ответ Гермеса в карточке вопроса целиком (аудит 27.10.2026): его вопрос к ней — в конце. */
.review-hermes-reply { font-size: 13px; white-space: pre-line; overflow-wrap: anywhere; margin: 2px 0;
  padding-left: 10px; border-left: 2px solid var(--line); color: var(--text); }
.chat-msg-about { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.review-album-pick-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 8px; padding: var(--pad-lg); overflow-y: auto;
}
/* Отмеченная плитка: выбранный артикул в окне альбома — тем же видом, что
   догадка Гермеса (`.guess`) в вопросах «Ревью». */
.album-pick .review-compare-option.on { border-color: var(--accent); background: var(--accent-dim); }
.album-pick-panel { width: min(720px, 94vw); }
.album-pick-panel .modal-title { padding: var(--pad) var(--pad-lg) 0; }
.album-pick-panel .row-actions { padding: 0 var(--pad-lg) var(--pad-lg); }

/* «Обнаружено различие в цене» (29.09.2026): фото артикула, обе цены и три
   ответа — у каждого подпись, что он сделает. Фото — сразу, крупно: «чтобы я
   понимала, о чём речь». */
.price-diff-panel { width: min(560px, 94vw); }
.price-diff-panel:focus { outline: none; }
.price-diff-main { display: flex; gap: 14px; align-items: flex-start; }
.price-diff-photo {
  width: 150px; height: 190px; object-fit: cover; flex: none; cursor: zoom-in;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--bg);
}
.price-diff-nophoto {
  width: 150px; height: 190px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line); border-radius: var(--radius-sm); font-size: 12px; color: var(--muted);
}
.price-diff-text { min-width: 0; }
.price-diff-lead { font-size: 15px; line-height: 1.45; overflow-wrap: anywhere; }
.price-diff-meta { margin-top: 8px; font-size: 12px; }
.price-diff-choices { display: grid; gap: 8px; margin-top: 16px; }
.price-diff-reason { display: grid; gap: 8px; margin-top: 16px; }
.price-diff-reason[hidden], .price-diff-choices[hidden] { display: none; }
.btn.price-diff-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  text-align: left; white-space: normal; border-radius: var(--radius); padding: 8px 14px;
}
.price-diff-choice-label { font-weight: 600; }
.price-diff-choice-hint { font-size: 12px; opacity: .8; font-weight: 400; }
@media (max-width: 520px) {
  .price-diff-main { flex-direction: column; }
  .price-diff-photo, .price-diff-nophoto { width: 100%; height: 220px; }
}

/* Снижение цены, которое вписал ассистент (15.10.2026): у владелицы — кто и
   почему, и «Изменить…»; у ассистента — «Почему цена стала ниже?». Каркас —
   окно «Обнаружено различие в цене». */
.price-drop .price-diff-text { flex: 1; }
.price-drop-who { margin-top: 10px; font-size: 13px; line-height: 1.5; }
.price-drop-words { color: var(--muted); overflow-wrap: anywhere; }
.price-drop-edit { display: grid; gap: 8px; margin-top: 14px; }
.price-drop-field { display: grid; gap: 4px; font-size: 12px; }
.price-drop-field input, .price-drop-field textarea,
.price-drop-reason-text {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 13px;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--ink);
}
.price-drop-reason-text { margin-top: 10px; resize: vertical; }

/* «Фабрика запрашивает КИЗы» (01.10.2026): кто просит, по какому заказу,
   размеры с числами крупно — решение за секунды — и слова фабрики мелко. */
.kiz-ask-panel { width: min(560px, 94vw); }
.kiz-ask-panel:focus { outline: none; }
.kiz-ask-lead { font-size: 15px; font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.kiz-ask-block {
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg);
}
.kiz-ask-order { font-size: 13px; }
.kiz-ask-code { font-weight: 600; }
.kiz-ask-sizes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.kiz-ask-size {
  padding: 4px 10px; border-radius: 999px; font-size: 14px;
  border: 1px solid var(--line); background: var(--accent-dim);
}
.kiz-ask-size-bad { background: var(--warn); }
.kiz-ask-candidates { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.kiz-ask-quote { margin-top: 8px; font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; }
.kiz-ask-basis { margin-top: 10px; }
.kiz-ask-basis > summary { cursor: pointer; font-size: 12px; width: max-content; }
.kiz-ask-basis .kiz-ask-quote { margin-top: 6px; }
.kiz-ask-ru { margin-top: 2px; }
.kiz-ask-total { margin-top: 12px; font-size: 13px; font-weight: 600; }
.kiz-ask-panel .row-actions { margin-top: 14px; flex-wrap: wrap; }
.kiz-ask-note { font-size: 13px; margin-bottom: 6px; overflow-wrap: anywhere; }
.kiz-ask-note .kiz-ask-text { font-size: 12px; margin-top: 2px; }
/* Чей размер (05.10.2026): размер есть у двух артикулов заказа — плитка с фото
   и цветом и есть ответ. Снимок фабрики — рядом, в «Основании». */
.kiz-ask-pick { margin-top: 10px; font-size: 13px; font-weight: 600; }
.kiz-ask-articles { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.kiz-ask-article {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px 6px 6px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.kiz-ask-article:hover { border-color: var(--accent); background: var(--accent-dim); }
.kiz-ask-article:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kiz-ask-article img, .kiz-ask-nophoto {
  width: 44px; height: 44px; flex: none; border-radius: var(--radius-sm); object-fit: cover;
}
.kiz-ask-nophoto { border: 1px dashed var(--line); background: var(--bg); }
.kiz-ask-article b { display: block; font-size: 14px; }
.kiz-ask-article .muted { font-size: 12px; }
.kiz-ask-photo {
  display: block; max-width: 100%; max-height: 240px; margin-top: 6px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: zoom-in;
}

/* «GTIN отсутствует» (01.10.2026): поверх окна заявки — своё окно, чуть выше
   по стопке; строки без номера, а после «Вписать» — поле на каждую. */
.kiz-gtin { z-index: 45; }
.kiz-gtin-panel { width: min(520px, 94vw); }
.kiz-gtin-panel:focus { outline: none; }
.kiz-gtin-list { display: grid; gap: 6px; margin-top: 10px; }
.kiz-gtin-line { font-size: 14px; overflow-wrap: anywhere; }
.kiz-gtin-row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 190px); gap: 4px 10px;
  align-items: center; font-size: 13px;
}
.kiz-gtin-what { min-width: 0; overflow-wrap: anywhere; }
.kiz-gtin-row input { width: 100%; font-variant-numeric: tabular-nums; }
.kiz-gtin-row input.kiz-gtin-bad { border-color: var(--danger); background: var(--danger); }
.kiz-gtin-error { grid-column: 1 / -1; font-size: 12px; }
.kiz-gtin-error:empty { display: none; }
.kiz-gtin-panel .row-actions { margin-top: 14px; flex-wrap: wrap; }
.kiz-gtin-panel .hint.warn-text:empty { display: none; }

/* Узкое окно: полосы встают одна под другой, иначе плитки сжимаются до
   нечитаемого — а решают по ним глазами. */
@media (max-width: 720px) {
  .review-album-cols { grid-template-columns: 1fr; }
}

/* Снимок крупно поверх интерфейса. Фон и блюр — от .modal-bg (токены темы),
   здесь только раскладка самого изображения, без цветовых литералов. */
.image-zoom { z-index: 60; cursor: zoom-out; }
.image-zoom-full {
  position: relative;
  max-width: 94vw; max-height: 94vh;
  object-fit: contain;
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 40px var(--shadow-soft);
}
.review-actions .btn {
  /* Цифра — своя колонка, подпись — своя: длинный ответ переносится внутри
     подписи и второй строкой встаёт под первой, а не под цифрой. */
  display: inline-flex;
  align-items: flex-start;
  gap: 6px;
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
  min-width: 0;
  text-align: left;
  line-height: 1.35;
}
.rule-text { line-height: 1.55; white-space: pre-wrap; }
.rule-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; min-width: 0; }
.rule-actions .btn {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: left;
  line-height: 1.35;
}
.kind { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  border: 1px solid var(--warn); color: var(--ink); background: var(--warn); border-radius: 4px; padding: 1px 5px; }

.parse-list { display: flex; flex-direction: column; gap: 6px; }
.parse-item {
  display: flex; align-items: center; gap: var(--gap); padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; background: var(--panel-2);
}
.parse-item:hover { border-color: var(--accent); }
.parse-item .grow { flex: 1; }
.parse-item small { color: var(--muted); }

/* job panel */
/* Плашка работы отступает от открытой панели Гермеса тем же `--chat-room`,
   что и окна (аудит 24.09.2026): панель выше неё (z-index 56 против 50), и
   при открытом разговоре «Стоп» и «Свернуть» лежали под ней — разбор нельзя
   было ни остановить, ни дочитать, пока не закроешь чат. */
.job {
  position: fixed; right: calc(var(--chat-room) + 14px); bottom: 14px; z-index: 50;
  width: min(560px, calc(92vw - var(--chat-room)));
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 12px 40px var(--shadow-soft);
}
.job-head { display: flex; align-items: center; gap: var(--gap); padding: 10px 12px; border-bottom: 1px solid var(--line); }
.job-head #job-title { margin-right: auto; }
.spinner.stopped { border-top-color: var(--warn); animation: none; }
.job-log { margin: 0; padding: 10px 12px; max-height: 230px; overflow-y: auto;
  font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted);
  white-space: pre-wrap; word-break: break-word; }
.job-log:empty { display: none; }
/* Полоса хода под заголовком плашки работы (13.10.2026, `jobBar` в app.js). */
.job-bar { margin: 12px 16px 0; }
.job.mini .job-bar { display: none; }
.job-bar .nw-busy-fill { display: block; transition: width .4s ease; }
/* Развёрнутая плашка (03.11.2026): заголовок, полоса и одна строка — что идёт сейчас.
   Журнал — под «Подробнее», шрифт обычный, а не машинный. */
.job { width: min(400px, calc(92vw - var(--chat-room))); }
.job-head { border-bottom: 0; padding: 14px 16px 0; }
.job-head #job-title { font-size: 15px; }
.job-now { display: flex; align-items: baseline; gap: var(--gap); padding: 10px 16px 14px; font-size: 13px; color: var(--muted); }
.job-now #job-now-text { margin-right: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-now #job-now-text:empty::before { content: 'Идёт работа…'; }
.job-now .link-btn { font: inherit; font-size: 13px; flex: 0 0 auto; }
.job-log { border-top: 1px solid var(--line); font-family: inherit; font-size: 12px; line-height: 1.55; max-height: 180px; }
.job.mini .job-now { display: none; }

/* Свёрнутая плашка разбора.
 *
 * Развёрнутая занимает правый нижний угол целиком и закрывает собой кнопки
 * карточки, а разбор идёт минутами — всё это время работать в CRM нельзя.
 * Свёрнутая освобождает экран и оставляет ровно то, ради чего на неё смотрят:
 * идёт работа или кончилась и на каком она производстве из скольких. На сам
 * разбор это не влияет никак — он идёт на сервере, плашка только читает его
 * журнал, и опрос при сворачивании не прекращается.
 *
 * Плашка, а не голый кружок (16.09.2026). Кружок с одним вертящимся ободком не
 * отвечал ни на один вопрос: понять, что это вообще такое, можно было только
 * наведя мышь и дождавшись подсказки браузера. Теперь «2/3» стоит на самой
 * плашке.
 *
 * Размеры задаются здесь целиком — ширина, высота, отступы, радиус, — поэтому
 * развёрнутое состояние ничего за собой не тянет: снял класс, и всё вернулось
 * к правилу `.job` выше. Сворачивать и разворачивать можно сколько угодно раз.
 */
.job.mini {
  /* Прижата к тому же правому краю, что и кнопка Гермеса под ней, и ровно на
     её высоту выше: две плашки стоят столбиком, а не наезжают друг на друга. */
  right: calc(var(--chat-room) + 18px); bottom: 70px;
  width: auto; min-width: 44px; max-width: min(240px, 60vw); height: 40px;
  padding: 0 14px; border-radius: 999px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 20px var(--shadow-soft);
}
/* Шапка внутри плашки — обычная строка из значка и подписи. `min-width: 0`
   обязателен: без него длинная подпись распирала бы плашку за край экрана
   вместо того, чтобы обрезаться многоточием. */
.job.mini .job-head {
  border-bottom: 0; padding: 0; gap: 8px; min-width: 0; width: 100%;
  justify-content: center;
}
.job.mini #job-title, .job.mini #job-min, .job.mini #job-stop,
.job.mini #job-close, .job.mini .job-log { display: none; }
.job.mini .spinner { width: 16px; height: 16px; border-width: 2.5px; }
/* Подпись живёт только в свёрнутом виде: в развёрнутом её место занимает
   полный заголовок с названием производства. */
.job-mini-text { display: none; }
.job.mini .job-mini-text {
  display: block; min-width: 0;
  font-size: 13px; line-height: 1; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Пустая подпись (разбор только начался и номера ещё нет) не должна оставлять
   в плашке лишний отступ — тогда она снова становится ровным кружком. */
.job.mini .job-mini-text:empty { display: none; }
.job.mini:has(.job-mini-text:empty) { padding: 0; width: 44px; height: 44px; border-radius: 50%; }

.spinner {
  width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--accent);
  animation: spin .8s linear infinite; flex: 0 0 auto;
}
.spinner.done { border-top-color: var(--ok); animation: none; }
.spinner.failed { border-top-color: var(--danger); animation: none; }
@keyframes spin { to { transform: rotate(360deg); } }

/* «Внимание, идёт обновление программы» (29.09.2026, ui/update-watch.js).
   Выше всего остального (окна — 40, меню снимка — 95): пока сервер меняют,
   нажимать нечего. Фон — как у окон, тосты под ним не видны: ошибки
   оборванных запросов тут ни о чём не говорят. */
.update-overlay { position: fixed; inset: 0; z-index: 200; }
.update-overlay::before {
  content: ''; position: absolute; inset: 0;
  background: var(--hushed-violet); opacity: .82;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.update-overlay:focus { outline: none; }
/* Карточка — по середине ВИДИМОГО экрана (`vw`/`vh`), а не подложки: на
   телефоне доска шире экрана, подложка растягивается вместе с ней, и
   карточка по её середине уезжала вправо за край. */
.update-card {
  position: fixed; left: 50vw; top: 50vh; transform: translate(-50%, -50%);
  width: min(440px, calc(100vw - 32px)); max-height: calc(100vh - 32px); overflow-y: auto;
  box-sizing: border-box;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 28px 26px 24px; text-align: center;
  box-shadow: 0 18px 48px var(--shadow-soft);
}
.update-card .update-spinner { display: block; width: 30px; height: 30px; margin: 0 auto 16px; border-width: 3px; }
.update-card h2 {
  margin: 0 0 8px; font-family: var(--font-display); font-size: 21px; font-weight: 600;
  line-height: 1.3; color: var(--text); text-wrap: balance;
}
.update-card p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text-2); }
.update-card .update-long { margin-top: 12px; font-size: 13px; color: var(--muted); }
body.is-updating .toasts { display: none; }

/* «Основной компьютер руководителя… выключен» (29.09.2026, ui/update-watch.js):
   за CRM ответил сервер-вход. Плашка, а не окно — доска под ней остаётся видна
   и читается. По середине ВИДИМОГО экрана (`vw`), как и карточка обновления:
   на телефоне доска шире экрана. Выше тостов и меню (60–95), ниже окна
   обновления (200); тосты на это время спускаются под неё. */
.offline-banner {
  position: fixed; top: 12px; left: 50vw; transform: translateX(-50%); z-index: 150;
  width: min(640px, calc(100vw - 24px)); box-sizing: border-box;
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 16px; border-radius: var(--radius);
  background: var(--danger); color: var(--ink-rose); border: 1px solid var(--c-ddb0b4-s);
  box-shadow: 0 10px 28px var(--shadow-soft);
  font-size: 14px; line-height: 1.45;
}
.offline-banner svg { flex: none; margin-top: 1px; }
.offline-banner strong { display: block; font-weight: 600; }
.offline-banner span { display: block; }
.offline-banner .offline-next { margin-top: 4px; font-size: 12px; opacity: .85; }
.offline-banner[hidden] { display: none; }
.offline-banner .offline-close {
  flex: none; margin: -4px -6px 0 auto; padding: 2px 6px; border: 0; background: none;
  color: inherit; font: inherit; font-size: 16px; line-height: 1; opacity: .7; cursor: pointer;
}
.offline-banner .offline-close:hover { opacity: 1; }
/* «Сейчас только просмотр… На экране — копия от 14:32» (07.10.2026, ui/offline.js):
   без связи CRM у зашедших через интернет открывается из копии на их компьютере. */
.offline-banner .offline-copy { margin-top: 6px; font-weight: 600; }
.offline-banner .offline-copy[hidden] { display: none; }
/* Обновление по копии (13.11.2026, ui/update-watch.js): это не сбой — спокойная плашка цвета
   карточки обновления, с кружком вместо значка «нет связи»; работать под ней можно. */
.offline-banner[data-kind="updating_work"] {
  background: var(--panel); color: var(--text); border-color: var(--line);
}
.offline-banner[data-kind="updating_work"] .offline-copy { font-weight: 500; color: var(--text-2); }
.offline-banner .update-strip-spinner { flex: none; width: 18px; height: 18px; margin-top: 2px; border-width: 2px; }
body.is-offline .toasts { top: 132px; }

/* Значок связи в шапке (04.10.2026, ui/outbox.js) — только у зашедших через
   интернет: «На связи», «Сохраняю…», «Нет связи · 2 правки ждут». Нажатие —
   панель `.conn-pop`: что случилось и что будет с правками. Цвет — по состоянию,
   слова — в самом значке, без подсказки по наведению. */
.conn-chip {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
  max-width: 260px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel); color: var(--muted); font: inherit; font-size: 12px;
  white-space: nowrap; cursor: pointer;
}
.conn-chip-text { overflow: hidden; text-overflow: ellipsis; }
.conn-chip-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.conn-chip[data-state="ok"] .conn-chip-dot { background: var(--ok); box-shadow: 0 0 0 1px var(--ink-green); }
.conn-chip[data-state="busy"] .conn-chip-dot { background: var(--warn); box-shadow: 0 0 0 1px var(--ink-yellow); }
.conn-chip[data-state="warn"] { background: var(--warn); color: var(--ink-yellow); border-color: transparent; }
.conn-chip[data-state="warn"] .conn-chip-dot { background: var(--ink-yellow); }
.conn-chip[data-state="bad"] { background: var(--danger); color: var(--ink-rose); border-color: transparent; }
.conn-chip[data-state="bad"] .conn-chip-dot { background: var(--ink-rose); }
.conn-pop {
  position: fixed; z-index: 160; box-sizing: border-box; display: grid; gap: 6px;
  padding: 12px 14px; border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--panel); color: var(--text); box-shadow: 0 10px 28px var(--shadow-soft);
  font-size: 13px; line-height: 1.45;
}
.conn-pop strong { font-weight: 600; }
/* «Есть новое обновление» (11.11.2026, ui/update-watch.js): внизу справа, левее кнопки
   Гермеса, светится; нажала — обновление ставится. */
.update-ready {
  position: fixed; right: 74px; bottom: 18px; z-index: 56; height: 44px; padding: 0 18px;
  border-radius: 22px; border: 1px solid var(--accent); cursor: pointer;
  background: var(--accent); color: var(--on-accent-strong); font: inherit; font-size: 14px; font-weight: 700;
  animation: update-glow 1.8s ease-in-out infinite;
}
.update-ready:hover { filter: brightness(1.06); }
.update-ready.is-asked, .update-ready:disabled { cursor: default; animation: none; opacity: .85; }
@keyframes update-glow {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent); }
  50% { box-shadow: 0 0 22px 6px var(--accent); }
}
@media (prefers-reduced-motion: reduce) { .update-ready { animation: none; box-shadow: 0 0 14px 3px var(--accent); } }
@media (max-width: 600px) { .update-ready { right: 70px; padding: 0 12px; font-size: 13px; } }

/* Новая версия CRM ждёт, пока закроют окно с набранным (ui/update-watch.js). */
.reload-wait {
  position: fixed; bottom: 16px; left: 50vw; transform: translateX(-50%); z-index: 150;
  box-sizing: border-box; max-width: calc(100vw - 24px); padding: 10px 14px; border-radius: var(--radius);
  background: var(--warn); color: var(--ink-yellow); box-shadow: 0 10px 28px var(--shadow-soft);
  font-size: 13px; line-height: 1.45;
}

/* Окно беды «CRM не читает WeChat» (01.10.2026): ключи к базам перестали
   подходить после обновления WeChat. Жёлтое, а не красное: доска со всем
   остальным работает, не приходит только новая переписка. */
.wechat-banner {
  position: fixed; top: 12px; left: 50vw; transform: translateX(-50%); z-index: 150;
  width: min(680px, calc(100vw - 24px)); box-sizing: border-box;
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 16px; border-radius: var(--radius);
  background: var(--warn); color: var(--warn-ink); border: 1px solid var(--warn-ink);
  box-shadow: 0 10px 28px var(--shadow-soft);
  font-size: 14px; line-height: 1.45;
}
.wechat-banner svg { flex: none; margin-top: 1px; }
.wechat-banner strong { display: block; font-weight: 600; margin-bottom: 2px; }
.wechat-banner .wechat-what { display: block; }
.wechat-banner .wechat-actions { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 8px; }

/* Скелет раздела: мерцающие плашки, пока грузятся данные. */
.section-skeleton { padding: 22px 26px; }
.skeleton-rows { display: flex; flex-direction: column; gap: 12px; max-width: 720px; }
.skeleton-row {
  height: 46px; border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--panel-2) 25%, var(--line) 37%, var(--panel-2) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.3s ease-in-out infinite;
}
.skeleton-row:nth-child(2) { width: 92%; }
.skeleton-row:nth-child(3) { width: 84%; }
.skeleton-row:nth-child(4) { width: 88%; }
.skeleton-row:nth-child(5) { width: 78%; }
@keyframes skeleton-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton-row { animation: none; } }

/* ── Календарь года ─────────────────────────────────────────────────────────
 *
 * Классы здесь `yc-*`, а не `cal-*`, и это исправление, а не вкусовщина.
 * Мини-календарь выбора даты (`.calendar-pop`, ниже по файлу) уже занимал
 * `.cal-grid` и `.cal-day`, и стоял он ПОЗЖЕ — то есть переопределял годовую
 * сетку. Год выкладывался семью колонками вместо четырёх, клетка получала
 * фиксированные 27px, и весь календарь уезжал за правый край экрана. Имена
 * разведены, чтобы это не повторилось.
 */
.cal-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 12px 0 16px; flex-wrap: wrap; }
.cal-year-nav { display: flex; align-items: center; gap: 8px; }
.cal-year { font-size: 20px; font-weight: 700; min-width: 64px; text-align: center; }

/* Строки внутри уже цветные — своя рамка и фон вокруг них были рамкой
   вокруг рамок (аудит 16.09.2026). */
.cal-attention { margin-bottom: 18px; }
.cal-att-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border-radius: var(--radius-sm); margin-top: 6px; flex-wrap: wrap;
}
.cal-att-row.overdue { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.cal-att-row.soon { background: color-mix(in srgb, var(--warn) 14%, transparent); }
.cal-att-main { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; min-width: 0; }
.cal-att-title { background: none; border: none; font-size: 14px; font-weight: 600; cursor: pointer; color: var(--ink); padding: 0; text-align: left; }
.cal-att-title:hover { text-decoration: underline; }
.cal-att-ask { display: flex; align-items: center; gap: 8px; }
.cal-left { font-size: 13px; font-weight: 600; color: var(--warn-ink, var(--ink)); }

/* Цвета задач. Пастель той же природы, что и вся палитра приложения, но
 * десять различимых оттенков: рядом в клетке стоят до трёх полосок, и они
 * должны читаться как разные, а не как оттенки одного.
 *
 * Селекторы нарочно привязаны к своим классам, а не к голому `[data-c]`:
 * атрибут короткий, и правило на весь документ рано или поздно покрасило бы
 * чужой узел. */
.yc-chip[data-c="sage"],  .yc-chip-dot[data-c="sage"],  .yc-mark[data-c="sage"],  .yc-swatch[data-c="sage"], .tw-item[data-c="sage"]  { --cal-c: #7fa98c; }
.yc-chip[data-c="rose"],  .yc-chip-dot[data-c="rose"],  .yc-mark[data-c="rose"],  .yc-swatch[data-c="rose"], .tw-item[data-c="rose"]  { --cal-c: #d98b93; }
.yc-chip[data-c="sand"],  .yc-chip-dot[data-c="sand"],  .yc-mark[data-c="sand"],  .yc-swatch[data-c="sand"], .tw-item[data-c="sand"]  { --cal-c: #d4b163; }
.yc-chip[data-c="lilac"], .yc-chip-dot[data-c="lilac"], .yc-mark[data-c="lilac"], .yc-swatch[data-c="lilac"], .tw-item[data-c="lilac"] { --cal-c: #9b8bc4; }
.yc-chip[data-c="sky"],   .yc-chip-dot[data-c="sky"],   .yc-mark[data-c="sky"],   .yc-swatch[data-c="sky"], .tw-item[data-c="sky"]   { --cal-c: #6fa3c4; }
.yc-chip[data-c="clay"],  .yc-chip-dot[data-c="clay"],  .yc-mark[data-c="clay"],  .yc-swatch[data-c="clay"], .tw-item[data-c="clay"]  { --cal-c: #c98a5e; }
.yc-chip[data-c="mint"],  .yc-chip-dot[data-c="mint"],  .yc-mark[data-c="mint"],  .yc-swatch[data-c="mint"], .tw-item[data-c="mint"]  { --cal-c: #5fb3a1; }
.yc-chip[data-c="plum"],  .yc-chip-dot[data-c="plum"],  .yc-mark[data-c="plum"],  .yc-swatch[data-c="plum"], .tw-item[data-c="plum"]  { --cal-c: #a8688f; }
.yc-chip[data-c="olive"], .yc-chip-dot[data-c="olive"], .yc-mark[data-c="olive"], .yc-swatch[data-c="olive"], .tw-item[data-c="olive"] { --cal-c: #8d9c58; }
.yc-chip[data-c="coral"], .yc-chip-dot[data-c="coral"], .yc-mark[data-c="coral"], .yc-swatch[data-c="coral"], .tw-item[data-c="coral"] { --cal-c: #e08a6d; }

/* Двенадцать месяцев: четыре в ряд — три ряда.
 *
 * Колонки в долях (`minmax(0, 1fr)`), поэтому месяц ужимается вместе с окном
 * и горизонтальной прокрутки не бывает никогда. `minmax(0, …)` обязателен:
 * без нуля колонка не сжимается меньше своего содержимого и сетка вылезает.  */
.yc-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  /* МЕСЯЦЫ В РЯДУ КОНЧАЮТСЯ НА ОДНОЙ ЛИНИИ (аудит 24.09.2026). В ноябре
     2026-го шесть недельных строк, в соседних месяцах пять, и от `start`
     карточка ноября свисала на 43 px ниже трёх остальных: ряд читался как
     съехавший. Растягиваем — низ у всех общий, а лишняя строка внутри
     короткого месяца просто пуста, как в бумажном календаре. */
  align-items: stretch;
}
.yc-month {
  min-width: 0;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px 9px; background: var(--panel);
}
.yc-month-name {
  font-weight: 700; font-size: 13px; margin-bottom: 7px; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.yc-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.yc-wd {
  font-size: 10px; color: var(--muted); text-align: center; padding-bottom: 2px;
  overflow: hidden; text-overflow: clip; white-space: nowrap;
}
.yc-day {
  position: relative;
  aspect-ratio: 1; min-width: 0; padding: 0;
  border: none; background: transparent; border-radius: 6px;
  cursor: pointer; color: var(--ink); font: inherit; font-size: 12px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  overflow: hidden;
}
.yc-day.empty { cursor: default; }
.yc-day:not(.empty):hover { background: var(--panel-2); }
.yc-day:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.yc-num { line-height: 1; }
.yc-day.has-entry .yc-num { font-weight: 700; }
.yc-day.today { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Суббота — день по желанию (14.10.2026): тот же тёплый цвет, что в плане недели. */
.yc-wd.sat { color: var(--tw-sat-ink); font-weight: 600; }
.yc-day.sat { background: var(--tw-sat-bg); }
/* Рабочая суббота (15.10.2026): та же суббота, но с рамкой — её поставили в плане недели. */
.yc-day.sat.work { box-shadow: inset 0 0 0 1.5px var(--tw-sat-line); }
/* Отпуск (21.10.2026): свой — заливкой, у владелицы — отпуск сотрудника полоской снизу. */
.yc-day.vac, .yc-day.sat.vac { background: var(--tw-vac-bg); }
.yc-day.vac .yc-num { color: var(--tw-vac-ink); font-weight: 700; }
.yc-day.staff-vac { box-shadow: inset 0 -3px 0 var(--tw-vac-line); }
.yc-tip-vac { font-size: 12px; font-weight: 600; color: var(--tw-vac-ink); margin: 2px 0 4px; }
.cal-day-vac {
  padding: 8px 10px; margin-bottom: 8px; border-radius: var(--radius-sm);
  background: var(--tw-vac-bg); color: var(--tw-vac-ink); font-weight: 600; font-size: 13px;
}
.cal-vac-strip { margin: 8px 0; }
.yc-day.sat.work .yc-num { color: var(--tw-sat-ink); font-weight: 700; }
/* Задача задачника в календаре (14.10.2026) — точка-квадратик пустой рамкой,
   как галочка задачи; у записи календаря — залитая. */
.is-task .yc-chip-dot { background: transparent; box-shadow: inset 0 0 0 2px var(--cal-c, var(--accent)); }
.yc-day.today .yc-num { font-weight: 700; }

/* Тревога остаётся фоном: она про срок, а не про то, какая это задача.
 * Какая именно — говорят цветные полоски ниже. */
.yc-day.has-entry.soon { background: color-mix(in srgb, var(--warn) 26%, transparent); }
.yc-day.has-entry.overdue { background: color-mix(in srgb, var(--danger) 24%, transparent); }
.yc-day.has-entry.all-done { background: color-mix(in srgb, var(--ok) 16%, transparent); }

/* Полоски задач под числом. У периода полоска идёт через все его дни и
 * скругляется только на краях — отрезок читается отрезком. */
.yc-marks {
  position: absolute; left: 0; right: 0; bottom: 2px;
  display: flex; flex-direction: column; gap: 1px; align-items: stretch;
}
.yc-mark {
  height: 3px; background: var(--cal-c, var(--accent)); border-radius: 0;
  margin: 0 -1px;
}
.yc-mark.start { border-top-left-radius: 3px; border-bottom-left-radius: 3px; margin-left: 2px; }
.yc-mark.end { border-top-right-radius: 3px; border-bottom-right-radius: 3px; margin-right: 2px; }
.yc-mark.done { opacity: .42; }
/* Задач на дате больше, чем полосок влезло, — точка в углу; список в плашке. */
.yc-day.yc-more::after {
  content: ''; position: absolute; top: 3px; right: 3px;
  width: 3px; height: 3px; border-radius: 50%; background: var(--muted);
}

/* ── поиск по календарю (Q93) ───────────────────────────
   Строка поиска из шапки ищет по названиям и заметкам записей, а найденное
   подсвечивается прямо в сетке: клетка обводится, полоски чужих записей
   гаснут. Ничего не прячем — сетка остаётся картой года, а не выборкой. */
.yc-day.found {
  outline: 2px solid var(--accent); outline-offset: -2px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.yc-day.found .yc-num { font-weight: 700; }
.yc-mark.faded { opacity: .18; }
.yc-mark.found { height: 4px; }
.yc-chip.faded { opacity: .38; }
.yc-chip.found { border-color: var(--cal-c, var(--accent)); box-shadow: 0 0 0 1px var(--cal-c, var(--accent)); }
/* Что нашлось — полосой над сеткой. Найденное в другом году отдельной строкой:
   сетка календарная (Q92), и туда переводит стрелка ›. */
.cal-found { margin: 10px 0 4px; }
.cal-found-other {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  margin-top: 6px; font-size: 13px; color: var(--muted);
}

/* Полоса «какая задача каким цветом» под сеткой. */
.yc-legend { margin-top: 18px; }
.yc-legend-strip { display: flex; flex-wrap: wrap; gap: 6px; }
.yc-chip {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%;
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--ink); font: inherit; font-size: 13px;
  cursor: pointer;
}
.yc-chip:hover { border-color: var(--cal-c, var(--accent)); background: var(--panel-2); }
.yc-chip.done .yc-chip-title { text-decoration: line-through; color: var(--muted); }
.yc-chip-dot {
  width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto;
  background: var(--cal-c, var(--accent));
}
.yc-chip-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 26ch; }
.yc-chip-when { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* Плашка при наведении на дату. Своя, а не `title`: появляется сразу,
 * красит задачи их цветом и умещает несколько в компактную колонку. */
.yc-tip {
  position: fixed; z-index: 80; pointer-events: none;
  width: max-content; max-width: min(340px, calc(100vw - 16px));
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 10px 28px var(--shadow-soft);
  font-size: 13px; line-height: 1.35;
}
.yc-tip-day { font-weight: 700; margin-bottom: 5px; }
/* «Выполнено 2 из 5» / «Все задачи выполнены» под датой (22.10.2026). */
.yc-tip-done { font-size: 12px; font-weight: 600; color: var(--text-2); margin: 0 0 5px; }
.yc-tip-done.all { color: var(--tw-done-ink); }
.yc-tip-row { display: flex; align-items: flex-start; gap: 6px; margin-top: 5px; min-width: 0; }
.yc-tip-row .yc-chip-dot { margin-top: 4px; }
.yc-tip-body { flex: 1 1 auto; min-width: 0; }
.yc-tip-row.done .yc-tip-title { text-decoration: line-through; color: var(--muted); }
/* Длинное название — в две строки, дальше многоточие: плашка должна отвечать,
 * что за задача, и при этом не разрастаться на пол-экрана. */
.yc-tip-title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
}
.yc-tip-meta { font-size: 11px; color: var(--muted); }
.yc-tip-meta.overdue { color: var(--ink-rose); font-weight: 600; }
.yc-tip-meta.soon { color: var(--ink-yellow); font-weight: 600; }
.yc-tip-more { margin-top: 4px; color: var(--muted); font-size: 12px; }

/* Выбор цвета в панели записи. */
.yc-picker { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 4px; }
.yc-swatch {
  width: 24px; height: 24px; border-radius: 7px; padding: 0; cursor: pointer;
  border: 1px solid var(--line); background: var(--cal-c, var(--panel-2));
}
.yc-swatch.auto {
  width: auto; padding: 0 10px; font: inherit; font-size: 12px; color: var(--muted);
  background: var(--panel-2);
}
.yc-swatch.on { outline: 2px solid var(--ink); outline-offset: 1px; }
.yc-swatch:hover { border-color: var(--ink); }
/* Кнопка статуса идёт сразу за кружками и без подзаголовка — отступ отделяет
   её от блока «Цвет». */
.yc-picker + .btn { margin-top: 12px; }

/* Панель дня / записи */
.cal-form, .cal-dates, .cal-add-check { display: flex; flex-direction: column; gap: 8px; margin: 6px 0; }
.cal-dates { flex-direction: row; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.cal-input {
  padding: 7px 9px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--ink); font-size: 13px; width: 100%;
}
.cal-label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; flex: 1; min-width: 130px; }
.cal-period { display: flex; align-items: center; gap: 4px; font-size: 13px; }
.cal-endwrap { display: flex; align-items: center; gap: 6px; }
.cal-notes {
  width: 100%; min-height: 70px; padding: 8px 9px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--panel); color: var(--ink); font-size: 13px; resize: vertical;
}
.cal-banner { padding: 9px 12px; border-radius: var(--radius-sm); margin-bottom: 12px; display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; font-size: 13px; }
.cal-banner.overdue { background: color-mix(in srgb, var(--danger) 14%, transparent); }
.cal-banner.soon { background: color-mix(in srgb, var(--warn) 16%, transparent); }
.cal-day-entry {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 8px 10px; margin-top: 5px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
  cursor: pointer; font-size: 13px; color: var(--ink);
}
.cal-day-entry-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-day-entry.done .cal-day-entry-title { text-decoration: line-through; color: var(--muted); }
.cal-checklist { display: flex; flex-direction: column; gap: 4px; margin: 6px 0; }
.cal-check { display: flex; align-items: center; gap: 8px; }
.cal-check.done .cal-check-text { text-decoration: line-through; color: var(--muted); }
.cal-check-text { flex: 1; border: 1px solid transparent; background: transparent; color: var(--ink); font-size: 13px; padding: 4px 6px; border-radius: 6px; }
.cal-check-text:focus { border-color: var(--line); background: var(--panel); }
.cal-add-check { flex-direction: row; align-items: center; }
.cal-delete { margin-top: 14px; color: var(--ink-rose); }

/* Узкое окно: колонок меньше, рядов больше. Влезть по ширине важнее, чем
 * удержать ровно три ряда, — прокрутки вбок не должно быть никогда. */
@media (max-width: 1240px) {
  .yc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
}
@media (max-width: 900px) {
  .yc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
}
@media (max-width: 560px) {
  .yc-grid { grid-template-columns: minmax(0, 1fr); }
  .yc-chip-title { max-width: 18ch; }
}

/* toasts */
/* Колонка тостов сама клики не ловит — только сами тосты: просвет между ними и
   место под закрытым тостом остаются кнопками раздела, а не пустой рамкой
   поверх них (29.09.2026). Слой — выше открытого крупно фото (80) и меню снимка
   (95): «Сохранено в «Загрузки»» из просмотра фото пряталось под ним (02.11.2026). */
.toasts {
  position: fixed; top: 62px; right: 14px; z-index: 96;
  display: flex; flex-direction: column; gap: 8px; pointer-events: none;
}
.toasts > .toast { pointer-events: auto; }
.toast {
  background: var(--panel); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  padding: 9px 13px; border-radius: var(--radius-sm); max-width: 400px; font-size: 13px;
  box-shadow: 0 8px 24px var(--shadow-soft);
}
.toast.error { border-left-color: var(--danger); }
.toast.ok { border-left-color: var(--ok); }

/* «Задача отмечена готовой» (02.11.2026, `NadosDone` в ui-kit.js): строка сверху по
   середине с «Вернуть», выше окна «На сегодня» (40) и тостов (60); счёт в шапке. */
.done-bar {
  position: fixed; top: 62px; left: 50vw; transform: translateX(-50%); z-index: 70;
  max-width: min(560px, calc(100vw - 32px)); box-sizing: border-box;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px 6px 12px; border-radius: 999px; font-size: 13px;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 8px 24px var(--shadow-soft);
  animation: done-bar-in .18s ease-out;
}
@keyframes done-bar-in { from { opacity: 0; transform: translate(-50%, -6px); } }
@media (prefers-reduced-motion: reduce) { .done-bar { animation: none; } }
.done-bar-mark { color: var(--ok); font-weight: 700; }
.done-bar-text { white-space: nowrap; }
.done-bar-title {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted);
}
.done-bar-title:empty { display: none; }
.done-bar-back { flex: 0 0 auto; border-radius: 999px; }
.done-bar-x {
  flex: 0 0 auto; border: 0; background: none; color: var(--muted); cursor: pointer;
  font-size: 16px; line-height: 1; padding: 2px 6px;
}

/* ── разделы левого меню ────────────────────────────────── */

.section-view { flex: 1; overflow: auto; padding: 18px 20px 28px; }
/* «Ревью» и открытая панель Гермеса — РЯДОМ (28.10.2026, её ответ на опросник аудита: «Ревью»
   сдвигается влево, панель ничего не закрывает). Раздел кончается там, где начинается панель (400 px;
   отступ снаружи — и полоса прокрутки раздела не уходит под панель). Пороги — по ширине меню (62 px
   свёрнуто, 224 — развёрнуто): вопросу нужно ~300 px, со списком (292) — 360; не хватает на список —
   он прячется, рядом остаётся сам вопрос (J/K листают); не хватает и на вопрос — панель поверх, как раньше. */
@media (min-width: 800px) {
  body.chat-open .shell.nav-collapsed #section-view[data-section="reviews"] { margin-right: 400px; }
}
@media (min-width: 960px) {
  body.chat-open .shell:not(.nav-collapsed) #section-view[data-section="reviews"] { margin-right: 400px; }
}
@media (min-width: 800px) and (max-width: 1169px) {
  body.chat-open .shell.nav-collapsed #section-view[data-section="reviews"] .split-list { display: none; }
}
@media (min-width: 960px) and (max-width: 1329px) {
  body.chat-open .shell:not(.nav-collapsed) #section-view[data-section="reviews"] .split-list { display: none; }
}
/* Обёртка сборки раздела (`renderSection`) не должна участвовать в раскладке:
   правила вроде `.section-view:has(.card-split)` рассчитывают на то, что лист
   раздела — прямой ребёнок области. `display: contents` отдаёт детей наверх. */
.section-frame { display: contents; }
/* Шапка раздела — одна строка кнопок и фильтров; названия раздела в ней нет. */
.section-head { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.section-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.section-list { display: flex; flex-direction: column; gap: var(--gap); }
.empty-state {
  padding: 24px; border: 1px dashed var(--line); border-radius: var(--radius);
  color: var(--muted); text-align: center;
}
/* Доска — ряд колонок; пустой результат поиска в него не встаёт колонкой,
   поэтому на время он занимает всю ширину. */
.board.board-empty { display: block; overflow-y: auto; }
.board.board-empty .empty-state { max-width: 520px; margin: 40px auto; }
.board.board-empty .empty-state .btn { margin-top: 12px; }

/* ── сворачиваемые блоки карточки ───────────────────────── */

.fold-head { display: flex; align-items: center; gap: var(--gap); }
.fold-toggle {
  display: flex; align-items: center; gap: 6px;
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .5px; padding: 0;
}
.fold-toggle::before { content: '▸'; font-size: 11px; }
.fold.open .fold-toggle::before { content: '▾'; }
.fold-head .btn { margin-left: auto; text-transform: none; letter-spacing: 0; }
.fold-body textarea { width: 100%; font-size: 13px; }

/* вкладку производства можно перетащить мышью */
.tab.dragging { opacity: .5; }

/* ── карточки разделов ──────────────────────────────────── */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.entity-card {
  display: flex; flex-direction: column; gap: var(--gap);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px;
}
.entity-card:hover { border-color: var(--accent); }
.entity-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.entity-card-title { font-size: 13px; color: var(--muted); }
.entity-card-meta { display: flex; gap: 6px; flex-wrap: wrap; font-size: 11px; }
.entity-card-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: auto; }
.entity-card-actions select { padding: 4px 8px; font-size: 12px; }
.section-subhead {
  margin: 18px 0 10px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--muted);
}
.modal-body > .section-subhead:first-child { margin-top: 0; }
.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }

/* ── формы разделов ─────────────────────────────────────── */

.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--gap); }
.form-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.form-field.wide { grid-column: 1 / -1; }
.form-label { font-size: 11px; color: var(--muted); }
.form-field input, .form-field select, .form-field textarea { width: 100%; font-size: 13px; }

/* ── ручная правка полей ────────────────────────────────── */

/* Кто вписал значение. Ручное агент не перезаписывает, и видно это должно быть
   ДО правки: иначе непонятно, почему поле не изменилось после разбора. */
.field-source {
  align-self: flex-start;
  font-size: 11px;
  line-height: 1.4;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1px solid var(--line);
  color: var(--muted);
  cursor: help;
}
.field-source.manual { color: var(--ink); border-color: var(--ok); background: var(--gossamer-green); }
.field-source.agent { color: var(--muted); background: var(--panel); }
.form-hint { font-size: 11px; color: var(--muted); line-height: 1.35; }

/* Мелкая кнопка правки внутри строки таблицы или анкеты: она не должна
   перетягивать на себя взгляд с самого значения. */
.btn-xs { padding: 2px 6px; font-size: 11px; line-height: 1.3; }
.fact-row:not(:hover) .fact-edit,
.quote-table tr:not(:hover) .quote-edit .btn,
.items-table tr:not(:hover) .item-edit .btn { opacity: 0; }
.fact-edit, .quote-edit .btn, .item-edit .btn { transition: opacity .12s; }
/* Пока правка открыта, кнопку видно и без курсора — иначе с клавиатуры до неё
   не добраться: она исчезает ровно тогда, когда получает фокус. */
.fact-edit:focus-visible, .quote-edit .btn:focus-visible,
.item-edit .btn:focus-visible { opacity: 1; }
.item-edit, .quote-edit { text-align: right; }
.checklist-item:not(:hover) .checklist-edit { opacity: 0; }
.checklist-edit { margin-left: auto; flex: 0 0 auto; transition: opacity .12s; }
.checklist-edit:focus-visible { opacity: 1; }

/* ── спор о поле в «Ревью» ──────────────────────────────── */

.review-conflict {
  margin: 0 0 9px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
}
.conflict-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin: 6px 0;
}
.conflict-side { padding: 6px 8px; border-radius: 5px; border: 1px solid var(--line); }
.conflict-side.ours { border-color: var(--ok); }
.conflict-label { font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.conflict-value {
  font-size: 14px;
  color: var(--text);
  word-break: break-word;
  white-space: pre-wrap;
}
.conflict-source { font-size: 12px; color: var(--muted); }
.conflict-source-head { font-weight: 600; }
.conflict-source-text { margin-top: 3px; white-space: pre-wrap; word-break: break-word; }

/* ── фотографии ─────────────────────────────────────────── */

.photo-strip { display: flex; gap: 8px; flex-wrap: wrap; }
.photo-item {
  position: relative; width: 84px; height: 84px; border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--line); background: var(--panel-2); flex: 0 0 auto;
}
.photo-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-remove, .photo-save {
  position: absolute; top: 3px;
  width: 20px; height: 20px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink);
  font-size: 11px; line-height: 1; padding: 0;
  opacity: 0; transition: opacity .15s ease;
}
.photo-remove { right: 3px; }
/* Скачивание — слева, чтобы не путать с удалением справа. */
.photo-save { left: 3px; font-size: 13px; }
.photo-item:hover .photo-remove,
.photo-item:hover .photo-save,
.photo-remove:focus-visible, .photo-save:focus-visible { opacity: 1; }
.photo-save:hover { background: var(--accent); }
.photo-remove:hover { background: var(--danger); }
.photo-make-first {
  position: absolute; bottom: 3px; left: 3px;
  width: 20px; height: 20px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink);
  font-size: 11px; line-height: 1; padding: 0;
  opacity: 0; transition: opacity .15s ease;
}
.photo-item:hover .photo-make-first, .photo-make-first:focus-visible { opacity: 1; }
.photo-make-first:hover { background: var(--accent); }
/* Первое фото товара — подпись внизу, его берёт вся CRM. */
.photo-first { border-color: var(--accent); }
.photo-first-mark {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 1px 0;
  font-size: 10px; font-weight: 700; text-align: center; background: var(--accent); color: var(--on-accent-strong);
  pointer-events: none;
}
/* Фото, добавленное без связи (14.10.2026): ждёт в браузере и уйдёт само. */
.photo-pending { border-style: dashed; }
.photo-pending img { opacity: .55; }
.photo-pending-mark {
  position: absolute; left: 3px; right: 3px; bottom: 3px; text-align: center;
  font-size: 10px; line-height: 1.4; border-radius: 4px;
  background: var(--paper); color: var(--ink);
}
.photo-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  width: 84px; height: 84px; border-radius: var(--radius-sm); cursor: pointer; text-align: center;
  border: 1px dashed var(--line); background: var(--panel-2);
  color: var(--muted); font-size: 10px; line-height: 1.25; padding: 6px;
}
.photo-drop:hover, .photo-drop.over { border-color: var(--accent); background: var(--accent-dim); }
/* Окно «Импорт файлов»: та же зона, но на всю ширину — две строки текста
   в квадрат 84×84 не помещались. */
#fi-drop { width: 100%; height: auto; padding: 18px 14px; font-size: 12px; box-sizing: border-box; }
/* Предложение вернуться к незаконченному импорту: одна строка над зоной
   перетаскивания (аудит 22.09.2026). */
.fi-pending {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--panel); font-size: 12px;
}

/* ── звёзды и показатели производства ───────────────────── */

.stars { display: flex; gap: 2px; }
.star {
  border: none; background: transparent; cursor: pointer; padding: 0 1px;
  font-size: 18px; line-height: 1; color: var(--star-off);
}
.star.on { color: var(--c-d4a514-t); }
.metric-list { display: flex; flex-direction: column; gap: 8px; }
.metric-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 9px 11px; background: var(--panel-2);
}
.metric-label { flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 4px; }
/* Поле ввода несёт собственную ширину по умолчанию (size=20) и в узкой
   колонке распирало строку; ширину задаёт колонка. */
.metric-note { padding: 4px 8px; font-size: 12px; width: 100%; min-width: 0; box-sizing: border-box; }
.factory-rating { display: flex; align-items: baseline; gap: 8px; }
.factory-rating.big { margin-bottom: 6px; }
.rating-value { font-size: 22px; font-weight: 700; }
.factory-card { cursor: pointer; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--gap); }
.stat-box { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px; background: var(--panel-2); position: relative; }
/* «ⓘ» плитки стоит в её углу, а не в конце подписи: подпись бывает в две
   строки, и значок уезжал на вторую один, кружком непонятно от чего. */
.stat-box .info-dot { position: absolute; top: 8px; right: 8px; margin: 0; }
/* ЧИСЛА В РЯДУ ПЛИТОК СТОЯТ НА ОДНОЙ ЛИНИИ (аудит 24.09.2026). Подпись
   бывает и в одну строку («Готов → отгружен»), и в две («Размещение → начало
   пошива»), и от этого большое число первой плитки опускалось на 16 px ниже
   остальных трёх: ряд показателей в досье фабрики читался как сломанный.
   Подпись держит место под две строки всегда — пусто там или нет. */
.stat-label {
  font-size: 11px; color: var(--muted); padding-right: 16px;
  min-height: 2.9em;
}
.stat-value { font-size: 20px; font-weight: 600; margin-top: 2px; }

/* ── разработки ─────────────────────────────────────────── */

.dev-feed { display: flex; flex-direction: column; gap: 12px; }
.dev-card {
  display: flex; flex-direction: column; gap: 14px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px;
}
.dev-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.dev-head-main { min-width: 0; }
.dev-head-side { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.dev-name { font-size: 17px; letter-spacing: .2px; }
.dev-suppliers { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; font-size: 11px; }
.dev-head select { padding: 5px 8px; font-size: 12px; }

/* Подписанные блоки: карточка читается сверху вниз, а не сплошной лентой. */
.dev-block { display: flex; flex-direction: column; gap: 6px; }
.dev-block-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted);
}

/* Готовность по чек-листам одним кольцом — видно, не читая список. */
.dev-progress { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.dev-progress-ring {
  --percent: 0;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: conic-gradient(var(--accent) calc(var(--percent) * 1%), var(--panel-2) 0);
  font-size: 11px; font-weight: 700;
}
.dev-progress-ring span {
  width: 32px; height: 32px; border-radius: 50%; background: var(--panel);
  display: grid; place-items: center;
}
.dev-progress.complete .dev-progress-ring { background: conic-gradient(var(--ink) 100%, var(--ink) 0); }
.dev-progress.complete .dev-progress-ring span { background: var(--gossamer-green); }

/* Этапы — вертикальная линия с точками: видно, что это хронология. */
.dev-stages {
  list-style: none; margin: 0; padding: 0 0 0 16px;
  display: flex; flex-direction: column; gap: 6px;
  border-left: 2px solid var(--line);
}
.dev-stages li {
  position: relative; display: flex; gap: var(--gap); align-items: baseline; font-size: 13px;
}
.dev-stages li::before {
  content: ''; position: absolute; left: -21px; top: 6px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--panel); border: 2px solid var(--accent-dim);
}
.dev-stages li:last-child::before { border-color: var(--accent); background: var(--accent); }
.dev-stages li.muted::before { display: none; }
.dev-stage-date { color: var(--muted); font-size: 12px; flex: 0 0 92px; }
/* Номер прошлой версии образца в объединённой ленте: своя работа и работа
   предыдущего номера стоят в одной ленте, и путать их нельзя. */
.dev-stage-from { flex: 0 0 auto; font-size: 11px; }
.dev-stage-text { flex: 1; }
.dev-stage-remove {
  border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 11px;
  opacity: 0; transition: opacity .15s ease;
}
.dev-stages li:hover .dev-stage-remove, .dev-stage-remove:focus-visible { opacity: 1; }
.dev-supplier-row {
  display: flex; align-items: center; gap: var(--gap);
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 7px 10px; background: var(--panel-2);
}
.dev-supplier-row .grow { flex: 1; }
.dev-price { width: 110px; padding: 4px 8px; font-size: 12px; }

/* ── заголовок рабочей области ──────────────────────────── */

.topbar-title { min-width: 120px; flex: 0 0 auto; display: flex; align-items: center; gap: var(--gap); }
.topbar-brand { font-weight: 700; font-size: 15px; line-height: 1.2; }
/* «WB» рядом с названием бренда (14.10.2026): ссылка на витрину Wildberries. */
.topbar-wb { display: inline-flex; align-items: center; font-weight: 700; letter-spacing: 0.04em; text-decoration: none; color: var(--text); }

.side-home {
  margin-top: auto;
  padding: 9px 10px;
  text-align: left;
  font: inherit;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.side-home:hover { background: var(--panel-2); color: var(--text); }

/* ── причина простоя и ОТК на карточке ──────────────────── */

.card-reason {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline;
  margin-top: 7px; padding-top: 6px;
  border-top: 1px dashed var(--line);
  font-size: 11px; line-height: 1.3;
}
.card-reason-label {
  text-transform: uppercase; letter-spacing: .4px; font-size: 10px;
  color: var(--ink); background: var(--gossamer-green);
  border-radius: 4px; padding: 1px 5px;
}
.card-reason.unknown .card-reason-label { background: var(--warn); }
.card-reason.bad .card-reason-label { background: var(--warn); }
.card-reason-date { color: var(--muted); }

.col-action {
  margin-left: 6px;
  border: 1px solid var(--line);
  background: var(--warn);
  color: var(--ink);
  border-radius: 6px;
  padding: 2px 7px;
  font: inherit;
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
}
.col-action:hover { border-color: var(--accent); }
.col-head .count { margin-left: auto; }

/* ── модалка скриптов ───────────────────────────────────── */

.script-body { display: grid; grid-template-columns: minmax(230px, 300px) 1fr; gap: 16px; }
.script-picker { display: flex; flex-direction: column; gap: 14px; }
.script-group { display: flex; flex-direction: column; gap: 6px; }
.script-group-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted);
}
.script-choice {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  text-align: left;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.script-choice:hover { border-color: var(--accent); }
.script-choice.active { background: var(--gossamer-green); border-color: var(--accent); }
.script-choice-name { font-weight: 600; font-size: 13px; }
.script-choice-hint { grid-column: 1; color: var(--muted); font-size: 11px; line-height: 1.3; }
.script-choice-count {
  grid-row: 1; grid-column: 2; align-self: center;
  min-width: 20px; text-align: center;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 0 6px; font-size: 11px; color: var(--muted);
}
.script-choice-count:empty { display: none; }
.script-preview { min-width: 0; display: flex; flex-direction: column; }
.script-output { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.script-output-head { display: flex; align-items: center; gap: var(--gap); }
.script-output-name { font-weight: 600; font-size: 13px; margin-right: auto; }
.script-empty {
  display: grid; place-items: center; min-height: 180px; padding: 20px; text-align: center;
  border: 1px dashed var(--line); border-radius: var(--radius); color: var(--muted); font-size: 13px;
}
/* «Скрипты» из плана недели (15.10.2026): то же окно, сверху — какой фабрике
   пишем, слева ещё три группы, группы сворачиваются (открыта та, где выбранный
   скрипт); скрипт про один заказ — сначала плитки заказов над текстом. */
.script-hub-bar {
  display: flex; align-items: center; gap: var(--gap);
  padding: 10px var(--pad-lg); border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.script-hub-label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.script-hub-factory { flex: 0 1 340px; min-width: 0; }
.script-hub-factory .combo { width: 100%; }
.script-hub-factory .combo-input { width: 100%; font-size: 14px; font-weight: 600; }
/* Фабрики товара кнопками рядом с выбором (11.11.2026). */
.script-hub-card-factories { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.script-hub-card-factories:empty { display: none; }
.script-hub-card-factory {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 6px 12px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
}
.script-hub-card-factory span { color: var(--muted); font-size: 12px; }
.script-hub-card-factory:hover { border-color: var(--text-2); }
.script-hub-card-factory.on { border-color: var(--accent); background: var(--accent-dim); }
.script-group.hub-only { display: none; }
#script-modal.script-hub .script-group.hub-only { display: flex; }
#script-modal.script-hub .script-group.hidden { display: none; }
#script-modal.script-hub .script-picker { gap: 6px; }
.script-group-chev, .script-group-count { display: none; }
#script-modal.script-hub .script-group-label {
  display: flex; align-items: center; gap: 6px; padding: 6px 4px; border-radius: 6px;
  cursor: pointer; user-select: none;
}
#script-modal.script-hub .script-group-label:hover { background: var(--panel-2); color: var(--text); }
#script-modal.script-hub .script-group-chev {
  display: inline-grid; place-items: center; transform: rotate(90deg); transition: transform .15s;
}
#script-modal.script-hub .script-group.folded .script-group-chev { transform: none; }
#script-modal.script-hub .script-group-chev svg { display: block; }
#script-modal.script-hub .script-group-count {
  display: inline-block; margin-left: auto; min-width: 20px; padding: 0 6px; border-radius: var(--radius-sm);
  text-align: center; font-size: 11px; line-height: 18px; letter-spacing: 0; background: var(--panel-3);
}
#script-modal.script-hub .script-group.folded > .script-choice { display: none; }
/* «Скрипты» из «Продуктов» (28.10.2026): то же окно, чужие скрипты спрятаны. */
#script-modal .scope-off { display: none !important; }
/* Письма по образцам справа в окне: отметки, адрес, текст и кнопка — столбиком. */
.script-embed { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }
.script-embed .sample-pick-list { max-height: 260px; overflow-y: auto; }
.script-embed .script-text { margin: 0; }
.script-pick { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.script-pick-title { font-size: 12px; font-weight: 600; color: var(--text-2); }
.script-pick-list { display: flex; flex-wrap: wrap; gap: 6px; max-height: 210px; overflow-y: auto; }
.script-pick-item {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 6px 11px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2); color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.script-pick-item strong { font-size: 13px; }
.script-pick-sub { font-size: 11px; color: var(--muted); }
.script-pick-item:hover { border-color: var(--accent); }
.script-pick-item.on { background: var(--gossamer-green); border-color: var(--accent); }
/* Свои скрипты (18.10.2026): группа «Мои скрипты», ряды полей над текстом
   (плитки с фото у образцов и товаров) и окно правки. */
.script-custom-list { display: flex; flex-direction: column; gap: 6px; }
.script-custom-list:empty { display: none; }
.script-custom-add {
  padding: 8px 11px; border: 1px dashed var(--line); border-radius: var(--radius-sm);
  background: transparent; color: var(--text-2); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.script-custom-add:hover { border-color: var(--accent); color: var(--text); }
#script-modal.script-hub .script-group.folded > .script-custom-list,
#script-modal.script-hub .script-group.folded > .script-custom-add { display: none; }
.script-preview.cs-mode #script-output { order: -1; margin-bottom: 14px; }
.script-preview.cs-mode #script-pick { margin-bottom: 0; }
.cs-field .script-pick-list { max-height: 148px; }
.cs-field-value { font-weight: 500; color: var(--muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-field { display: flex; flex-direction: column; gap: 6px; }
.cs-field + .cs-field { padding-top: 8px; border-top: 1px solid var(--line); }
.cs-field-head { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text-2); }
.cs-field.done .cs-field-head::after { content: '✓'; color: var(--accent); font-weight: 700; }
.cs-tile { flex-direction: row; align-items: center; gap: 8px; padding: 4px 11px 4px 4px; }
.cs-tile img, .cs-noimg {
  width: 36px; height: 36px; flex: none; border-radius: 6px; object-fit: cover; background: var(--panel-3);
}
.cs-tile-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cs-input { max-width: 280px; font-size: 13px; }
#script-wait .cs-note { color: var(--text-2); font-weight: 600; }
#script-wait .cs-ru { white-space: pre-wrap; margin-top: 4px; }
.cs-editor { display: flex; flex-direction: column; gap: 12px; }
.cs-editor .cs-text { width: 100%; font: inherit; font-size: 13px; line-height: 1.5; resize: vertical; }
.cs-insert, .cs-brands { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.cs-chip {
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel-2); color: var(--text); font: inherit; font-size: 12px; cursor: pointer;
}
.cs-chip:hover { border-color: var(--accent); }
.cs-chip.on { background: var(--gossamer-green); border-color: var(--accent); font-weight: 600; }
.cs-actions { justify-content: flex-end; }
.cs-actions .cs-delete { margin-right: auto; }
@media (max-width: 720px) {
  .script-body { grid-template-columns: 1fr; }
}

/* «Новые образцы»: количество кнопками, ниже — что именно будет заведено. */
.nsm-counts { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.nsm-plan { margin-bottom: 14px; }
.nsm-plan:empty, .fi-plan:empty { display: none; }
.nsm-codes {
  font: 600 15px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .3px;
  padding: 9px 11px; margin-bottom: 6px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
}

/* Предупреждение разбора: не отказ, но и не рядовая подсказка. Пастель
   `--warn` во всей доске работает фоном, а не цветом текста. */
.hint.warn-text {
  background: var(--warn); color: var(--ink);
  border-radius: var(--radius-sm); padding: 5px 8px; margin-top: 6px;
}

/* Согласие завести новую фабрику из бланка (Q86): галочка, без которой импорт
   нового заказа не пойдёт. Стоит сразу под предупреждением и читается как его
   продолжение, а не как отдельная настройка. */
/* Бренд бланка — выбором, а не догадкой по доске (решение Q119). */
.imp-brand {
  display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 13px;
}
.imp-brand select { flex: 1; min-width: 0; }

.imp-new-supplier {
  display: flex; align-items: center; gap: 8px;
  margin-top: 8px; padding: 6px 8px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 13px; color: var(--ink);
}
.imp-new-supplier input { margin: 0; }

/* ── «Отправить на ОТК»: выбор заказов ──────────────────── */

/* Заказов в производстве бывает полтора десятка — список прокручивается,
   а окно остаётся одного размера. */
.qcs-orders {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 210px; overflow-y: auto;
  margin-bottom: 10px;
}
.qcs-orders:empty { display: none; }
.qcs-order {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 6px; border-radius: var(--radius-sm); cursor: pointer;
}
.qcs-order:hover { background: var(--panel-2); }
.qcs-code { font: 600 13px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }

/* «Отправить на примерку»: список образцов — те же строки, что у заказов на
   ОТК (`.qcs-order`), а письмо правят на месте, поэтому оно в textarea, а не
   в <pre>: в поле ввода кнопка «Перевести» не встаёт (TEXTAREA — в SKIP_TAGS
   у NadosTranslate), и в буфер уходит ровно то, что видно. */
.script-edit {
  width: 100%; min-height: 170px; margin: 0 0 8px;
  white-space: pre-wrap; overflow-wrap: anywhere;
  font: 13px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── тост с действием ───────────────────────────────────── */

.toast { display: flex; align-items: center; gap: var(--gap); }
.toast-text { flex: 1; min-width: 0; }
.toast .btn { flex: 0 0 auto; }
/* Крестик есть у каждого тоста, и попасть в него должно быть легко: прежние
   12 px без поля мимо промахивались. */
.toast-close {
  flex: 0 0 auto; align-self: flex-start;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin: -3px -6px -3px 0; padding: 0;
  border: none; border-radius: 6px; background: transparent; color: var(--muted);
  font: inherit; font-size: 13px; line-height: 1; cursor: pointer;
}
.toast-close:hover { background: var(--panel-2); color: var(--text); }

/* Заметки разработки: в ленте свёрнуты до нескольких строк, по клику целиком. */
.dev-notes {
  white-space: pre-wrap;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  cursor: pointer;
  overflow-wrap: anywhere;
}
.dev-notes.clamped {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── даты: клик открывает мини-календарь ────────────────── */

.date-pill {
  cursor: pointer;
  border-bottom: 1px dashed var(--line);
  padding-bottom: 1px;
}
.date-pill:hover { border-bottom-color: var(--accent); background: var(--panel-2); }

.calendar-pop {
  position: fixed;
  z-index: 70;
  width: 244px;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px var(--shadow-soft);
}
.cal-head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.cal-title { flex: 1; text-align: center; font-weight: 600; font-size: 13px; }
.cal-nav {
  width: 24px; height: 24px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font: inherit; line-height: 1; padding: 0;
}
.cal-nav:hover { border-color: var(--accent); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-weekday {
  text-align: center; font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .3px; padding-bottom: 2px;
}
.cal-day {
  display: grid; place-items: center;
  height: 27px; border-radius: 6px; font-size: 12px;
  border: 1px solid transparent;
}
.cal-day.empty { visibility: hidden; }
.cal-day.today { border-color: var(--ink); font-weight: 700; }
.cal-day.picked { background: var(--accent); color: var(--on-accent-strong); font-weight: 700; }
.cal-legend {
  display: flex; flex-direction: column; gap: 3px;
  margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--muted);
}
.cal-legend-item { display: flex; align-items: center; gap: 6px; }
.cal-legend-item::before {
  content: ''; width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto;
  border: 1px solid var(--line);
}
.cal-legend-item.today::before { border-color: var(--ink); border-width: 2px; }

/* ── фотография крупно ──────────────────────────────────── */

.photo-item img, .lightbox-source { cursor: zoom-in; }
.lightbox {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  background: var(--c-rgba-20-12-16-82-s);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 40px;
  overflow: hidden;
  touch-action: none;
}
.lightbox img {
  max-width: min(1100px, 92vw);
  max-height: 86vh;
  border-radius: var(--radius);
  background: var(--paper);
  object-fit: contain;
  user-select: none;
  will-change: transform;
}
.lightbox img.is-zoomed { cursor: grab; }
.lightbox img.is-zoomed:active { cursor: grabbing; }
/* Увеличенный снимок не закрывает кнопки. */
.lightbox > button, .lightbox-count { z-index: 1; }
.lightbox-close, .lightbox-nav {
  position: absolute;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 0;
}
.lightbox-close { top: 16px; right: 18px; width: 34px; height: 34px; font-size: 15px; }
/* «Сохранить в «Загрузки»» — рядом с крестиком, тем же кружком (29.09.2026).
   Тот же класс стоит и у снимка крупно из «Ревью» (`openImageZoom`). */
.lightbox-save {
  position: absolute; top: 16px; right: 60px; width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: 16px; line-height: 1; cursor: pointer;
}
.image-zoom .lightbox-save { position: fixed; right: 18px; z-index: 1; }

/* Меню правой кнопки у снимка CRM: «Скачать в «Загрузки»», «Скопировать
   изображение». Живёт в `body` и стоит выше лайтбокса и плашки «ⓘ». */
.photo-menu {
  position: fixed; z-index: 95; min-width: 210px; padding: 4px;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: 0 10px 28px var(--shadow-soft);
}
.photo-menu button {
  border: none; background: transparent; color: var(--text);
  font: inherit; font-size: 13px; text-align: left;
  padding: 7px 10px; border-radius: 6px; cursor: pointer;
}
.photo-menu button:hover, .photo-menu button:focus-visible { background: var(--panel-2); outline: none; }
.lightbox-nav { top: 50%; transform: translateY(-50%); width: 40px; height: 40px; font-size: 22px; }
.lightbox-nav.prev { left: 18px; }
.lightbox-nav.next { right: 18px; }
.lightbox-count {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
  color: var(--on-accent); font-size: 12px;
}

/* ── разработки: вид как у исходной таблицы ─────────────── */

/* Полоса вкладок — дно раздела, а не часть ленты. Прокручивается сам лист,
   поэтому заголовок сверху и ярлычки снизу остаются на месте, как в таблице. */
.section-view:has(.dev-tabs) {
  display: flex; flex-direction: column; padding-bottom: 0; overflow: hidden;
}
.dev-sheet {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  margin: 0 -20px; padding: 0 20px 18px;
  scrollbar-width: thin;
}

.dev-tabs {
  flex: 0 0 auto;
  display: flex;
  gap: 3px;
  align-items: flex-end;
  margin: 0 -20px;
  padding: 6px 20px;
  background: var(--panel);
  border-top: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: thin;
}
.dev-tab {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px 5px;
  border: 1px solid var(--line);
  border-bottom: 3px solid var(--line);
  border-radius: 0 0 8px 8px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.dev-tab:hover { background: var(--bg); }
.dev-tab.colored { border-bottom-color: var(--tab-color); }
.dev-tab.active {
  font-weight: 700;
  background: var(--bg);
  border-bottom-width: 4px;
}
.dev-tab.colored.active { background: color-mix(in srgb, var(--tab-color) 18%, var(--paper)); }
.dev-tab-count {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 0 5px; font-size: 10px; color: var(--muted); font-weight: 500;
}
.dev-tab-sep { width: 1px; align-self: stretch; background: var(--line); margin: 4px 5px; }

.dev-card.colored { border-left: 4px solid var(--tab-color); }
.dev-table-wrap { overflow-x: auto; }
.dev-table td { vertical-align: top; }
.dev-table .dev-table-photo .photo-item { width: 62px; height: 62px; }
.dev-table-notes { max-width: 420px; cursor: pointer; }
.dev-table .dev-notes { font-size: 11px; }
.dev-table .dev-notes.clamped { -webkit-line-clamp: 3; line-clamp: 3; }

/* ══════════════════════════════════════════════════════════════════════════
   Оформление раздела «Заказы» по утверждённому макету.
   Цвет держат плитки этапов сверху; колонки под ними бледные, чтобы не
   спорить с плитками. Карточка заказа открывается боковой панелью справа,
   меню сворачивается в полосу иконок.
   Правила намеренно лежат в конце файла: они перекрывают прежние.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── меню: иконки и сворачивание ────────────────────────── */

.sidebar { gap: 16px; padding: 14px 12px 12px; }
.side-head { gap: var(--gap); padding: 0 3px; }
.logo { width: 36px; height: 36px; border-radius: var(--radius-sm); }
.brand-name { font-weight: 700; }

.side-item { gap: var(--gap); border-radius: var(--radius-sm); padding: 9px 11px; }
.side-item svg { flex: 0 0 auto; opacity: .85; }
.side-item:hover { background: var(--hover); }
.side-item.active {
  background: var(--tile-violet-bg);
  border-color: transparent;
  color: var(--c-46405a-t);
  font-weight: 700;
}
.side-item .badge { background: var(--pastel-yellow); color: var(--ink-yellow); font-weight: 700; }

.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 4px; }
.side-toggle {
  display: flex; align-items: center; gap: var(--gap);
  padding: 9px 11px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: transparent;
  color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
}
.side-toggle:hover { background: var(--hover); color: var(--text); }
.side-home {
  margin-top: 0;
  display: flex; align-items: center; gap: var(--gap);
  border: none; border-radius: var(--radius-sm); padding: 9px 11px; font-size: 13px;
}
.side-home:hover { background: var(--hover); }
/* Свёрнутое меню: остаются иконки, подписи всплывают подсказкой браузера. */
.shell.nav-collapsed .sidebar {
  flex-basis: 62px;
  align-items: center;
  padding: 14px 0 12px;
}
.shell.nav-collapsed .side-head { justify-content: center; }
.shell.nav-collapsed .side-head-text { display: none; }
.shell.nav-collapsed .side-nav { align-items: center; }
.shell.nav-collapsed .side-item,
.shell.nav-collapsed .side-toggle,
.shell.nav-collapsed .side-home {
  position: relative;
  width: 42px; height: 38px;
  justify-content: center;
  padding: 0; gap: 0;
}
.shell.nav-collapsed .side-item .label,
.shell.nav-collapsed .side-toggle .label,
.shell.nav-collapsed .side-home .label { display: none; }
.shell.nav-collapsed .side-item .badge {
  position: absolute; top: 1px; right: 3px;
  min-width: 15px; height: 15px; padding: 0 4px;
  margin-left: 0; font-size: 10px;
}
.shell.nav-collapsed .side-foot { align-items: center; }

/* ── шапка и вкладки производств ────────────────────────── */

.topbar { padding: 12px 20px; gap: 12px; }
.topbar-brand { font-family: var(--font-display); font-weight: 400; font-size: 20px; }
.filters input {
  border-radius: 999px;
  background: var(--bg);
  padding: 8px 14px;
}

.btn { border-radius: 999px; background: var(--paper); border-color: var(--line); }
.btn:hover { background: var(--hover); border-color: var(--line); }
.btn-ghost { background: var(--paper); }
.btn-primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--on-accent-strong); font-weight: 700;
}
.btn-primary:hover { background: var(--c-a3c6b0-s); border-color: var(--c-a3c6b0-s); color: var(--on-accent-strong); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--ink-rose); }

.viewswitch { background: var(--c-f4f1e8-s); border: none; border-radius: 999px; }
.vbtn { border-radius: 999px; }
.vbtn.active { background: var(--paper); box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s); }

.tabs { padding: 9px 20px; gap: 4px; }
.tab {
  border: none; border-radius: 999px;
  padding: 6px 12px; margin-bottom: 0;
}
.tab:hover { background: var(--hover); }
.tab.active { background: var(--c-eef2e9-s); color: var(--text); font-weight: 700; }
.tab .n, .tab.active .n { background: transparent; color: inherit; opacity: .68; padding: 0; }
.tab.script-tab { background: var(--accent-dim); color: var(--ink-green); }

/* Число на вкладке производства — кружок в правом верхнем углу (02.10.2026,
   `tabBadge` в `ui/app.js`): заказы или образцы, смотря по режиму. Тихий, пока
   вкладка не выбрана. Полоса прокручивается вбок и режет всё, что вылезает за
   неё сверху, поэтому ей добавлен отступ ровно под кружок — и съеден у шапки,
   чтобы вкладки не уехали вниз. */
.tabs-scroll { padding-top: 6px; margin-top: -6px; }
.tab { position: relative; }
.tab.with-badge { margin-right: 6px; }
.tab-badge {
  position: absolute; top: -5px; right: -7px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm); font-size: 10px; font-weight: 600; line-height: 1;
  background: var(--panel-2); color: var(--muted);
  box-shadow: 0 0 0 1px var(--line);
  pointer-events: none;
}
.tab.active .tab-badge { background: var(--accent); color: var(--on-accent-strong); box-shadow: none; }

/* Шестерёнка «Бренды и фабрики»: под значком без подписи место квадратное,
   а не пилюля по ширине слова. Правило стоит ЗДЕСЬ, после общего `.tab`
   из этого же блока: тот переопределяет отступы, и выше его было бы не
   перебить. */
.tab.tab-gear, .btn.btn-gear { padding: 6px 8px; }
.tab.tab-gear svg, .btn.btn-gear svg { display: block; }

/* ── плитки этапов ──────────────────────────────────────── */

/* Плитка живёт в своей колонке первой строкой — тем и держится ровно по её
   ширине, и едет вместе с ней при горизонтальной прокрутке доски. */
.fun-tile {
  flex: 0 0 auto;
  display: flex; flex-direction: column;
  padding: 13px 14px 12px; border-radius: var(--radius) var(--radius) 0 0;
  background: var(--panel-3); color: var(--text-2);
}
.fun-head { display: flex; align-items: baseline; gap: 8px; }
.fun-count { font-family: var(--font-display); font-size: 27px; line-height: 1; }
.fun-name { font-size: 12px; font-weight: 700; }
.fun-meter { display: flex; align-items: center; gap: 6px; margin: 9px 0; }
.fun-bar { flex: 1; height: 5px; border-radius: 3px; background: var(--c-rgba-255-255-255-7-s); overflow: hidden; }
.fun-bar i { display: block; height: 100%; border-radius: 3px; background: currentColor; opacity: .5; }
.fun-share { font-size: 11px; opacity: .78; white-space: nowrap; }
.fun-risk {
  margin-top: 0; padding: 5px 9px; border-radius: var(--radius-sm);
  font-size: 11px; background: var(--c-rgba-255-255-255-7-s);
}
.fun-risk.bad { background: var(--marys-rose); color: var(--ink-rose); font-weight: 700; }

.fun-tile[data-status="new"] { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.fun-tile[data-status="production"] { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fun-tile[data-status="qc_sent"] { background: var(--tile-blush-bg); color: var(--tile-blush-text); }
.fun-tile[data-status="qc"] { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.fun-tile[data-status="shipped"] { background: var(--tile-green-bg); color: var(--tile-green-text-2); }

/* ── колонки доски ──────────────────────────────────────── */

.board { gap: var(--gap); padding: 14px 18px 16px; }

/* Колонка начинается своей плиткой: у обеих один радиус, поэтому верхние углы
   совпадают, а карточки идут прямо под плиткой. */
.col {
  flex: 0 0 236px;
  background: var(--c-f8f6ef-s);
  border: none;
  border-radius: var(--radius);
}
.col[data-status="new"] { background: var(--c-fdf3f4-s); }
.col[data-status="production"] { background: var(--tile-cream-bg); }
.col[data-status="qc_sent"] { background: var(--c-faf5f5-s); }
.col[data-status="qc"] { background: var(--tile-violet-bg-2); }
.col[data-status="shipped"] { background: var(--tile-green-bg-2); }
.col[data-status="done"], .col[data-status="cancelled"] { background: var(--c-f7f5ef-s); }
.col.drop { background: var(--c-eef4f0-s); outline: 2px solid var(--accent); }

/* Название этапа, счётчик и полоска риска стоят в плитке над колонкой; здесь
   шапка остаётся только ради собственного действия колонки. */
.col-head {
  padding: 10px 13px 2px;
  border-bottom: none;
}
.col-action {
  flex: 1 0 100%;
  border-radius: 999px; border: 1px solid var(--c-rgba-120-104-80-18-l);
  background: var(--c-rgba-255-255-255-72-s);
  letter-spacing: 0; text-transform: none; font-weight: 500;
}
.col-action:hover { background: var(--paper); border-color: var(--c-rgba-120-104-80-3-l); }
.col-body { padding: 10px 8px 11px; gap: 8px; }
/* Отступ сверху уже дала шапка с действием — второй раз он не нужен. */
.col-head + .col-body { padding-top: 6px; }

/* ── карточка заказа на доске ───────────────────────────── */

.card {
  background: var(--paper);
  border: none;
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s);
}
.card:hover { box-shadow: 0 0 0 1px var(--c-e3dbc9-s), 0 1px 3px var(--c-rgba-80-66-48-08-s); }
.card.selected { box-shadow: 0 0 0 2px var(--c-ddb0b4-s); }
/* «ОТК не пройден» — полоска слева, как у просроченного образца: карточка в
   «В производстве» лежит вперемешку с теми, что просто шьются, и бейджа внизу
   с расстояния не видно. Тень карточки повторяется, иначе класс её снял бы. */
.card.qc-failed { box-shadow: inset 3px 0 0 var(--c-b8515d-s), 0 1px 2px var(--c-rgba-80-66-48-06-s); }
.card.qc-failed:hover { box-shadow: inset 3px 0 0 var(--c-b8515d-s), 0 0 0 1px var(--c-e3dbc9-s), 0 1px 3px var(--c-rgba-80-66-48-08-s); }
.card.qc-failed.selected { box-shadow: inset 3px 0 0 var(--c-b8515d-s), 0 0 0 2px var(--c-ddb0b4-s); }
.card-code {
  font-family: var(--font-display); font-size: 16px; font-weight: 400;
  align-items: baseline;
}
.card-links {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--c-9c9282-t);
  font-family: Manrope, sans-serif;
}
.card-title { font-size: 12px; }
.card-meta { gap: 4px; margin-top: 8px; }
.chip {
  border: none; border-radius: 999px;
  background: var(--panel-3); color: var(--text-3);
  padding: 2px 9px; font-size: 11px;
}
.chip.warn { background: var(--c-fbf5da-s); color: var(--ink-yellow); border-color: transparent; }
.chip.danger { background: var(--tile-rose-bg-2); color: var(--ink-rose); border-color: transparent; }
.chip.ok-chip { background: var(--accent-dim); color: var(--ink-green); border-color: transparent; }
/* Плашка-кнопка: тот же вид, но по ней переходят в карточку. */
button.chip-link { font: inherit; font-size: 11px; cursor: pointer; }
button.chip-link:hover { background: var(--c-ece7d8-s); color: var(--text); }

.card-reason {
  margin-top: 8px; padding: 6px 9px; padding-top: 6px;
  border-top: none; border-radius: var(--radius-sm);
  background: var(--panel-3);
  font-size: 11px; color: var(--text-2);
}
.card-reason.unknown { background: var(--tile-rose-bg-2); color: var(--ink-rose); }
/* Непройденная проверка красится так же, как ненайденная причина простоя:
   и то и другое — «здесь ждут действия», а не просто справка. */
.card-reason.bad { background: var(--tile-rose-bg-2); color: var(--ink-rose); }
.card-reason-label {
  background: transparent; color: inherit; padding: 0;
  font-size: 10px; letter-spacing: .7px; opacity: .8; font-weight: 700;
}
.card-reason.unknown .card-reason-label,
.card-reason.bad .card-reason-label { background: transparent; }
.card-reason-date { color: inherit; opacity: .75; }

.shipping-date.shipping-alert {
  border: none; border-radius: 7px;
  background: var(--tile-yellow-bg); color: var(--ink-yellow);
  padding: 2px 8px;
}
.shipping-date.shipping-overdue { background: var(--tile-rose-bg-2); color: var(--ink-rose); }

/* ── боковая панель заказа вместо всплывающего окна ─────── */

#order-modal { display: block; pointer-events: none; }
#order-modal .modal-bg { display: none; }
#order-modal .modal-panel { pointer-events: auto; }
/* Панель шире прежних 404px: в неё встают три поля «Отправки на ОТК» в один
   ряд, а длинный адрес получателя перестал переноситься по букве.
   Ширина — ОДНОЙ переменной: её же читает отступ доски, иначе на узком экране
   правый край доски уезжал под панель (панель держала свой минимум, а отступ
   считался от доли экрана и выходил меньше). */
:root { --order-drawer: 468px; }
@media (max-width: 1240px) { :root { --order-drawer: 404px; } }
@media (max-width: 720px) { :root { --order-drawer: 92vw; } }

#order-modal .modal-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: var(--order-drawer); max-height: none;
  border: none; border-left: 1px solid var(--line); border-radius: 0;
  box-shadow: -10px 0 26px var(--c-rgba-90-74-55-08-s);
}
/* Доска не прячется под панелью: правый край уходит из-под неё. */
body.order-open .board { padding-right: calc(var(--order-drawer) + 16px); }

#order-modal .modal-head {
  flex-direction: column; align-items: stretch; gap: var(--gap);
  padding: 14px 16px;
  background: var(--c-fdf9ee-s);
  border-bottom: 1px solid var(--line-4);
}
.drawer-top { display: flex; align-items: baseline; gap: var(--gap); }
#order-modal .modal-code { font-family: var(--font-display); font-size: 24px; font-weight: 400; }
#order-modal .modal-title { font-size: 12px; margin-top: 3px; }
#order-modal .modal-head .btn { margin-left: auto; align-self: flex-start; }
.status-pill {
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700;
  background: var(--c-f3efe4-s); color: var(--text-2);
}
.status-pill[data-status="new"] { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.status-pill[data-status="production"] { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.status-pill[data-status="qc_sent"] { background: var(--tile-blush-bg); color: var(--tile-blush-text); }
.status-pill[data-status="qc"] { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.status-pill[data-status="shipped"], .status-pill[data-status="done"] { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.drawer-risks { display: flex; flex-wrap: wrap; gap: 6px; }
.drawer-risks:empty { display: none; }

.path-strip { display: flex; gap: 4px; margin-bottom: 18px; }
/* Плитка воронки — кнопка: по ней заказ и переводят на этап. */
.path-step {
  flex: 1; min-width: 0;
  padding: 7px 8px; border-radius: var(--radius-sm);
  background: var(--panel-6); color: var(--c-a09684-t);
  border: 1px solid transparent;
  font: inherit; text-align: left;
  cursor: pointer;
  transition: border-color .12s ease, transform .12s ease;
}
.path-step:hover:not(:disabled) { border-color: var(--gossamer-green); transform: translateY(-1px); }
.path-step:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 2px; }
.path-step:disabled { cursor: default; }
@media (prefers-reduced-motion: reduce) { .path-step { transition: none; } }
.path-step.done { background: var(--tile-green-bg); color: var(--ink-green); }
.path-step.now { background: var(--tile-yellow-bg); color: var(--ink-yellow); }
.path-name {
  font-size: 10px; text-transform: uppercase; letter-spacing: .4px;
  opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.path-date { font-size: 12px; font-weight: 700; margin-top: 4px; }

/* ── блоки боковой панели: один вид на все ───────────────
   Раньше блоки отличались друг от друга случайно: у одних был заголовок, у
   других два, отступы между полем и кнопкой были то 4, то 12 пикселей, а
   границ не было вовсе — и панель читалась одной сплошной простынёй. Теперь
   блок один и тот же: карточка с рамкой, заголовок сверху, поля внутри. */
#order-modal .modal-body { padding: 16px 18px 28px; }
#order-modal .card-section {
  margin-bottom: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel);
}
#order-modal .card-section h3 {
  font-size: 10px; letter-spacing: 1.4px; margin: 0 0 12px;
}
/* Свёрнутый блок не носит заголовочного отступа: под ним ничего нет. */
#order-modal .card-section.fold:not(.open) h3 { margin-bottom: 0; }
#order-modal .card-section .fold-body { padding-top: 12px; }
#order-modal .edit-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
#order-modal .row-actions { margin-top: 14px; gap: var(--gap); }
/* Между «Отправкой на ОТК» и «Результатом примерки» отступ больше обычного:
   это два разных решения, и второе не должно читаться продолжением кнопок
   первого. */
#order-modal #fold-qc-result { margin-top: 22px; }
/* Подпись рядом с заголовком свёрнутого блока: что внутри, не разворачивая. */
.fold-note {
  font-weight: 400; text-transform: none; letter-spacing: 0;
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.fold-note.bad { color: var(--ink-rose); }
.fold-note:empty { display: none; }
#order-modal .fold-toggle { min-width: 0; }
#order-modal .fold-head { gap: 8px; }
/* Служебная строка под кнопками блока — своей строкой, а не в ряд с ними:
   в ряду она растягивала кнопки и переносилась по слову. */
.fold-meta { font-size: 12px; margin-top: 10px; line-height: 1.4; }
.fold-meta:empty { display: none; }
/* «Уточнение»: две строки по умолчанию, «Показать всё» разворачивает. */
.reason-field {
  width: 100%; resize: vertical; line-height: 1.4;
  max-height: 3.4em; overflow: hidden;
}
.reason-field.expanded { max-height: 18em; overflow: auto; }
#order-modal .msg { border: none; border-radius: var(--radius-sm); background: var(--panel-5); }
#order-modal .msg.out { border-left: none; background: var(--c-eef4f0-s); }

/* Дата отгрузки в шапке панели — обычная строка: срок и просрочка уже
   показаны признаками риска рядом со статусом. */
#order-modal .modal-title .shipping-date,
#order-modal .modal-title .shipping-date.shipping-alert,
#order-modal .modal-title .shipping-date.shipping-overdue {
  display: block;
  padding: 0;
  border: none;
  background: none;
  color: var(--muted);
  font-weight: 400;
}
#order-modal .modal-title .shipping-countdown { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   Разделы в оформлении «Заказов»: выбранные варианты макетов.
   Список слева и карточка справа, узкие строки задач, группы контрагентов,
   полосы цен и таблица закрытых.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── список слева, подробности справа ───────────────────── */

.split-view { display: flex; gap: 14px; align-items: flex-start; }
/* Чьим именем CRM в Google (09.11.2026): строка над списком «Таблиц». */
.tables-google { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.tables-google-warn { color: var(--ink); font-weight: 600; }
.split-list { flex: 0 0 292px; display: flex; flex-direction: column; gap: 6px; }
.split-row {
  display: flex; align-items: center; gap: var(--gap); width: 100%;
  padding: 10px 12px; border: none; border-radius: var(--radius-sm);
  background: var(--panel); box-shadow: 0 1px 2px var(--c-rgba-80-66-48-05-s);
  font: inherit; color: var(--text); text-align: left; cursor: pointer;
}
.split-row:hover { box-shadow: 0 0 0 1px var(--c-e3dbc9-s), 0 1px 3px var(--c-rgba-80-66-48-08-s); }
.split-row.on { box-shadow: 0 0 0 2px var(--c-ddb0b4-s); }
.split-name { font-weight: 600; }
.split-meta { margin-left: auto; color: var(--muted); font-size: 12px; white-space: nowrap; }
.split-note { font-size: 11px; }
/* Имя фабрики и строка «чем нашлось» — в столбик, вторая мельче и приглушена.
   Ширину не даём: имя короткое, а совпадение обрезаем многоточием, иначе
   длинный адрес растянул бы строку списка. */
.split-name-box { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.split-match { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── плашка производства: имя, оценка, выполненные заказы ─
 *
 * Ничего больше в неё не ставим. Сумма в юанях, отсрочка платежа и время
 * ответа отсюда убраны: список из трёх десятков строк с четырьмя показателями
 * в каждой читался как таблица. Подробности живут в досье справа.            */
.factory-row { flex-wrap: wrap; }
.factory-row .split-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.factory-row-right {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto; margin-left: auto;
}
.factory-row-right .split-meta { margin-left: 0; }
/* Плашки брендов у записи библиотеки (20.10.2026): строка одна на фабрику, в
 * каких брендах она работает — плашками; где работала раньше — бледно. */
.factory-row-brands { display: flex; gap: 4px; flex: 0 0 auto; }
.factory-row-brands .chip { font-size: 11px; }
.ctr-brand-past { color: var(--muted); opacity: .7; }
.ctr-brand-cards { margin: 4px 0 8px; flex-wrap: wrap; }
/* Кнопку «Перевести» в плашку не ставит сам `NadosTranslate` (`.factory-row`
 * попал в его SKIP_INSIDE). Правило ниже — страховка на случай, если кнопка
 * всё же окажется внутри: в списке ей не место. */
.factory-row .nt-btn { display: none; }

/* ── фильтр по специализации ─────────────────────────────
 *
 * В разделе — ОДНА кнопка «Фильтр» под вкладками «Актуальные» / «Библиотека
 * фабрик»: чипов стало семь, и полоса из них занимала строку на всю ширину
 * ради выбора, который делают раз в месяц. Выбранное кнопка называет рядом с
 * собой, снимается оно кнопкой «Сбросить».
 *
 * Те же чипы (`.spec-chip`) остались в досье — там они назначают
 * специализацию, а не фильтруют, и выбор там ежедневный.                     */
.spec-filter, .spec-edit {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 12px;
}
.spec-filter-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--text); font: inherit; font-size: 13px;
  cursor: pointer; white-space: nowrap;
}
.spec-filter-btn:hover { border-color: var(--accent); background: var(--panel-2); }
.spec-filter-btn.on { background: var(--accent-dim); border-color: var(--accent); font-weight: 600; }
.spec-filter-btn.on .spec-chip-n { color: var(--ink-green); }
.spec-filter-now {
  font-size: 12px; color: var(--muted); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.spec-filter-clear {
  border: none; background: none; padding: 0; font: inherit; font-size: 12px;
  color: var(--muted); text-decoration: underline; cursor: pointer;
}
.spec-filter-clear:hover { color: var(--ink-rose); }
.spec-pick-list { display: flex; flex-direction: column; gap: 2px; max-height: 340px; overflow-y: auto; }
.spec-pick-row {
  display: flex; align-items: center; gap: var(--gap);
  padding: 7px 8px; border-radius: var(--radius-sm); cursor: pointer;
}
.spec-pick-row:hover { background: var(--panel-2); }
.spec-pick-row .grow { flex: 1; min-width: 0; }
.spec-pick-row.muted .grow { color: var(--muted); }
.spec-edit { margin: 4px 0 14px; }
.spec-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--text); font: inherit; font-size: 13px;
  cursor: pointer; white-space: nowrap;
}
.spec-chip:hover { border-color: var(--accent); background: var(--panel-2); }
.spec-chip.on { background: var(--accent-dim); border-color: var(--accent); font-weight: 600; }
.spec-chip.muted { color: var(--muted); }
.spec-chip-n { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.spec-chip.on .spec-chip-n { color: var(--ink-green); }
.spec-chip-x { color: var(--muted); font-size: 11px; padding: 0 1px; }
.spec-chip-x:hover { color: var(--ink-rose); }
.spec-add { display: inline-flex; align-items: center; gap: 4px; }
.spec-add input { font-size: 13px; padding: 4px 9px; width: 170px; }
.split-detail {
  flex: 1; min-width: 0;
  background: var(--panel); border-radius: 15px; padding: 16px 18px;
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s);
}
.split-detail .section-subhead { margin-top: 18px; }
.split-detail .section-subhead:first-child { margin-top: 0; }

.detail-head { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; margin-bottom: 4px; }
.detail-title { font-family: var(--font-display); font-size: 22px; }
/* Имя фабрики в строке списка: то же, что заголовок досье, но в размер строки. */
.detail-title-sm { font-family: var(--font-display); font-size: 15px; }
/* Название, по которому кликают: кнопка, а не ссылка — переход внутри окна. */
.link-btn {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-family: var(--font-display); font-size: 15px;
  color: var(--accent, inherit); text-align: left;
}
.link-btn:hover { text-decoration: underline; }
/* Базовая фабрика в досье производства — одна строка: подпись и кнопка
   (24.09.2026). Отдельного заголовка над ней больше нет. */
.factory-base { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; }
.factory-base .row-actions { margin-top: 0; align-items: center; }
.factory-base .form-label { margin: 0; }
.detail-rating { display: flex; align-items: baseline; gap: var(--gap); margin-left: auto; }
.detail-rating b { font-family: var(--font-display); font-size: 26px; font-weight: 400; }

.stars-view { letter-spacing: 2px; font-size: 13px; }
.stars-view .on { color: var(--c-d8b26a-t); }
.stars-view .off { color: var(--c-e2dccc-t); }

/* Три плитки в ряд, пока ряд шире 420px, дальше — сколько влезет. Жёсткие три
   колонки в узком окне (минимум приложения — 900px) резали подписи: «прошли
   ОТК сразу» не помещалось в 91 пиксель. */
.fact-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--gap); }
.fact-tile { padding: 13px 14px 12px; border-radius: var(--radius); background: var(--panel-3); color: var(--text-2); }
.fact-tile.ok { background: var(--tile-green-bg); color: var(--ink-green); }
.fact-tile.warn { background: var(--tile-yellow-bg); color: var(--ink-yellow); }
.fact-tile.cool { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.fact-top { display: flex; align-items: baseline; gap: 8px; }
/* Только внутри плитки (20.10.2026): голое `.fact-value` набирало ответы анкеты
   Literata с межстрочным 1 — строки слипались. */
.fact-tile .fact-value { font-family: var(--font-display); font-size: 26px; line-height: 1; }
.fact-name { font-size: 12px; font-weight: 700; }
.fact-note { margin-top: 9px; padding: 5px 9px; border-radius: var(--radius-sm); background: var(--c-rgba-255-255-255-66-s); font-size: 11px; }

/* «Данные» карточки: ровно две плитки в ряд — так и задумано, отсюда и класс.
   В боковой панели они получались по 80 px не из-за этой пары, а из-за того,
   что и само досье стояло в двух колонках; чинится это выше, в `.dossier-grid`.
   Совсем узкий случай разложен в одну колонку в конце файла. */
.stat-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.stat-box { min-width: 0; }
.stat-value.small { font-size: 14px; font-weight: 500; }
/* Две колонки показателей, пока каждая шире 300px. Раньше их было ровно две
   при любой ширине, а `.metric-label` держал `min-width: 200px` — в узком окне
   строка вылезала за колонку, и «Средняя стоимость образцов» обрывалась на
   «обр». Ширина считается по самой панели, а не по окну: в досье слева ещё
   список, и одного брейкпоинта по ширине экрана здесь мало. */
/* `min(300px, 100%)` вместо голых 300px: в панели уже 300 колонка не ужимается
   и вылезает за край на разницу. */
.metric-list.two { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 8px; }
.metric-list.two .metric-label { min-width: 120px; }

/* ── задачи: один список компактных строк ───────────────── */

/* Активные и выполненные разведены по вкладкам (16.09.2026), поэтому колонок
   больше нет: каждой вкладке достаётся вся ширина. Прежняя сетка делила экран
   на 2,2 к 0,8, и текст активных задач обрезался ради колонки, в которую
   заглядывают раз в неделю. */
.task-lane.done { opacity: 1; }
.lane-count {
  margin-left: 8px; font-family: var(--font-display); font-size: 14px;
  letter-spacing: 0; text-transform: none; color: var(--muted);
}
.task-list { display: flex; flex-direction: column; gap: 2px; }
/* Строка без рамки и без карточной тени: список читается по отбивке и по
   наведению, а не по обводке вокруг каждой задачи. Разделяет строки тонкая
   черта, и та — не у первой. */
.task-row {
  display: flex; align-items: flex-start; gap: var(--gap);
  padding: 7px 10px; border-radius: var(--radius-sm); background: transparent;
  border-top: 1px solid var(--line);
}
.task-list > .task-row:first-child { border-top: 0; }
.task-row:hover { background: var(--panel-2); }
/* Текст активной задачи виден ЦЕЛИКОМ. Агенту велено переносить в неё всю
   конкретику дословно — размеры, количества, форматы файлов, — и обрезка по
   двум строкам съедала ровно её: задачу нельзя было выполнить, не наведя мышь
   на строку ради подсказки. */
.task-row .task-text { font-size: 13px; line-height: 1.4; }
.task-row .task-actions {
  flex: 0 0 auto; display: flex; gap: 2px; margin: 0; padding-top: 1px;
  /* Правка и удаление — редкие действия: до наведения они не должны спорить
     за внимание с текстом задачи. */
  opacity: 0; transition: opacity .12s ease;
}
.task-row:hover .task-actions,
.task-row:focus-within .task-actions { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .task-row .task-actions { transition: none; } }
.task-row.task-done .task-text { color: var(--muted); text-decoration: line-through; }

/* Галочка вместо кнопки «Выполнено»: то же действие, но размером с само
   действие. Стоит слева, как в любом списке дел. */
.task-check {
  flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); border-radius: 50%;
  background: transparent; color: transparent;
  font: inherit; font-size: 12px; line-height: 1; cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.task-check:hover { border-color: var(--accent); color: var(--accent); }
.task-check.on {
  border-color: var(--ok); background: var(--ok); color: var(--panel);
}
.task-check.on:hover { background: transparent; color: var(--ok); }
@media (prefers-reduced-motion: reduce) { .task-check { transition: none; } }

/* Строка отметилась — и ушла (27.10.2026, `NadosRows.leave` в ui-kit.js): бледнеет и
   схлопывается на месте, раздел потом подменяется без мигания. */
.row-leave {
  overflow: hidden; pointer-events: none;
  animation: row-leave 260ms ease-in forwards;
}
@keyframes row-leave {
  0% { opacity: 1; max-height: var(--row-h, 120px); }
  40% { opacity: .5; max-height: var(--row-h, 120px); }
  100% {
    opacity: 0; max-height: 0;
    padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; border-width: 0;
  }
}
@media (prefers-reduced-motion: reduce) { .row-leave { animation: none; opacity: 0; } }

/* Подзаголовок группы: производство, приславшее просьбы. */
.task-factory {
  display: flex; align-items: center; gap: 8px; margin: 14px 0 2px;
  font-family: var(--font-display); font-size: 13px; font-weight: 600;
  color: var(--muted);
}
.task-factory:first-of-type { margin-top: 0; }
/* Возраст просьбы решает, чем заняться сейчас, поэтому он и говорит цветом:
   сегодняшняя и вчерашняя — спокойные, неделя — тёплая, дальше — тревожная.
   Прежняя плашка была жёлтой всегда, и «сегодня» выглядело так же срочно, как
   «месяц назад». Цвет текста на плашке — тёмный: серый по жёлтому на кегле
   11,5 не читался. */
.task-age {
  flex: 0 0 auto; font-size: 12px; color: var(--muted); white-space: nowrap;
  background: transparent; border-radius: 4px; padding: 0 2px;
}
/* У выполненной задачи в плашке две даты (Q90). Она стоит в общей строке
   пометок и переносится по словам, а не держит справа колонку под самую
   длинную из дат. */
.task-row.task-done .task-age { white-space: normal; }
.task-age.age-warm { background: var(--warn); color: var(--ink-yellow); }
.task-age.age-hot { background: var(--danger); color: var(--ink-rose); }
.task-delete, .task-edit {
  width: auto; padding: 2px 6px; border: none; background: transparent;
  cursor: pointer; font-size: 13px; line-height: 1; opacity: .45;
  display: inline-flex; align-items: center; color: var(--text-2);
}
.task-delete:hover, .task-edit:hover { opacity: 1; }
/* Правка формулировки на месте: строка списка становится полем ввода. */
.task-edit-field {
  flex: 1; min-width: 0; font: inherit; font-size: 13px;
  padding: 2px 6px; border: 1px solid var(--accent); border-radius: 6px;
  background: var(--panel);
}
/* Основание задачи — сообщение фабрики. Свёрнуто по умолчанию: строка списка
   должна оставаться строкой, а не карточкой переписки. */
.task-row .task-source { font-size: 12px; }
.task-row .task-source summary { color: var(--muted); }
.task-row .task-source-text, .task-row .task-source-ru { font-size: 12px; line-height: 1.35; }
.task-chat { font-size: 12px; color: var(--muted); }

/* Связанная сущность — ВНУТРЕННЯЯ ссылка, а не кнопка «Открыть…».
 *
 * Номер посылки, номер заказа, имя артикула и имя фабрики уже стоят в тексте
 * задачи; отдельная кнопка рядом называла то же самое второй раз. Теперь
 * кликается сам номер. Выглядит как ссылка, а не как кнопка: рамки вокруг
 * каждого номера в списке из тридцати задач — это тридцать рамок.
 *
 * `ent-chip` — тот же вид для сущности, которой в тексте не нашлось: связь
 * есть, и потерять её нельзя, но и выдавать её за часть формулировки незачем. */
.ent-link {
  border: 0; background: transparent; color: var(--ink-green);
  padding: 0; font: inherit; cursor: pointer;
  border-bottom: 1px dashed var(--accent); border-radius: 0;
}
.ent-link:hover { color: var(--accent); border-bottom-style: solid; }
.ent-chip {
  font-size: 12px; border-bottom: 0;
  background: var(--panel-2); border-radius: 4px; padding: 1px 6px;
}
.ent-chip:hover { border-bottom: 0; background: var(--accent-dim); }
/* Бренд показывается только во «Всех брендах» — там задачи двух компаний
   стоят вперемешку. */
.task-brand {
  font-size: 11px; color: var(--muted); border: 1px solid var(--line);
  border-radius: 4px; padding: 1px 6px;
}
/* Задачу закрыл агент, а не человек: видно это без разворачивания основания. */
.task-closer {
  font-size: 11px; color: var(--ink-green); background: var(--accent-dim);
  border-radius: 4px; padding: 1px 6px;
}
.task-answer-head { margin-top: 6px; font-size: 11px; color: var(--muted); }

/* ── ПОРУЧЕНИЯ АССИСТЕНТАМ (10.10.2026) ─────────────────────────────────────
   Владелица передаёт задачу или запись календаря ассистенту. Над доской задач
   — «Поручено вам» (открыт всегда: это список дел ассистента) и «Передано»
   (свёрнут: у кого сколько — прямо в заголовке). Буква в кружке — та же, что
   у человека в «Доступе». */
.task-assign-blocks { display: grid; gap: 8px; margin: 0 0 10px; }
.task-assigned {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 8px 10px;
}
.task-assigned.mine { border-color: var(--accent); }
.task-assigned-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px;
  font-family: var(--font-display); font-size: 13px; color: var(--text);
}
.task-assigned-head .lane-count { margin-left: 0; }
.task-assigned.mine .task-assigned-head,
.task-assigned.given[open] .task-assigned-head { margin-bottom: 4px; }
summary.task-assigned-head { cursor: pointer; list-style: none; }
summary.task-assigned-head::-webkit-details-marker { display: none; }
summary.task-assigned-head::before { content: '▸'; color: var(--muted); font-size: 11px; }
.task-assigned.given[open] summary.task-assigned-head::before { content: '▾'; }
.task-assigned-who { display: inline-flex; align-items: center; gap: 4px; font-weight: 400; }
.assign-avatar {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  display: inline-grid; place-items: center;
  font-size: 11px; font-weight: 700; line-height: 1; font-family: inherit;
  background: var(--accent-dim); color: var(--ink-green);
}
/* У кого задача — плашкой в строке; у владелицы она же кнопка. */
.task-assignee {
  display: inline-flex; align-items: center; gap: 4px;
  border: 0; border-radius: 999px; padding: 1px 8px 1px 2px;
  font: inherit; font-size: 12px; line-height: 18px;
  background: var(--accent-dim); color: var(--ink-green);
}
button.task-assignee { cursor: pointer; }
button.task-assignee:hover { background: var(--accent); }
.task-assign { white-space: nowrap; }
/* Меню «Кому передать»: живёт в `body`, как меню снимка, и стоит выше панелей. */
.assign-menu {
  position: fixed; z-index: 95; min-width: 240px; max-width: 320px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 14px 36px var(--shadow-soft);
}
/* 15.10.2026: сверху — что передаём одной строкой, ниже — люди крупно. */
.assign-menu-head {
  display: flex; flex-direction: column; gap: 2px; padding: 6px 10px 8px;
  border-bottom: 1px solid var(--line); margin-bottom: 2px;
  font-size: 13px; color: var(--text);
}
.assign-menu-what {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assign-menu-item {
  display: flex; align-items: center; gap: var(--gap);
  border: none; background: transparent; color: var(--text);
  font: inherit; font-size: 13px; text-align: left;
  padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer;
}
.assign-menu-item .assign-avatar { width: 30px; height: 30px; font-size: 13px; }
.assign-menu-text { display: flex; flex-direction: column; min-width: 0; }
.assign-menu-name { font-weight: 600; }
.assign-menu-sub { font-size: 12px; color: var(--muted); }
.assign-menu-item:hover, .assign-menu-item:focus-visible { background: var(--panel-2); outline: none; }
.assign-menu-item.on { background: var(--accent-dim); cursor: default; }
.assign-menu-mark { margin-left: auto; color: var(--ink-green); font-weight: 700; }
.assign-menu-item.back { border-top: 1px solid var(--line); margin-top: 2px; border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
.assign-menu-item.back .assign-avatar { background: var(--panel-3); color: var(--text-2); }
/* «Передать» / «Обоим» у приоритета и повторяющейся задачи (15.10.2026): человек —
   строкой, две кнопки справа. */
.tw-share-menu { min-width: 280px; max-width: 360px; }
.tw-share-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: var(--radius-sm); }
.tw-share-row:hover { background: var(--panel-2); }
.tw-share-row .assign-avatar { width: 30px; height: 30px; font-size: 13px; flex: none; }
.tw-share-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.tw-share-row .btn { flex: none; }
/* «Кому» кнопками (15.10.2026): «Мне» и ассистенты с буквой в кружке. */
.assign-pick { display: flex; flex-wrap: wrap; gap: 6px; }
/* С 12.11.2026 — только кружки: буква, цвет человека, имя при наведении; выбранный —
   в кольце с галочкой, остальные приглушены. */
.assign-pick { gap: 10px; align-items: center; }
.assign-pick-btn {
  position: relative; display: inline-grid; place-items: center;
  width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; font: inherit; cursor: pointer;
  opacity: .5; transition: opacity .12s, transform .12s, box-shadow .12s;
}
.assign-pick-btn .assign-avatar { width: 32px; height: 32px; font-size: 14px; }
.assign-pick-btn:hover { opacity: 1; transform: scale(1.06); }
.assign-pick-btn.on { opacity: 1; box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink-green); }
.assign-pick-btn.on::after {
  content: '✓'; position: absolute; right: -4px; bottom: -4px;
  width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center;
  font-size: 10px; font-weight: 800; line-height: 1;
  background: var(--ink-green); color: var(--paper); box-shadow: 0 0 0 2px var(--paper);
}
.assign-pick-btn.vac::before {
  content: '☀'; position: absolute; left: -4px; top: -5px; font-size: 13px; line-height: 1;
}
.assign-pick-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 3px; }
/* Цвет человека — по номеру (`taskAssignColor`); «Я» — цвет CRM. */
.assign-avatar[data-c="1"] { background: var(--person-1); color: var(--person-ink); }
.assign-avatar[data-c="2"] { background: var(--person-2); color: var(--person-ink); }
.assign-avatar[data-c="3"] { background: var(--person-3); color: var(--person-ink); }
.assign-avatar[data-c="4"] { background: var(--person-4); color: var(--person-ink); }
.assign-avatar[data-c="5"] { background: var(--person-5); color: var(--person-ink); }
.assign-avatar[data-c="6"] { background: var(--person-6); color: var(--person-ink); }
.assign-avatar[data-c="me"] { background: var(--accent); color: var(--on-accent-strong); }
.assign-menu-item.back .assign-avatar[data-c] { background: var(--panel-3); color: var(--text-2); }
/* Имя над кружком при наведении (`personTip`). */
.person-tip {
  position: fixed; z-index: 2000; pointer-events: none;
  display: flex; flex-direction: column; gap: 1px; padding: 5px 10px;
  border-radius: var(--radius-sm); background: var(--text); color: var(--paper);
  font-size: 12.5px; line-height: 1.3; white-space: nowrap;
  box-shadow: 0 6px 18px var(--shadow-soft);
}
.person-tip span { font-size: 11.5px; opacity: .8; }
/* Значок «Передать» у задачи плана — при наведении (на планшете виден всегда). */
.tw-item { position: relative; }
.tw-give {
  position: absolute; top: 3px; right: 3px; width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center; border: 1px solid var(--line); border-radius: 50%;
  background: var(--paper); color: var(--text-2); cursor: pointer;
  opacity: 0; transition: opacity .12s;
}
.tw-item:hover .tw-give, .tw-give:focus-visible { opacity: 1; }
.tw-give:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent-strong); }
@media (hover: none) { .tw-give { opacity: 1; } }
/* Панель записи календаря: кому передана — сразу под сроком. */
.cal-assign { display: flex; align-items: center; gap: 8px; margin: 2px 0 10px; font-size: 13px; }
.yc-chip .assign-avatar, .cal-day-entry .assign-avatar { width: 16px; height: 16px; font-size: 10px; }

/* Плашка вида контрагента. */
.chip-kind { background: var(--panel-3); color: var(--text-3); }

/* ── строка с галочкой («Мой склад» в окне бренда) ──────── */

.pick-row {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 8px 10px; background: var(--panel);
}

/* ── контрагенты ────────────────────────────────────────── */

/* Раздел разложен вкладками по типу; групп с заголовками (`.party-group`) в
   нём больше нет, вместе с ними ушли и их правила. */

/* Адрес человек пишет строками: предупреждение, сам адрес, телефон. Схлопнутые
   в одну строку, они читаются как каша — и в панели, и в заметке. */
.hint.pre { white-space: pre-line; }

/* Библиотека контрагентов: слева имя, справа плашки брендов. Список длинный —
   прокручивается сам, а заголовки типов липнут к верху, как в выборе фабрик. */
.library-list { gap: 0; max-height: min(56vh, 460px); overflow-y: auto; }
.library-row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; border-bottom: 1px solid var(--line);
}
.library-row:last-child { border-bottom: 0; }
.library-row .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.library-row .nm { font-size: 13px; }
.library-row .muted { font-size: 11px; }
.library-row .chip-row { flex-wrap: nowrap; }

/* Плашка-переключатель: погашенная — бренд не отмечен, зажжённая — отмечен.
   Цвет тот же, что у «по умолчанию»: в разделе это одна и та же мысль — «да». */
button.chip-toggle {
  font: inherit; font-size: 11px; cursor: pointer;
  opacity: .5; white-space: nowrap;
}
button.chip-toggle:hover { opacity: .8; }
button.chip-toggle.on {
  opacity: 1; background: var(--accent-dim); color: var(--ink-green);
}
.party-brands { color: var(--muted); }

/* ── товары: полоса закупочной цены ─────────────────────── */

.product-top { display: flex; gap: 12px; align-items: flex-start; }
.product-top .photo-strip { flex: 0 0 84px; }
.product-title { min-width: 0; flex: 1; }
.price-bars { display: flex; flex-direction: column; gap: 4px; margin-top: 12px; }
.price-row { display: flex; align-items: center; gap: var(--gap); font-size: 12px; }
.price-name { width: 108px; flex: 0 0 auto; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.price-track { flex: 1; height: 6px; border-radius: 3px; background: var(--c-f1ece0-s); overflow: hidden; }
.price-track i { display: block; height: 100%; border-radius: 3px; background: var(--c-a9cdb8-s); }
.price-value { width: 74px; text-align: right; font-weight: 600; }

/* ── закрытые заказы: итоги и таблица ───────────────────── */

/* Сводка «Завершено» — плитки «Аналитики» (20.10.2026): раскладка и вид —
   `.analytics-tiles`/`.analytics-tile`. Плитка здесь ничего не открывает: без
   руки-курсора и без «подскока» при наведении; «ⓘ» — в углу, как у `.stat-box`. */
.analytics-tiles.closed-tiles { margin-bottom: 12px; }
.closed-tiles > .analytics-tile { position: relative; cursor: default; padding-right: 26px; }
.closed-tiles > .analytics-tile:hover:not(:disabled) { border-color: var(--line); transform: none; }
.closed-tiles > .analytics-tile > .info-dot { position: absolute; top: 8px; right: 8px; margin: 0; }
/* Скругление углов раньше держалось на `overflow: hidden`, но оно же делает
   таблицу собственным контейнером прокрутки — и липкая шапка внутри неё липнуть
   перестаёт. Углы скругляем самим ячейкам, а шапка липнет к верху раздела. */
.closed-table { background: var(--panel); border-radius: var(--radius); }
.closed-table thead th:first-child { border-top-left-radius: 13px; }
.closed-table thead th:last-child { border-top-right-radius: 13px; }
.closed-table tbody tr:last-child td:first-child { border-bottom-left-radius: 13px; }
.closed-table tbody tr:last-child td:last-child { border-bottom-right-radius: 13px; }
.closed-table th {
  background: var(--panel-5); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 2; padding: 0;
}
/* Заголовок — кнопка сортировки во всю ячейку: попадать в мелкую надпись мышью
   неудобно, а колонок восемь. */
.closed-table th .sort-th {
  display: flex; align-items: center; gap: 4px; width: 100%;
  padding: 7px 10px; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit; text-align: left; letter-spacing: inherit;
  text-transform: inherit;
}
.closed-table th .sort-th:hover { color: var(--text); background: var(--c-f6f2e6-s); }
.closed-table th .sort-th.active { color: var(--ink); }
.closed-table th .sort-mark { font-size: 10px; opacity: .75; }
.closed-table td { border-bottom: 1px solid var(--c-f4efe3-l); cursor: pointer; }
.closed-table tr:last-child td { border-bottom: none; }
.closed-table tbody tr:hover td { background: var(--c-fdfbf5-s); }
.closed-table td.code { font-family: var(--font-display); font-size: 14px; }
.closed-more { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* ── ревью: очередь и разбираемый случай ────────────────── */

.review-row { flex-direction: column; align-items: stretch; gap: 6px; }
.review-row-top { display: flex; align-items: baseline; gap: 8px; }
.review-row-top .muted { margin-left: auto; font-size: 11px; }
.review-row-q { font-size: 12px; }
/* Длинный вопрос в списке — две строки, целиком он в карточке справа (22.10.2026). */
.review-row-q { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Номер заказа и номер вопроса — вместе справа, а не номер заказа посередине. */
.review-row-top .muted + .muted { margin-left: 0; }
.split-detail .review { border: none; background: transparent; padding: 0; }
.review-when { margin-left: auto; font-size: 11px; }
.split-detail .review-question { font-family: var(--font-display); font-size: 17px; margin: 12px 0 0; }
.split-detail .review-context { margin-top: 6px; }
.split-detail .msg { margin-top: 12px; }
.split-detail .review-actions { margin-top: 14px; }

/* ── карточка раздела как боковая панель ────────────────── */

.entity-top { display: flex; align-items: baseline; gap: var(--gap); }
#entity-modal.as-drawer { display: block; }
#entity-modal.as-drawer .modal-bg { display: none; }
/* Панель не запирает раздел: контейнер прозрачен для кликов, ловит их только
   сама панель — можно открывать соседние карточки и жать кнопки, не закрывая её. */
#entity-modal.as-drawer { pointer-events: none; }
#entity-modal.as-drawer .modal-panel { pointer-events: auto; }
#entity-modal.as-drawer .modal-panel {
  position: fixed; top: 0; right: 0; bottom: 0;
  /* 404 px — рабочая ширина панели, но не на узком окне: там она закрывала
     собой раздел целиком, а вернуться к списку можно только мимо неё. */
  width: min(404px, calc(100vw - 40px)); max-height: none;
  border: none; border-left: 1px solid var(--line); border-radius: 0;
  box-shadow: -10px 0 26px var(--c-rgba-90-74-55-08-s);
}
#entity-modal.as-drawer .modal-head { background: var(--c-fdf9ee-s); border-bottom: 1px solid var(--line-4); }
/* «Перейти в раздел» под названием панели (18.10.2026): ссылка открывает
   карточку панелью, а в раздел ведёт эта кнопка. */
.modal-head .entity-go { margin-top: 10px; }
#entity-modal.as-drawer .modal-code { font-family: var(--font-display); font-size: 22px; }
#entity-modal.as-drawer .photo-strip { margin: 4px 0 12px; }
/* Тело панели — гибкий элемент в колонке, и без `min-width: 0` его нельзя
   сжать: широкая таблица внутри растягивала панель за край экрана. */
#entity-modal.as-drawer .modal-body { min-width: 0; overflow-x: hidden; }

/* Досье внутри панели — без второй рамки; правила стоят в конце файла, после
   запросов к контейнеру: те тоже правят отступ досье и при равном весе
   перебивали бы обнуление. */

/* ── разработки: лента в две колонки ────────────────────── */

.dev-feed { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
.dev-card {
  border: none; border-radius: var(--radius); gap: 12px;
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s);
}
.dev-card.colored { border-left: 4px solid var(--tab-color); }
.dev-head { border-bottom: 1px solid var(--c-f2ecdd-l); }
.dev-name { font-family: var(--font-display); font-size: 17px; }
.dev-progress.complete .dev-progress-ring { background: conic-gradient(var(--accent) 100%, var(--accent) 0); }
.dev-progress.complete .dev-progress-ring span { background: var(--accent-dim); }
@media (max-width: 1180px) {
  .dev-feed { grid-template-columns: minmax(0, 1fr); }
}

/* ── «Завершено»: выбор производства наверху ────────────── */
/* Сама шапка объявлена выше, рядом с .history-body: там она стоит до
   @media (max-width: 760px), который складывает её в колонку. */
.history-picker { flex: 0 0 auto; max-width: 260px; }
/* В обзоре выбор — единственный ребёнок шапки; без прижима вправо он прыгал
   бы по горизонтали при переходе обзор ↔ производство. */
.history-toolbar > .history-picker:only-child { margin-left: auto; }
.closed-more { padding: 10px 0 0; font-size: 13px; }

/* ── окно статистики производства ───────────────────────── */
.stat-scope {
  display: flex; flex-wrap: wrap; gap: var(--gap); align-items: baseline;
  margin: 4px 0 10px; font-size: 13px;
}

/* ── образцы: полосы статусов ───────────────────────────── */

/* ── образец с подходящим сроком ──────────────────────────
   Образцы живут в «Продуктах», строкой внутри карточки товара: полоска слева
   говорит, что срок на исходе (жёлтая) или уже прошёл (красная). У ведущего
   образца своя полоска цветом акцента — срок её перебивает, он важнее. */
.card-sample.sample-due { box-shadow: inset 3px 0 0 var(--c-d9b96a-s); }
.card-sample.sample-overdue { box-shadow: inset 3px 0 0 var(--c-b8515d-s); }
.card-sample.leading.sample-due, .card-sample.leading.sample-overdue { border-left-color: transparent; }

/* ── завершённые: ошибки проверки ───────────────────────── */
.closed-table td.center { text-align: center; }
.defect-chip { width: auto; cursor: pointer; border: none; font: inherit; }
.defect-list { margin: 8px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.defect-list li { font-size: 13px; }

/* ── решение по ОТК прямо на карточке доски ─────────────── */
.card-decide { display: flex; gap: 6px; margin-top: 8px; }
.card-decide-btn {
  flex: 1; width: auto; padding: 5px 8px; border-radius: var(--radius-sm); cursor: pointer;
  font-size: 12px; line-height: 1.2; border: 1px solid var(--line);
  background: var(--panel); color: var(--text);
}
.card-decide-btn.passed:hover { border-color: var(--c-4a7c59-l); background: var(--tile-green-bg-2); color: var(--c-3f6b4c-t); }
.card-decide-btn.failed:hover { border-color: var(--c-a94550-l); background: var(--c-f9ecee-s); color: var(--c-8e3a44-t); }
/* «Отправить на ОТК» у заказа в производстве (20.10.2026). */
.card-decide-btn.send:hover { border-color: var(--accent); background: var(--accent-dim); color: var(--accent-ink); }
.qc-decision-label {
  display: block; margin-bottom: 4px; font-size: 12px; color: var(--muted);
}
#qc-decision-defects { width: 100%; margin-bottom: 10px; }
#qc-decision .script-preview { max-height: 260px; overflow-y: auto; }

/* Выбор исхода: скрипт ОТК всегда про один заказ и одно решение. */
.qc-choice { display: flex; flex-direction: column; gap: 4px; }
.qc-choice .btn-lg { margin-top: 6px; }

/* Номер заказа виден до того, как текст уйдёт в WeChat: скрипт именной. */
.script-order-line {
  margin: 0 0 8px; padding: 6px 10px; border-radius: var(--radius-sm);
  background: var(--c-fdf3d8-s); border: 1px solid var(--c-e6d3a3-l);
  font-size: 13px; font-weight: 600; color: var(--c-6d5620-t);
}
.script-order-line:empty { display: none; }
.btn-lg {
  width: 100%; margin-top: 10px; padding: 11px 16px;
  font-size: 14px; font-weight: 600; border-radius: var(--radius-sm);
}
.btn-danger-solid {
  border: 1px solid var(--c-c96a74-l); background: var(--c-b8515d-s); color: var(--on-accent);
}
.btn-danger-solid:hover { background: var(--c-a5454f-s); }

/* ── «Заказы»: переключатель режимов и доска образцов ──────────────────────
   На месте прежней плашки «N образцов в разработке» стоит переключатель
   «Заказы | Образцы» (17.09.2026). Он узкий и тихий: это не заголовок раздела,
   а выбор того, какую из двух досок показывать. */
.orders-mode { padding: 9px 20px 0; flex: 0 0 auto; }
.mode-switch {
  display: inline-flex; gap: 2px; padding: 2px;
  border-radius: 999px; background: var(--c-f4f1e8-s);
}
.mode-btn {
  border: none; background: transparent; color: var(--muted);
  padding: 5px 16px; border-radius: 999px; font: inherit; font-size: 13px;
  cursor: pointer; white-space: nowrap;
}
.mode-btn:hover { color: var(--text); }
.mode-btn.on {
  background: var(--paper); color: var(--text); font-weight: 650;
  box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s);
}
.mode-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.mode-btn:disabled { opacity: .4; cursor: default; }
.mode-btn:disabled:hover { color: inherit; }

/* Доска образцов собрана теми же колонками, что и доска заказов (`.col`,
   `.fun-tile`, `.card`), — своей вёрстки у неё нет. Отличаются только цвета
   этапов: статусы у образца свои. */
.col[data-sample-status="sample"] { background: var(--tile-cream-bg); }
.col[data-sample-status="fitting"] { background: var(--tile-violet-bg-2); }
.col[data-sample-status="sample_ok"] { background: var(--tile-green-bg-2); }
.col[data-sample-status="rejected"] { background: var(--c-fdf3f4-s); }
.col[data-sample-status="done"] { background: var(--c-f7f5ef-s); }
.col[data-sample-status="archive"] { background: var(--panel-2); }
.fun-tile[data-sample-status="sample"] { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fun-tile[data-sample-status="fitting"] { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.fun-tile[data-sample-status="sample_ok"] { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.fun-tile[data-sample-status="rejected"] { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.fun-tile[data-sample-status="done"] { background: var(--panel-3); color: var(--text-2); }
.fun-tile[data-sample-status="archive"] { background: var(--panel-3); color: var(--text-2); }

/* Карточку образца перетаскивают между колонками — так же, как карточку
   заказа (17.09.2026): этап образца меняют прямо на доске, и второго приёма
   для этого на ней быть не должно. Курсор о том и говорит. */
.sample-card { cursor: grab; }
.sample-card.dragging { cursor: grabbing; }
.sample-card-name { margin-top: 3px; overflow-wrap: anywhere; }
/* Драфты — одна карточка (20.10.2026): «был О-082» рядом с новым номером. */
.sample-card-prev { font-size: 11px; font-weight: 400; }
.sample-prev-codes { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sample-card-factory {
  margin-top: 3px; font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sample-card.late { border-color: var(--tile-rose-line); }
.sample-card-late {
  display: inline-block; margin-top: 6px;
  padding: 2px 7px; border-radius: 6px; font-size: 11px; font-weight: 600;
  color: var(--tile-rose-text); background: var(--tile-rose-bg);
  border: 1px solid var(--tile-rose-line);
}
/* Причина отказа и список недописанного — в одну строку с многоточием: на
   карточке они напоминают, а читают их в самой карточке образца. */
.sample-card-why, .sample-card-gap {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sample-card-gap { margin-top: 5px; font-size: 11px; color: var(--c-a08b6f-t); }

/* Новый товар прямо в окне «Новые образцы»: артикул называют здесь, и он
   сразу появляется в «Продуктах» с этим названием. */
.nsm-new { margin-top: 12px; }
.nsm-new .row-inline { display: flex; gap: 8px; align-items: center; }
.nsm-new .row-inline input { flex: 1 1 auto; min-width: 0; }
.nsm-new-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.nsm-new-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px; border-radius: 999px; font-size: 12px;
  background: var(--c-eef3ec-s); color: var(--tile-green-text); border: 1px solid var(--c-dbe6d9-l);
}
.nsm-new-drop {
  border: 0; background: none; cursor: pointer; color: inherit;
  font-size: 14px; line-height: 1; padding: 0;
}

/* Готовый вопрос фабрике в карточке «Ревью»: текст правится на месте. */
.review-script { margin-top: 10px; }
.review-script > summary { cursor: pointer; font-size: 12px; color: var(--muted); }
.review-script-text {
  width: 100%; margin-top: 8px; font: inherit; font-size: 13px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); color: var(--text); resize: vertical;
}

/* Совет по устранимому простою: не тревога, а подсказка — поэтому спокойнее
   красной плашки «стоит» и стоит сразу под ней. */
.card-reason.advice {
  background: var(--tile-yellow-bg); color: var(--tile-yellow-text); border-color: var(--tile-yellow-line);
}
.card-reason.advice .card-reason-label { color: var(--tile-yellow-text); }

/* Цена в «Данных» карточки правится на месте: поле должно выглядеть как
   значение, а не как форма посреди плиток. */
.stat-box .form-field { margin: 0; gap: 0; }
.stat-box .form-label { display: none; }
.stat-input {
  width: 100%; border: 1px solid transparent; background: transparent;
  padding: 2px 4px; margin-left: -4px; border-radius: 6px;
  font: inherit; font-size: 15px; color: var(--text);
}
.stat-input:hover { border-color: var(--line); }
.stat-input:focus { border-color: var(--accent); background: var(--panel-raw); }

/* У разработки производств несколько, и цена у каждого своя: строка на
   производство, имя слева, его цена справа. Одним полем на всех показать это
   нельзя — оно врёт про то, чья цена (ревизия 15.09.2026). */
.price-by-factory {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding-top: 4px;
}
.price-by-factory + .price-by-factory { border-top: 1px solid var(--line); }
.price-by-factory-name { flex: 1 1 96px; min-width: 0; font-size: 13px; color: var(--muted); }
.price-by-factory .form-field { flex: 0 1 90px; min-width: 64px; }
.price-by-factory .stat-input { text-align: right; }

/* «Запросить цену» (06.10.2026): у пустой закупочной цены — жёлтая кнопка с
   «!». Цены нет — это видно с первого взгляда, и просят её здесь же. В плитке
   кнопка встаёт под подписью, на её запасную вторую строку, — плитка не растёт. */
.stat-label.price-ask-label { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.btn.price-ask-btn {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--warn); border-color: var(--warn); color: var(--warn-ink); font-weight: 600;
}
.btn.price-ask-btn:hover { background: var(--warn); border-color: var(--warn-ink); }
/* В строке образца без цены: номер с фабрикой — строкой, под ним поле цены и
   кнопка рядом. Иначе в узкой колонке кнопка уезжала третьей строкой. */
.price-by-factory.has-ask .price-by-factory-name { flex-basis: 100%; }
.price-by-factory.has-ask .form-field { flex: 1 1 40px; min-width: 40px; }
.price-by-factory.has-ask .price-ask-btn { flex: none; }
.price-ask-mark {
  display: inline-grid; place-items: center; flex: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--warn-ink); color: var(--warn);
  font-size: 10px; font-weight: 800; line-height: 1;
}
/* Окно: напоминание её словами и фото карточки — нажатие копирует снимок. */
.price-ask-photo {
  margin-top: 12px; padding: 10px 12px; border-radius: var(--radius);
  background: var(--tile-yellow-bg); border: 1px solid var(--tile-yellow-line); color: var(--tile-yellow-text);
}
.price-ask-photo-text { font-weight: 650; }
.price-ask-photos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.price-ask-photo-tile {
  position: relative; width: 64px; height: 64px; padding: 0; overflow: hidden; cursor: pointer;
  border: 1px solid var(--tile-yellow-line); border-radius: var(--radius-sm); background: var(--panel-raw);
}
.price-ask-photo-tile:hover, .price-ask-photo-tile:focus-visible { border-color: var(--warn-ink); }
.price-ask-photo-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
.price-ask-photo-copy {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 0;
  font-size: 10px; text-align: center;
  background: var(--c-rgba-20-12-16-82-s); color: var(--on-accent);
  opacity: 0; transition: opacity .12s;
}
.price-ask-photo-tile:hover .price-ask-photo-copy,
.price-ask-photo-tile:focus-visible .price-ask-photo-copy { opacity: 1; }
/* Письмо о цене со всеми образцами фабрики (12.11.2026): номер под фото и «когда спрашивали». */
.price-ask-photo-item { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.price-ask-photo-code { font-size: 11px; font-weight: 650; }
.price-ask-asked { list-style: none; margin: 8px 0 0; padding: 0; font-size: 13px; color: var(--muted); }
.price-ask-asked li { padding: 2px 0; }
.price-ask-asked li.is-asked span { color: var(--warn-ink); }
.price-ask-asked-inline { font-weight: 400; color: var(--warn-ink); }
/* То же окно из задачи «Уточнить закупочную цену» (14.10.2026): сверху плитки
   образцов задачи — выбранная обведена, скопированная с галочкой. */
.price-ask-samples { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
/* «Поручить» в окне «Запросите цену» (28.10.2026) — люди кнопками под вопросом. */
.price-notice-assign { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.price-ask-sample {
  position: relative; display: flex; align-items: center; gap: 8px;
  min-width: 0; max-width: 100%; padding: 6px 10px 6px 6px; cursor: pointer; text-align: left;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); color: var(--text);
}
.price-ask-sample:hover, .price-ask-sample:focus-visible { border-color: var(--accent); }
.price-ask-sample.is-active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); background: var(--accent-dim); }
.price-ask-sample-photo {
  flex: none; width: 40px; height: 40px; overflow: hidden; border-radius: 6px; background: var(--panel-2);
}
.price-ask-sample-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.price-ask-sample-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.price-ask-sample-text span { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.price-ask-sample-done {
  display: none; place-items: center; flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--accent); background: var(--accent-dim); color: var(--ink-green);
  font-size: 11px; font-weight: 800;
}
.price-ask-sample.is-done .price-ask-sample-done { display: inline-grid; }

/* ── разговор с Гермесом ──────────────────────────────────────────────────
   Свёрнутая панель поверх доски, а не раздел: спрашивают про то, что на
   экране, и экран должен остаться виден. Поэтому панель узкая и прижата к
   правому краю, а доска под ней не сдвигается. */
/* Только круг с иконкой: подпись «Спросить Гермеса» жила на экране постоянно,
   хотя значение кнопки читается по самой иконке. Текст остался подсказкой при
   наведении и меткой для программ чтения с экрана. */
.chat-toggle {
  position: fixed; right: 18px; bottom: 18px; z-index: 55;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--card, var(--panel-raw)); color: var(--text);
  box-shadow: 0 6px 20px var(--c-rgba-40-34-28-14-s);
  font: inherit;
}
.chat-toggle svg { flex: 0 0 auto; }
.chat-toggle:hover { border-color: var(--accent); color: var(--ink-green); }
/* Пока разговор открыт, круглая кнопка прячется: она оказывается ровно под
   панелью. Свернуть можно крестиком в шапке разговора и ⌘/. */
.chat-toggle.under-chat { display: none; }
/* Индикатор непрочитанных ошибок-оснований у кнопки чата. Цвета — токенами. */
.chat-toggle-badge {
  position: absolute; top: -3px; right: -3px;
  min-width: 18px; height: 18px; padding: 0 4px;
  display: grid; place-items: center;
  background: var(--warn); color: var(--ink);
  border: 1px solid var(--card, var(--panel-raw));
  border-radius: var(--radius-sm); font-size: 11px; font-weight: 700; line-height: 1;
}

.chat-panel {
  position: fixed; right: 0; top: 0; bottom: 0; z-index: 56;
  width: 400px; max-width: 92vw;
  display: flex; flex-direction: column;
  background: var(--card, var(--panel-raw)); border-left: 1px solid var(--line);
  box-shadow: -10px 0 30px var(--c-rgba-40-34-28-10-s);
}
.chat-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--gap);
  padding: 14px 14px 10px; border-bottom: 1px solid var(--line);
}
.chat-title { font-family: var(--font-display); font-size: 17px; }


.chat-log {
  flex: 1 1 auto; overflow-y: auto; padding: 14px;
  display: flex; flex-direction: column; gap: var(--gap);
}
.chat-empty { color: var(--muted); font-size: 13px; line-height: 1.5; }
.chat-msg {
  max-width: 92%; padding: 9px 12px; border-radius: var(--radius);
  font-size: 13px; line-height: 1.5;
}
/* Реплика человека прижата вправо, ответ — влево: у разговора должно быть
   видно, кто говорит, без подписей у каждой строки. */
.chat-user {
  align-self: flex-end; background: var(--accent); color: var(--on-accent-strong);
  border-bottom-right-radius: 4px;
}
.chat-agent {
  align-self: flex-start; background: var(--bg); border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
}
.chat-error {
  align-self: flex-start; background: var(--tile-rose-bg); border: 1px solid var(--tile-rose-line); color: var(--tile-rose-text);
}
.chat-msg-text { white-space: pre-wrap; word-break: break-word; }
.chat-msg-at { font-size: 10px; opacity: .6; margin-top: 4px; }
.chat-user .chat-msg-at { text-align: right; }
.chat-thinking { opacity: .7; font-style: italic; }
/* Ответ «Ревью» в очереди к Гермесу (06.10.2026): её реплика, но ещё не
   ушедшая — пунктир вместо заливки. Ушёл — становится обычной репликой. */
.chat-user.chat-queued {
  background: transparent; color: var(--text);
  border: 1px dashed var(--accent);
}
.chat-queued .chat-msg-at { opacity: .8; }

/* Ход работы: что Гермес думал, какие инструменты позвал и что из этого
   вышло. Свёрнут — при беглом чтении нужен ответ, а подробности когда что-то
   пошло не так. */
.chat-turn { display: flex; flex-direction: column; gap: 8px; }
.chat-work { align-self: stretch; }
.chat-work-head {
  cursor: pointer; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.chat-work-body {
  margin-top: 6px; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--bg); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 4px;
}
.chat-step {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 12px; color: var(--muted); min-width: 0;
}
.chat-step-thought { font-style: italic; }
.chat-step-mark { flex: 0 0 auto; width: 12px; text-align: center; }
.chat-step-text { color: var(--text); }
.chat-step-arg {
  color: var(--muted); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; min-width: 0;
}
/* Вызов, который изменил данные CRM, виден среди прочих: по нему человек
   понимает, что доска под панелью уже другая. */
.chat-step-tool.crm .chat-step-text { color: var(--ink-green); font-weight: 600; }
.chat-system { opacity: .75; font-style: italic; }

/* Вопрос о разрешении. Не в свёртке: на него надо ответить, и прятать его
   значило бы прятать остановку. */
.chat-permission {
  align-self: stretch; padding: 10px 12px; border-radius: var(--radius);
  background: var(--tile-yellow-bg); border: 1px solid var(--tile-yellow-line); color: var(--tile-yellow-text);
  font-size: 13px; line-height: 1.5;
}
.chat-permission.ask { border-color: var(--tile-yellow-line-2); }
.chat-permission-head { font-weight: 600; margin-bottom: 4px; }
.chat-permission-what { word-break: break-word; }
.chat-permission-arg {
  margin-top: 4px; font-family: var(--mono); font-size: 11px; opacity: .8; word-break: break-all;
}
.chat-permission-done { margin-top: 6px; font-size: 12px; opacity: .8; }
.chat-permission .row-actions { margin-top: 8px; flex-wrap: wrap; }

/* Вопрос «код не распознал это как задачу — правильно ли я понял?».
   Ширина во всю ленту, как у вопроса о разрешении: на него надо ответить, и
   выглядеть он должен не репликой, а остановкой. */
/* В окне-сообщении бывают строки со своим смыслом — счётчики, перечисления:
   переносы в них должны оставаться переносами. */
#ask-text { white-space: pre-line; }
/* «Заказать новый образец?» (05.11.2026): фото товара слева, имя и что с образцами справа. */
.sample-order-ask { display: flex; align-items: center; gap: 12px; white-space: normal; }
.sample-order-ask-photo {
  flex: none; width: 64px; height: 84px; object-fit: cover; border-radius: var(--radius-sm);
}
.sample-order-ask-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* «Новые примерки» (10.11.2026): образцы примерки строками с фото, ниже — куда они денутся «не сейчас». */
.fit-new { display: flex; flex-direction: column; gap: 10px; white-space: normal; }
.fit-new-list { display: flex; flex-direction: column; gap: 8px; max-height: 50vh; overflow-y: auto; }
.fit-new-row { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.fit-new-row:last-child { border-bottom: 0; }
.fit-new-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.fit-new-photo { flex: none; width: 44px; height: 58px; object-fit: cover; border-radius: var(--radius-sm); cursor: zoom-in; }
/* Распознанный образец кнопкой — «это другой товар» (11.11.2026). */
.fit-new-code {
  align-self: flex-start; padding: 2px 8px; margin-left: -8px; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: none; color: inherit; font: inherit; font-weight: 600; text-align: left; cursor: pointer;
}
.fit-new-code:hover, .fit-new-code:focus-visible { border-color: var(--accent); background: var(--accent-dim); }
.fit-new-model { display: flex; flex-direction: column; gap: 4px; }
.fit-new-model-row { display: flex; flex-wrap: wrap; gap: 6px; }
.fit-new-model-photo {
  width: 72px; height: 96px; object-fit: cover; border-radius: var(--radius-sm); cursor: zoom-in; border: 1px solid var(--line);
}
.fit-new-model-photo:hover { border-color: var(--accent); }
/* Каталог «Какой товар мерили?»: поиск и товары плитками, у плитки — кнопки её образцов. */
.fit-pick-search { margin: 8px var(--pad-lg) 0; width: calc(100% - 2 * var(--pad-lg)); }
.fit-pick { z-index: 55; }
#ask-modal .modal-panel:has(.fit-new-model) { width: min(640px, calc(94vw - var(--chat-room))); }
.fit-pick .fit-pick-grid { max-height: 60vh; overflow-y: auto; }
.fit-pick-tile { display: flex; flex-direction: column; gap: 4px; }
/* «О-132 · 37 Factory» шире узкой плитки и вылезал за край (11.11.2026): переносится строкой. */
.fit-pick-sample { width: 100%; min-width: 0; white-space: normal; overflow-wrap: anywhere; line-height: 1.2; text-align: center; }
.fit-new-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* «Выбрать товар» у неузнанной примерки — обычная кнопка под строкой «Не узнали…». */
.fit-new-pick { align-self: flex-start; width: auto; margin: 4px 0 2px; }
/* «Итоги примерки» — образцы плашками: какой открыт, какие записаны. */
.fit-results-steps { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.fit-results-step {
  flex: 0 0 auto; width: auto; border: 1px solid var(--line); background: var(--panel); color: var(--text);
  border-radius: 20px; padding: 5px 12px; font-size: 13px; cursor: pointer;
}
.fit-results-step:hover { border-color: var(--muted); }
.fit-results-step.on { background: var(--accent-dim); border-color: var(--accent); font-weight: 600; }
.fit-results-step.done { color: var(--tile-green-text); }
.fit-results-left { font-size: 12px; color: var(--muted); margin-left: 4px; }
/* «Мой склад» (18.10.2026): строка в окне бренда и окно настройки. */
.ms-brand-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.ms-brand-row > .grow { flex: 1 1 auto; min-width: 0; }
.ms-bad { color: var(--ink-rose); }
.ms-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ms-state { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; font-weight: 600; }
.ms-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.ms-state.is-on .ms-dot { background: var(--accent); }
.ms-state.is-bad .ms-dot { background: var(--danger); }
.ms-error {
  margin-top: 8px; padding: 6px 10px; font-size: 13px;
  background: var(--tile-rose-bg); color: var(--tile-rose-text); border-radius: var(--radius-sm);
}
.ms-map {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.2fr);
  align-items: center; gap: 6px 10px; margin: 6px 0 4px;
}
.ms-map-crm { font-size: 13px; }
.ms-map-arrow { color: var(--muted); }
.ms-map select, .ms-map .combo { width: 100%; min-width: 0; }
.ms-preview { margin: 6px 0; }
.ms-list-head { font-weight: 600; font-size: 13px; margin-top: 8px; }
.ms-list-head.ms-warn, .ms-warn { color: var(--warn-ink); }
div.ms-warn {
  margin-top: 8px; padding: 6px 10px; font-size: 13px;
  background: var(--tile-yellow-bg); border-radius: var(--radius-sm);
}
.ms-list { margin: 4px 0 0; padding-left: 18px; font-size: 13px; line-height: 1.45; }
/* «Заказ ждёт размещения» (05.11.2026): строка на заказ — текст и «Игнорировать». */
.ms-ready-list { display: flex; flex-direction: column; gap: 10px; white-space: normal; }
.ms-ready-row { display: flex; align-items: center; gap: 12px; }
.ms-ready-row + .ms-ready-row { padding-top: 10px; border-top: 1px solid var(--line); }
.ms-ready-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; line-height: 1.4; }
.ms-ready-row > .btn { flex: none; }
/* Окно шире (05.11.2026): справа от текста — товары заказа, фото и размеры. */
#ask-modal .modal-panel:has(.ms-ready-list) { width: min(940px, calc(94vw - var(--chat-room))); }
.ms-ready-row:has(> .ms-ready-items) { align-items: flex-start; }
.ms-ready-row:has(> .ms-ready-items) > .ms-ready-text { flex: 0 1 300px; }
.ms-ready-items { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.ms-ready-item { display: flex; align-items: flex-start; gap: 12px; }
.ms-ready-photo {
  flex: none; width: 72px; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden;
  background: var(--bg);
}
.ms-ready-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ms-ready-item-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.ms-ready-item-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.ms-ready-sizes { display: flex; flex-wrap: wrap; gap: 6px; }
.ms-ready-size {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 8px;
  border: 1px solid var(--line); border-radius: 999px; font-size: 13px; white-space: nowrap;
}
.ms-ready-total, .ms-ready-wait { font-size: 13px; }
@media (max-width: 720px) {
  .ms-ready-row { flex-wrap: wrap; }
  .ms-ready-row:has(> .ms-ready-items) > .ms-ready-text { flex: 1 1 100%; }
}
.ms-ready-row.is-ignored .ms-ready-text { color: var(--muted); text-decoration: line-through; }
.ms-ready-ignored { margin-top: 4px; }
.ms-ready-ignored .ms-ready-row { padding: 4px 0; font-size: 13px; }
/* «Что нового в CRM» (04.10.2026): пункт списком, перенос — под текст, а не под точку. */
.whats-new-entry + .whats-new-entry { margin-top: 12px; }
.whats-new-head { font-weight: 600; margin-bottom: 4px; }
.whats-new-list { margin: 0; padding-left: 18px; }
.whats-new-list li { line-height: 1.45; }
.whats-new-list li + li { margin-top: 6px; }
/* «Новые поручения» ассистента (20.10.2026): что поручили — крупно, под ним
   срок плашкой задачника и где. Строка — карточкой, чтобы два поручения не
   сливались в один абзац. */
.assigned-new-from { font-size: 13px; color: var(--muted); margin-bottom: 8px; }
.assigned-new-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.assigned-new-item {
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.assigned-new-text { font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.assigned-new-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 6px; }
.assigned-new-meta .task-due { font-size: 13px; line-height: 20px; }
.assigned-new-nodue, .assigned-new-where { font-size: 13px; color: var(--muted); }

/* «Изменения в CRM после разбора» (20.10.2026, просьба владелицы: окно «красиво
   оформленное»). Крупный заголовок, плитки-счётчики по разделам, ниже пункты
   карточками: номер цветной плашкой, товар, фабрика справа, что поменялось и
   слова из переписки курсивом. Цвета разделов — те же тона, что у плашек «Лога». */
.parse-news-panel { width: min(680px, calc(94vw - var(--chat-room))); max-height: 86vh; }
.parse-news-panel:focus { outline: none; }
.pn-head { padding: 20px 24px 14px; border-bottom: 1px solid var(--line); }
.pn-eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted); letter-spacing: .02em;
}
.pn-title {
  margin: 6px 0 0; font-family: var(--font-display); font-size: 21px; line-height: 1.25;
  font-weight: 700; color: var(--ink); overflow-wrap: anywhere;
}
.pn-sub { margin-top: 6px; font-size: 13px; color: var(--muted); }
.pn-failed {
  display: flex; align-items: center; gap: 6px; margin-top: 10px; padding: 6px 10px;
  border-radius: var(--radius-sm); font-size: 13px; background: var(--tile-rose-bg-3); color: var(--tile-rose-text);
}
.pn-body { padding: 16px 24px 10px; overflow-y: auto; }
.pn-tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 8px; margin-bottom: 18px;
}
.pn-tile {
  display: grid; grid-template-columns: auto 1fr; column-gap: 8px; row-gap: 2px;
  align-items: center; text-align: left; padding: 10px 12px;
  border: 0; border-radius: var(--radius); cursor: pointer; font: inherit;
}
.pn-tile svg { grid-row: 1 / span 2; opacity: .85; }
.pn-tile b { font-size: 22px; line-height: 1; }
.pn-tile span { font-size: 12px; line-height: 1.2; }
.pn-tile:hover { filter: brightness(.96); }
.pn-group { scroll-margin-top: 8px; }
.pn-group + .pn-group { margin-top: 16px; }
.pn-group-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.pn-group-icon {
  display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: var(--radius-sm);
}
.pn-group-title { font-weight: 600; font-size: 14px; }
.pn-group-n {
  font-size: 12px; color: var(--muted); padding: 1px 8px; border-radius: 999px;
  background: var(--panel-2);
}
.pn-items { display: flex; flex-direction: column; gap: 8px; }
/* Пункт (27.10.2026, «сейчас это просто набор текста»): фото товара слева,
   номер и артикул крупно, фабрика плашкой, перемены строками со своим видом,
   слова фабрики пузырём, стрелка «открыть» справа. */
.pn-item {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: start;
  column-gap: 12px; width: 100%; text-align: left; font: inherit; color: inherit;
  padding: 10px 12px 10px 10px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel);
}
button.pn-item { cursor: pointer; transition: border-color .12s, background .12s; }
button.pn-item:hover { border-color: var(--accent); background: var(--hover); }
button.pn-item:hover .pn-go { color: var(--text); transform: translateX(2px); }
.pn-thumb {
  width: 48px; height: 48px; border-radius: var(--radius-sm); object-fit: cover; display: block;
  background: var(--panel-2);
}
.pn-thumb-icon { display: grid; place-items: center; }
.pn-item-main { min-width: 0; display: flex; flex-direction: column; gap: 6px; padding-top: 2px; }
.pn-item-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-height: 22px; }
.pn-code { font-weight: 700; font-size: 13px; padding: 2px 9px; border-radius: 999px; }
.pn-name { font-weight: 700; font-size: 14px; color: var(--ink); }
.pn-item-title {
  flex: 1 1 260px; min-width: 0; font-size: 14px; line-height: 1.4; font-weight: 500;
  color: var(--ink); overflow-wrap: anywhere;
}
.pn-factory {
  display: inline-flex; align-items: center; gap: 4px; margin-left: auto; flex: none;
  font-size: 12px; color: var(--muted); padding: 2px 8px; border-radius: 999px;
  background: var(--panel-2); white-space: nowrap;
}
.pn-facts { display: flex; flex-direction: column; gap: 4px; }
.pn-fact {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px;
  font-size: 13px; line-height: 1.35; color: var(--text-2);
}
.pn-fact > svg { color: var(--muted); flex: none; }
.pn-fact-icon {
  display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 7px;
  background: var(--panel-2); color: var(--muted); flex: none;
}
.pn-fact-label { color: var(--muted); }
.pn-fact-value { color: var(--ink); font-weight: 700; overflow-wrap: anywhere; }
.pn-fact-was { color: var(--muted); font-size: 12px; }
.pn-fact-text { color: var(--text); overflow-wrap: anywhere; }
.pn-fact[data-result="failed"] .pn-fact-icon { background: var(--tile-rose-bg-3); color: var(--tile-rose-text); }
.pn-fact[data-result="passed"] .pn-fact-icon { background: var(--tile-green-bg); color: var(--tile-green-text); }
.pn-fact-price .pn-fact-icon, .pn-fact-qty .pn-fact-icon { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.pn-fact-deadline .pn-fact-icon, .pn-fact-fitting_planned .pn-fact-icon,
.pn-fact-fitting_sent .pn-fact-icon { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.pn-pill { font-size: 12px; padding: 2px 9px; white-space: nowrap; }
/* «Было» — тише, «стало» — главное в строке. */
.pn-fact-status .pn-pill:not(.pn-pill-to) { opacity: .62; }
.pn-pill-to { box-shadow: inset 0 0 0 1px var(--line-2); }
.pn-pill-stage { background: var(--panel-2); color: var(--text-2); }
.pn-pill-stage.pn-pill-to { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.pn-quote {
  display: flex; gap: 8px; align-items: flex-start; padding: 8px 10px;
  border-radius: 4px 12px 12px 12px; background: var(--panel-2);
}
.pn-quote-icon { color: var(--muted); flex: none; padding-top: 2px; }
.pn-quote-list { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pn-note { font-size: 13px; line-height: 1.45; color: var(--text-2); overflow-wrap: anywhere; }
.pn-go {
  align-self: center; color: var(--muted); display: inline-grid; place-items: center;
  transition: transform .12s, color .12s;
}
/* Пункт словами без фото (задача, закрытое, вопрос) — компактнее: значок меньше. */
.pn-item-plain { grid-template-columns: 32px minmax(0, 1fr) auto; padding: 9px 12px 9px 10px; align-items: center; }
.pn-item-plain .pn-thumb { width: 32px; height: 32px; border-radius: var(--radius-sm); }
.pn-item-plain .pn-item-main { padding-top: 0; }
.pn-item-done.pn-item-plain .pn-thumb { border-radius: 50%; }
.pn-item-done .pn-item-title { color: var(--text-2); font-weight: 400; }
.pn-item-other .pn-item-title { color: var(--text-2); font-weight: 400; }
/* Одинаковый переход у нескольких заказов — одной строкой с номерами. */
.pn-batch { grid-template-columns: 48px minmax(0, 1fr); }
.pn-stack { position: relative; width: 48px; height: 48px; }
.pn-stack .pn-thumb { position: absolute; width: 38px; height: 38px; border: 2px solid var(--panel); }
.pn-stack .pn-thumb:nth-child(1) { left: 0; top: 0; z-index: 3; }
.pn-stack .pn-thumb:nth-child(2) { left: 6px; top: 6px; z-index: 2; }
.pn-stack .pn-thumb:nth-child(3) { left: 10px; top: 10px; z-index: 1; }
.pn-stack .pn-thumb:only-child { width: 48px; height: 48px; border: 0; }
.pn-batch-n { font-weight: 700; font-size: 14px; color: var(--ink); }
.pn-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pn-chip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 4px 10px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--bg);
  font: inherit; font-size: 13px; color: var(--text);
}
.pn-chip b { font-weight: 700; }
.pn-chip span, .pn-chip small { color: var(--muted); }
.pn-chip small { font-size: 11px; }
button.pn-chip { cursor: pointer; }
button.pn-chip:hover { border-color: var(--accent); background: var(--hover); }
.pn-empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--gap); padding: 28px 12px 22px;
  text-align: center; color: var(--muted); font-size: 14px;
}
.pn-empty svg { color: var(--tile-green-text); }
/* Что прочитано — плашками под заголовком. */
.pn-run { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.pn-run-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 999px;
  background: var(--panel-2); color: var(--text-2); font-size: 12px;
}
.pn-run-chip svg { color: var(--muted); }
.pn-parse .pn-run { margin: 0 0 12px; }
.pn-brand {
  margin: 18px 0 10px; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted);
}
.pn-parse { border: 1px solid var(--line); border-radius: var(--radius); padding: 0 14px; }
.pn-parse + .pn-parse { margin-top: 10px; }
.pn-parse-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; padding: 12px 0;
  cursor: pointer; list-style: none;
}
.pn-parse-head::-webkit-details-marker { display: none; }
.pn-parse-head::before { content: '▸'; color: var(--muted); transition: transform .15s; }
.pn-parse[open] > .pn-parse-head::before { transform: rotate(90deg); }
.pn-parse-name { font-weight: 600; }
.pn-parse-when { color: var(--muted); font-size: 13px; }
.pn-parse-n { margin-left: auto; font-size: 12px; color: var(--muted); text-align: right; }
.pn-parse-body { padding-bottom: 14px; }
.pn-more { margin-top: 12px; font-size: 12px; color: var(--muted); }
.pn-foot {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--gap);
  padding: 12px 24px 16px; border-top: 1px solid var(--line);
}
.pn-foot-right { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
@media (max-width: 560px) {
  .pn-head, .pn-body, .pn-foot { padding-left: 16px; padding-right: 16px; }
  .pn-title { font-size: 18px; }
  .pn-item { grid-template-columns: 40px minmax(0, 1fr) auto; column-gap: 10px; }
  .pn-batch { grid-template-columns: 40px minmax(0, 1fr); }
  .pn-item-plain { grid-template-columns: 32px minmax(0, 1fr) auto; }
  .pn-thumb, .pn-stack, .pn-stack .pn-thumb:only-child { width: 40px; height: 40px; }
  .pn-stack .pn-thumb { width: 32px; height: 32px; }
  .pn-factory { margin-left: 0; }
}
/* «Лог»: то же «Что изменилось» над схемой раскрытого разбора. */
.jr-news {
  margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--panel);
}
.jr-news-title { font-weight: 700; margin-bottom: 10px; }

.chat-hint { align-self: stretch; max-width: none; }
.chat-hint-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

.chat-input {
  display: flex; gap: 8px; align-items: flex-end;
  padding: 10px 14px; border-top: 1px solid var(--line);
}
.chat-attach-btn { padding: 6px 8px; color: var(--muted); }
.chat-attach-btn:hover { color: var(--ink-green); }
/* Файлы к вопросу — чипы над полем ввода; картинка показывается миниатюрой. */
.chat-attach {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px 14px 0; border-top: 1px solid var(--line);
}
.chat-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 3px 6px 3px 4px; border-radius: var(--radius-sm); font-size: 12px;
  background: var(--bg); border: 1px solid var(--line); color: var(--text);
}
.chat-chip img { width: 28px; height: 28px; object-fit: cover; border-radius: 5px; }
.chat-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }
.chat-chip-size { color: var(--muted); }
.chat-chip-x { border: 0; background: none; cursor: pointer; color: var(--muted); font: inherit; padding: 0 2px; }
.chat-chip-x:hover { color: var(--tile-rose-text); }
/* Вложения в отправленной реплике: миниатюры и имена файлов. */
.chat-msg-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chat-msg-files img { max-width: 160px; max-height: 120px; border-radius: var(--radius-sm); display: block; }
.chat-msg-files .chat-chip { background: var(--c-rgba-255-255-255-18-s); border-color: var(--c-rgba-255-255-255-35-l); color: inherit; }
.chat-panel.drop { outline: 2px dashed var(--accent); outline-offset: -4px; }
/* Ответ Гермеса: лёгкий markdown — списки, жирный, код. */
.chat-md .chat-list { margin: 2px 0 2px 18px; padding: 0; }
.chat-md .chat-list li { margin: 1px 0; }
.chat-md .chat-md-head { font-weight: 700; margin-top: 4px; }
.chat-md .chat-md-gap { height: 6px; }
.chat-md code { font-size: 12px; background: var(--panel-2); padding: 0 4px; border-radius: 4px; }
.chat-md .chat-code {
  margin: 4px 0; padding: 6px 8px; border-radius: var(--radius-sm); font-size: 12px;
  background: var(--panel-2); white-space: pre-wrap; word-break: break-word;
}
.review-images { margin-top: 8px; }
/* Завершённый чек-лист стоит на акцентном фоне: приглушённый текст на нём не читается. */
.checklist.complete .muted, .checklist.complete .checklist-count,
.checklist.complete .date-pill, .checklist.complete small { color: var(--ink-green); }
.chat-input textarea {
  flex: 1 1 auto; min-width: 0; resize: none; font: inherit; font-size: 13px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text);
}
.chat-input textarea:focus { border-color: var(--accent); background: var(--panel-raw); }

/* Выпадашка, в которой можно печатать (решение 14.09.2026).
   Снаружи ведёт себя как <select>, поэтому и выглядеть должна так же: те же
   рамка, высота и стрелка. Список — поверх формы, с прокруткой. */
.combo { position: relative; }
.combo-input {
  width: 100%;
  /* Стрелка та же, что браузер рисует у <select>: элемент поменялся, а
     выпадашка на экране обязана остаться прежней. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%237a7268' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 26px;
  cursor: pointer;
}
.combo-input:focus { cursor: text; }
.combo.disabled .combo-input { opacity: .6; cursor: default; }
/* ВЫПАДАШКА В РЯДУ ДЕЙСТВИЙ — РОСТОМ С КНОПКАМИ РЯДОМ (аудит 24.09.2026).
   В «Таблицах» ряд собран из трёх малых кнопок и выпадашки «Все
   производства», и выпадашка была на 7.5 px выше: ряд шёл ступенькой.
   Здесь она не поле формы, а такая же кнопка выбора — и размер у неё
   кнопочный. */
.row-actions > .combo .combo-input,
.section-actions > .combo .combo-input,
.actions > .combo .combo-input {
  padding: 4px 26px 4px 12px; font-size: 13px;
}

/* КНОПКА РЯДОМ С ПОЛЕМ ВВОДА — ОДНОЙ С НИМ ВЫСОТЫ (аудит 24.09.2026).
   «Применить» у комментария в карточке заказа, «Добавить» в настройках
   брендов, «+ Добавить» в окне новых образцов — всюду поле 36 px, а кнопка
   вплотную к нему 30: пара читалась как два разных ряда. Правило смотрит на
   состав самого ряда, поэтому работает и в окнах, которых ещё нет. */
.row-actions:has(> input:not([type="checkbox"]):not([type="radio"])) > .btn,
.row-inline:has(> input:not([type="checkbox"]):not([type="radio"])) > .btn,
.status-row > .btn {
  min-height: 36px;
}
.combo-menu {
  /* Поле бывает узким (в форме их два в ряд), а имена контрагентов длинные:
     список шире поля — иначе «Модель ОТК Полина» читается как «Модель ОТК
     Пол…», и выбирать приходится наугад.

     МЕСТО СПИСКУ СЧИТАЕТ JS (`place` в ui/sections.js), потому что он висит
     НАД страницей: лежал внутри поля `position: absolute` — и всякий предок с
     `overflow: hidden` его резал (у коротких окон — по дну панели). Значения
     ниже остаются запасными: ими список выглядит собой до первого открытия. */
  position: fixed; z-index: 40; left: 0; top: calc(100% + 4px);
  min-width: 100%; width: max-content; max-width: 340px;
  max-height: 240px; overflow-y: auto;
  background: var(--card, var(--panel-raw)); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 8px 24px var(--c-rgba-40-34-28-12-s);
  padding: 4px;
}
.combo-item {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: 6px 9px; border-radius: 7px; cursor: pointer; font: inherit;
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.combo-item:hover, .combo-item.marked { background: var(--bg); }
.combo-item.on { color: var(--ink-green); font-weight: 600; }
/* Основная модель бренда в выпадашке получателя — подсвечена и подписана (13.10.2026). */
.combo-item.combo-item-mark { background: var(--accent-dim); }
.combo-item.combo-item-mark:hover, .combo-item.combo-item-mark.marked { background: var(--bg); }
.combo-mark {
  margin-left: 8px; font-size: 11px; color: var(--ink-green); font-weight: 600;
}
.combo-empty { padding: 8px 9px; color: var(--muted); font-size: 13px; }
.combo-group {
  padding: 7px 9px 3px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted);
}

/* Окно разбора: бренды галочками, техническое — под свёрткой. */
.plan-brands {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap);
  margin-bottom: 10px;
}
.plan-brands:empty { display: none; }
.plan-brand {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 13px;
}
.plan-brand:hover { border-color: var(--muted); }
.plan-advanced { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.plan-advanced > summary { cursor: pointer; font-size: 13px; color: var(--muted); }
.plan-advanced-hint { margin: 8px 0; }

/* Кнопка «+ Задача» над списком: своё дело заводят там же, где его видят. */
/* Действие задачи — заметной кнопкой: смысл такой задачи в том, чтобы
   написать человеку конкретный вопрос, и вход в готовый текст должен быть
   виден, а не спрятан подписью. */
.task-ask { white-space: nowrap; }

/* ── разбор: сводка и свёрнутый выбор чатов ─────────────── */
.plan-summary { margin: 10px 0 4px; font-size: 14px; }
.plan-pick { margin: 6px 0 2px; }
.plan-pick > summary {
  cursor: pointer; font-size: 13px; color: var(--muted); user-select: none;
  padding: 6px 0;
}
.plan-pick > summary:hover { color: var(--text); }
.plan-pick[open] > summary { color: var(--text); }

/* ── скрипты по образцам: выбор скрипта, производства и самих образцов ── */
/* Свои имена: `.script-picker` уже занят окном скриптов заказов, где он
   выкладывает варианты колонкой, и чужая раскладка растягивала эти чипы. */
.sample-script-picker { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
/* Чипы двух рядов выглядят одинаково, но значат разное: верхний выбирает
   скрипт, нижний — производство. Стиль общий, имена раздельные. */
.sample-script-factory, .sample-script-chip {
  flex: 0 0 auto; width: auto;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  border-radius: 20px; padding: 5px 12px; font-size: 13px; cursor: pointer;
}
.sample-script-factory:hover, .sample-script-chip:hover { border-color: var(--muted); }
.sample-script-factory.on, .sample-script-chip.on {
  background: var(--accent-dim); border-color: var(--accent); font-weight: 600;
}
.sample-script-hint { font-size: 12px; color: var(--muted); margin-bottom: 8px; }

/* ── окно с готовым письмом —————————————————— */
/* Кому отправлять — первой строкой и не петитом: письмо читает то
   фабрика, то модель, а скопированный текст легко уходил не в тот чат.
   Одна строка на все восемь окон со скриптами (24.09.2026). */
.ask-to {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius);
}
.ask-to-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.ask-to-name { font-weight: 650; overflow-wrap: anywhere; }
/* Адресатов несколько — это предупреждение, а не справка: одно письмо
   называет чужие номера и уйти должно каждому по отдельности. */
.ask-to-many { border-color: var(--warn); }
/* Место под строкой: пока адресат не выбран, места оно не занимает. */
.ask-to-slot:empty { display: none; }
/* Переключатель языка и счёт посылок — одной строкой над текстом. */
.ask-script-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px; margin-bottom: 8px;
}
.ask-script-head .sample-script-hint { margin-bottom: 0; }

/* Список образцов с галочками: что именно уходит в текст скрипта. */
/* Список образцов не съедает окно целиком: под ним ещё адрес, текст письма и
   кнопки, а до них надо доскроллить. Шести образцов одного товара хватает,
   чтобы предыдущая высота в 320px оставляла кнопки за краем экрана. */
.sample-pick-list { max-height: 190px; overflow-y: auto; margin-bottom: 10px; }
.sample-script-address { margin-bottom: 6px; }
/* Плюсы и минусы примерки: строка и крестик рядом, поле тянется. */
.fitting-lines { margin-bottom: 8px; }
.fitting-line { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.fitting-line input { flex: 1 1 auto; min-width: 0; }
/* Решение по примерке для фабрики по-китайски (03.11.2026): отдельный блок под русским. */
/* Итог примерки кнопками (03.11.2026): выбранная — подсвечена, повторное нажатие снимает. */
.fitting-verdict { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 8px; }
.fitting-verdict .btn[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-dim); color: var(--ink); }
/* Итог примерки позже (10.11.2026): кнопки у карточки «Ждёт решения» на доске, окно «что исправить»
   и строка «Решение по образцу» в «На сегодня». */
.sample-card-verdict { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 8px; }
.sample-card-verdict .btn {
  flex: 1 1 auto; min-width: 0; padding-left: 3px; padding-right: 3px; font-size: 12px; white-space: nowrap;
}
.sample-verdict-what { font-weight: 650; margin-bottom: 6px; }
.sample-verdict-note { font-size: 13px; color: var(--text-2); margin-bottom: 8px; overflow-wrap: anywhere; }
.sample-verdict-label { font-size: 13px; font-weight: 650; color: var(--text-2); margin-bottom: 4px; }
.sample-verdict-field { width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; resize: vertical; }
/* Вид задачи примерки в «На сегодня»: для бренда / для фабрики (11.11.2026). */
.today-kind { display: inline-block; margin-bottom: 4px; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.today-kind-brand { background: var(--accent-dim); color: var(--accent-ink); }
.today-kind-factory { background: var(--panel-2); color: var(--ink); border: 1px solid var(--line); }
/* Итог бренду записан — блок свёрнут, раскрыть нажатием на заголовок (11.11.2026). */
.fitting-brand > summary { cursor: pointer; list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fitting-brand > summary::-webkit-details-marker { display: none; }
.fitting-brand > summary::before { content: '▾'; }
.fitting-brand:not([open]) > summary::before { content: '▸'; }
.fitting-brand-done { font-size: 13px; font-weight: 600; color: var(--accent-ink); }
/* Решение для бренда и для фабрики — заметной рамкой; вписанное само — курсивом (11.11.2026). */
.fitting-decision { margin: 10px 0 14px; padding: 10px 12px 12px; border: 2px solid var(--accent); border-radius: var(--radius); background: var(--accent-dim); }
.fitting-decision-title { margin: 0 0 6px; font-size: 15px; font-weight: 700; color: var(--ink); }
.fitting-decision textarea { width: 100%; box-sizing: border-box; background: var(--panel); }
.fitting-decision textarea.fitting-auto { font-style: italic; color: var(--muted); }
.fitting-auto-note { margin-top: 4px; font-size: 12px; font-style: italic; color: var(--muted); }
.fitting-zh { margin-top: 28px; padding-top: 16px; border-top: 2px solid var(--line); }
/* Письмо фабрике ушло — свёрнуто, раскрыть — что ушло (13.11.2026). Фото — своим блоком, «Заказать драфт» — внизу. */
.fitting-sent { margin: 0 0 14px; }
.fitting-sent pre { margin: 6px 0 8px; }
.fitting-photos-part { margin-top: 20px; }
.fitting-redraft-order { display: block; width: 100%; margin-top: 20px; padding: 12px 16px; font-size: 16px; }
/* Два скрипта окна «Решение по примерке» — подписи-разделители (11.11.2026). */
.fitting-part { margin: 0 0 10px; padding: 8px 12px; border-radius: var(--radius-sm); background: var(--accent-dim); color: var(--ink); font-size: 15px; font-weight: 700; }
.fitting-zh-photos { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.fitting-zh-photos .sample-script-hint { flex: 1 0 100%; }
.fitting-zh-photos img { width: 84px; height: 84px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); cursor: zoom-in; }
/* «Фото с примерки» / «Фото в карточке» (11.11.2026): вкладки, нажатие — крупно, «Копировать» под фото. */
.fitting-zh-photo-tabs { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 0 100%; }
.fitting-zh-photo-tab { font: inherit; font-size: 13px; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer; }
.fitting-zh-photo-tab.on { border-color: var(--accent); color: var(--ink); font-weight: 600; }
.fitting-zh-photo-grid { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 0 100%; }
.fitting-zh-photo { display: flex; flex-direction: column; gap: 4px; width: 120px; }
.fitting-zh-photos .fitting-zh-photo img { width: 120px; height: 120px; }
.fitting-zh-photo-copy { font: inherit; font-size: 12px; padding: 3px 0; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; }
.fitting-zh-photo-copy:hover { border-color: var(--accent); }
/* «×» и перенос «↓/↑» видны всегда (06.10.2026). У ленты этапов крестик
   прозрачен до наведения на строку, а строк примерки то правило не касалось:
   убрать предложенную строку было нечем на глаз. */
.fitting-line .dev-stage-remove, .fitting-line-move {
  flex: 0 0 auto; width: 26px; height: 26px; padding: 0; opacity: 1;
  border: 1px solid transparent; border-radius: 6px; background: transparent;
  color: var(--muted); cursor: pointer; font-size: 14px; line-height: 1;
}
.fitting-line .dev-stage-remove:hover, .fitting-line-move:hover,
.fitting-line .dev-stage-remove:focus-visible, .fitting-line-move:focus-visible {
  color: var(--text); border-color: var(--line); background: var(--panel-2);
}
.fitting-marks-source[hidden] { display: none; }
.sample-pick-group {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); margin: 10px 0 4px;
}
.sample-pick-group:first-child { margin-top: 0; }
.sample-pick-row {
  display: flex; align-items: center; gap: var(--gap);
  padding: 6px 9px; border-radius: var(--radius-sm); background: var(--panel-2);
  font-size: 13px; cursor: pointer; margin-bottom: 4px;
}
.sample-pick-row input[type="checkbox"],
.sample-pick-row input[type="radio"] { flex: 0 0 auto; }
.sample-pick-row .grow { flex: 1; min-width: 0; color: var(--muted); }
/* «Решение по примерке»: полоса уже завершённых отделена, но не заперта.
   Выбрать такой образец можно — решение иногда оформляют задним числом. */
.sample-pick-group.muted { opacity: .7; }
.sample-pick-row.spent { opacity: .72; }
.sample-pick-row.spent:hover { opacity: 1; }
/* Строка образца «Решения по примерке» (10.11.2026): номер и товар, под ними
   серым — когда уехал и примерен; цена справа. Без плашек: они не сжимались. */
.sample-pick-row.fit-pick { align-items: flex-start; gap: 10px; padding: 8px 12px; }
.fit-pick input[type="radio"] { margin-top: 2px; }
.fit-pick-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fit-pick-top { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.fit-pick-top strong { flex: 0 0 auto; white-space: nowrap; }
.fit-pick-name { min-width: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fit-pick-meta { font-size: 12px; color: var(--muted); }
.fit-pick-price { flex: 0 0 auto; white-space: nowrap; color: var(--text-2); font-variant-numeric: tabular-nums; }
/* У решения свой список, и он длиннее общего: полос три, а под ним ещё плюсы,
   минусы и текст письма. Держим его чуть выше, но всё так же прокручиваемым. */
.sample-pick-list { max-height: 230px; }

/* ── товары: вкладки «Тестируется» и «Действующие» ──────── */
.product-tabs {
  /* Переносим, а не обрезаем: на узком окне четвёртая кнопка уезжала за край
     контейнера и нажать её было нечем. */
  display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 12px;
}
.product-tab {
  width: auto; display: inline-flex; align-items: baseline; gap: 6px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  border-radius: 20px; padding: 6px 14px; font-size: 13px; cursor: pointer;
}
.product-tab:hover { color: var(--text); }
.product-tab.on {
  background: var(--accent-dim); border-color: var(--accent);
  color: var(--text); font-weight: 600;
}

/* ── «Продукты», вид «По фабрикам» (17.09.2026) ──────────
   Фабрика — ВКЛАДКА, её текущая работа — строки внутри. Действующие и
   отложенные юниты лежат под свёрткой: они у фабрики есть, но это не работа.

   Полоса вкладок прокручивается вбок и не переносится: фабрик бывает десяток,
   и второй ряд кнопок менял бы высоту шапки от бренда к бренду. */
.factory-tabs {
  display: flex; margin: 2px 0 14px; max-width: 980px;
  border-bottom: 1px solid var(--line);
}
.factory-tabs-scroll {
  display: flex; gap: 4px; min-width: 0; flex: 1 1 auto;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
  padding-bottom: 1px;
}
.factory-tab {
  flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 6px;
  max-width: 260px; padding: 7px 13px; margin-bottom: -1px;
  border: 1px solid transparent; border-bottom: none; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: transparent; color: var(--muted); font: inherit; font-size: 13px;
  cursor: pointer; white-space: nowrap;
}
.factory-tab-name { overflow: hidden; text-overflow: ellipsis; }
.factory-tab:hover { color: var(--text); background: var(--hover); }
/* Активная вкладка видна и цветом, и рамкой: одного фона мало — в тёмной теме
   он почти сливается с полосой. */
.factory-tab.on {
  background: var(--panel); border-color: var(--line); border-bottom-color: var(--panel);
  color: var(--text); font-weight: 650;
}
.factory-tab:focus-visible { outline: 2px solid var(--ink-green); outline-offset: -2px; }
.factory-tab-n {
  flex: 0 0 auto; border-radius: var(--radius-sm); padding: 0 6px;
  background: var(--panel-2); font-size: 11px; font-weight: 500; color: var(--muted);
}
.factory-tab.on .factory-tab-n { background: var(--accent); color: var(--ink); }
/* Фабрика без текущей работы: вкладка остаётся (действующие и отложенные у неё
   есть), но не зовёт себя нажать. */
.factory-tab.idle { opacity: .62; }
.factory-tab.idle .factory-tab-n { opacity: .7; }
/* «в библиотеке»: по фабрике не работают, но её юниты — бренда, и вкладка
   остаётся. Подпись словами, а не цветом: цвет тут уже занят «нет работы». */
.factory-tab-shelved {
  flex: 0 0 auto; font-size: 11px; font-weight: 500; color: var(--muted);
}
.factory-tab-panel { max-width: 980px; }
.factory-unit-group {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: 12px 14px;
}
.factory-unit-group-head {
  display: flex; align-items: baseline; gap: var(--gap); margin-bottom: 9px;
  padding-bottom: 8px; border-bottom: 1px solid var(--line-4);
}
.factory-unit-group-name { font-size: 14px; font-weight: 650; min-width: 0; overflow-wrap: anywhere; }
.factory-unit { padding: 7px 0; border-bottom: 1px solid var(--line-4); min-width: 0; display: flex; gap: 10px; align-items: flex-start; overflow-wrap: anywhere; }
.factory-unit .factory-unit-thumb { width: 40px; height: 50px; }
.factory-unit-body { flex: 1; min-width: 0; }
.factory-unit:last-child { border-bottom: none; }
.factory-unit-head { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; }
.factory-unit-name { font-size: 13px; font-weight: 600; min-width: 0; }
.factory-unit-code { font-size: 13px; }
.factory-unit-price { font-size: 13px; color: var(--text-2); margin-left: auto; }
.factory-unit-tag {
  padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 600;
  background: var(--panel-3); color: var(--text-3);
}
.factory-unit-meta, .factory-unit-note { font-size: 12px; margin-top: 3px; }
.factory-unit-result { display: flex; align-items: baseline; gap: 6px; margin-top: 4px; font-size: 12px; }
.factory-unit-result.rejected .status-pill { background: var(--tile-rose-bg-3); color: var(--ink-rose); }
.factory-unit-result.approved .status-pill { background: var(--accent-dim); color: var(--ink-green); }
.factory-unit-more { margin-top: 8px; }
.factory-unit-more > summary {
  cursor: pointer; font-size: 12px; color: var(--muted); padding: 3px 0;
}
.factory-unit-more > summary:hover { color: var(--text); }

/* ── товары: список строк, подробности — боковой панелью ── */
.product-feed { display: flex; flex-direction: column; gap: 6px; max-width: 900px; }
.product-row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px; cursor: pointer;
  border-radius: var(--radius); background: var(--panel);
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s);
}
.product-row:hover { box-shadow: 0 2px 8px var(--c-rgba-80-66-48-12-s); }
.product-row.testing { border-left: 4px solid var(--c-d9b96a-l); }
.card-thumb {
  position: relative; flex: 0 0 auto; width: 46px; height: 58px;
  border-radius: var(--radius-sm); overflow: hidden; background: var(--bg);
  border: 1px solid var(--line);
}
.card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-thumb.empty {
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-size: 9px; color: var(--muted); padding: 2px;
}
.card-thumb-count {
  position: absolute; right: 2px; bottom: 2px; padding: 0 4px;
  border-radius: 6px; background: var(--c-rgba-59-50-39-72-s); color: var(--on-accent); font-size: 10px;
}
.product-summary-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.product-name { font-family: var(--font-display); font-size: 16px; }
.product-summary-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.product-row-side { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.product-price {
  flex: 0 0 auto; font-family: var(--font-display); font-size: 16px;
  font-variant-numeric: tabular-nums;
}

/* Карточка, на которую пришли по ссылке: подсветка на пару секунд, чтобы
   глазами найти её в списке. Ссылки на карточки CRM — решение от 29.08.2026. */
.focused {
  outline: 2px solid var(--accent); outline-offset: 2px;
  animation: focus-fade 2.4s ease-out 1s forwards;
}
@keyframes focus-fade { to { outline-color: transparent; } }

/* Итог утреннего разбора делится по брендам (решение Q117 от 29.08.2026):
   человек стоит в одном бренде, а в общем списке были заказы другого. */
.digest-brand { margin-top: 12px; }
.digest-brand:first-of-type { margin-top: 6px; }
.digest-brand-title {
  font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  color: var(--muted); padding-bottom: 4px; margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
}

/* ── лог: журнал действий по дням ───────────────────────── */
.log-days { display: flex; flex-direction: column; gap: 18px; max-width: 760px; }
.log-list { display: flex; flex-direction: column; gap: 4px; }
.log-row {
  display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap;
  padding: 7px 11px; border-radius: var(--radius-sm); background: var(--panel);
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-05-s);
}
.log-time {
  flex: 0 0 auto; font-variant-numeric: tabular-nums;
  font-size: 12px; color: var(--muted);
}
.log-actor {
  flex: 0 0 auto; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; border-radius: 20px; padding: 1px 8px;
}
.log-actor-board { background: var(--tile-green-bg-2); color: var(--c-4a7c59-t); }
.log-actor-agent { background: var(--tile-violet-bg-2); color: var(--c-7c6a92-t); }
.log-actor-system { background: var(--tile-cream-bg); color: var(--c-a8742f-t); }
/* Основа 0, а не по содержимому: строка журнала теперь переносится (перечень
   уборки живёт под ней), и длинное действие иначе уезжало бы на вторую строку
   целиком вместо того, чтобы просто ужаться. */
.log-action { flex: 1 1 0; font-size: 13px; min-width: 0; overflow-wrap: anywhere; }

/* Действие без бренда: видно в любом бренде, но серым и с пометкой «общее»
   (решение Q116 от 29.08.2026) — иначе чужая строка читается как своя. */
.log-row.log-shared { opacity: .72; }
.log-common {
  flex: 0 0 auto; font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); border-radius: 20px; padding: 1px 7px;
}

/* Перечень при строке журнала: что именно унесла еженедельная уборка (Q89). */
.log-items { flex: 1 0 100%; margin-top: 2px; font-size: 12px; }
.log-items > summary {
  cursor: pointer; color: var(--muted); list-style: none;
  border-bottom: 1px dashed var(--line); display: inline-block;
}
.log-items > summary::-webkit-details-marker { display: none; }
.log-items-list { display: flex; flex-direction: column; gap: 2px; margin: 5px 0 2px 2px; }
.log-item { font-size: 13px; color: var(--ink); overflow-wrap: anywhere; }
.log-item::before { content: '• '; color: var(--muted); }
/* Хвост списка: сколько показано и чем добрать. Той же ширины, что и строки. */
.log-more {
  display: flex; align-items: center; gap: 12px;
  max-width: 760px; margin-top: 14px; font-size: 13px;
}

/* ── «Лог» схемой «что из чего вышло» (30.09.2026, `ui/journal.js`) ──────────
   Строка — цепочка, свёрнутая: время, кто, что и цветные плашки разделов.
   Раскрытая — схема: слева действие, от него стрелки к тому, что оно
   поменяло. Стрелки рисует CSS: у каждой цели свой кусок ствола и своя
   стрелка, поэтому схема живёт при любой высоте карточек и не пересчитывает
   координаты. */
.jr-tabs { align-items: center; }
/* Отбор «Лога» выпадающими списками (28.10.2026): «Что ▾», «Кто ▾», «Только главное». */
.jr-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }
.jr-filter { position: relative; }
.jr-filter-btn {
  display: inline-flex; align-items: center; gap: 6px; max-width: 340px;
  padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
}
.jr-filter-btn:hover { background: var(--hover); }
.jr-filter-btn.on { border-color: var(--accent); background: var(--accent-dim); }
.jr-filter-title { color: var(--muted); }
.jr-filter-value { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jr-filter-caret { color: var(--muted); font-size: 11px; transition: transform .15s; }
.jr-filter.open .jr-filter-caret { transform: rotate(180deg); }
.jr-filter-menu {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  min-width: 220px; max-height: 60vh; overflow-y: auto; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 8px 24px var(--c-rgba-80-66-48-05-s);
}
.jr-filter.open .jr-filter-menu { display: flex; flex-direction: column; gap: 1px; }
.jr-check {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border-radius: var(--radius-sm); cursor: pointer; font-size: 13px;
}
.jr-check:hover { background: var(--hover); }
.jr-check.on { background: var(--accent-dim); }
.jr-check input { margin: 0; accent-color: var(--accent); }
.jr-check-label { flex: 1 1 auto; }
.jr-check-n { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.jr-major-only {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer; font-size: 13px;
}
.jr-major-only.on { border-color: var(--accent); background: var(--accent-dim); font-weight: 600; }
.jr-major-only input { margin: 0; accent-color: var(--accent); }

/* Главное — полоса слева и событие плашкой; мелочь — тихая строка без плашек. */
.jr-item.jr-major { box-shadow: inset 4px 0 0 var(--accent), 0 1px 3px var(--c-rgba-80-66-48-05-s); }
.jr-item.jr-major .jr-title { font-weight: 600; font-size: 14px; }
.jr-events { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; flex: 0 1 auto; }
.jr-event {
  white-space: nowrap; font-size: 12px; font-weight: 600; border-radius: 20px; padding: 2px 9px;
  background: var(--tile-green-bg); color: var(--tile-green-text);
}
.jr-event-more { background: var(--panel-3); color: var(--text-3); }
.jr-item.jr-minor { background: none; box-shadow: none; }
.jr-item.jr-minor .jr-head { padding-top: 4px; padding-bottom: 4px; }
.jr-item.jr-minor .jr-title { font-size: 13px; color: var(--muted); }
.jr-item.jr-minor .log-actor { opacity: .6; }
.jr-minor-run { border-radius: var(--radius-sm); }
.jr-minor-head {
  display: flex; align-items: center; gap: 8px; padding: 5px 12px; cursor: pointer;
  font-size: 13px; color: var(--muted); border-radius: var(--radius-sm);
}
.jr-minor-head:hover { background: var(--hover); }
.jr-minor-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.jr-minor-caret { font-size: 10px; transition: transform .15s; }
.jr-minor-run.open .jr-minor-caret { transform: rotate(90deg); }
.jr-minor-count { font-weight: 600; white-space: nowrap; }
.jr-minor-what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jr-minor-body { display: none; flex-direction: column; gap: 2px; padding-left: 14px; }
.jr-minor-run.open .jr-minor-body { display: flex; }
.jr-days { display: flex; flex-direction: column; gap: 18px; max-width: 1180px; }
.jr-list { display: flex; flex-direction: column; gap: 4px; }
.jr-item {
  background: var(--panel); border-radius: var(--radius-sm);
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-05-s);
}
.jr-item.jr-shared { opacity: .75; }
.jr-item > .fold-head { margin: 0; }
.jr-head {
  display: flex; align-items: center; gap: var(--gap); width: 100%; min-width: 0;
  padding: 8px 12px; background: none; border: 0; text-align: left;
  font: inherit; color: var(--text); text-transform: none; letter-spacing: 0; font-weight: 400;
}
.jr-head-button { cursor: pointer; }
.jr-head-button:hover { background: var(--hover); border-radius: var(--radius-sm); }
.jr-head-button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-sm); }
/* Действие другого бренда, под которым лежат свои строки: рамка без текста. */
.jr-card-shell { opacity: .55; border-style: dashed; }
.jr-shell .jr-title { color: var(--muted); font-style: italic; }
.jr-leaf .jr-head { padding-left: 30px; }
.jr-head > .log-actor, .jr-head > .log-common { flex: 0 0 auto; }
.jr-time {
  flex: 0 0 auto; font-variant-numeric: tabular-nums; font-size: 12px; color: var(--muted);
}
.jr-title { flex: 1 1 0; min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
.jr-pills { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; flex: 0 1 auto; }
.jr-pill {
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
  font-size: 11px; font-weight: 600; border-radius: 20px; padding: 2px 8px;
}
.jr-pill-n { font-weight: 700; opacity: .8; }
.jr-pill-more { background: var(--panel-3); color: var(--text-3); }
.jr-steps { flex: 0 0 auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.jr-item .log-items { margin: 0 12px 8px 30px; }
/* Итог разбора строкой под его названием (14.10.2026): сколько чатов прочитано,
   сколько нового, с какого по какое время, где не вышло. */
.jr-run { margin: -3px 12px 8px 30px; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.jr-card .jr-run { margin: 4px 0 0; }
.jr-run-bad {
  margin-left: 8px; padding: 0 5px; border-radius: 4px;
  background: var(--danger); color: var(--ink);
}
/* Пришли с надписи «Последний разбор» — строку видно сразу. */
.jr-item.jr-revealed { outline: 2px solid var(--accent); outline-offset: 1px; }
.jr-body { padding: 6px 14px 18px; }
.jr-loading { color: var(--muted); padding: 6px 0; }

/* Цвет раздела: заказы — зелёный, образцы и продукты — розовый, посылки —
   жёлтый, вопросы и задачи — сиреневый, фабрики и контрагенты — пыльный. */
.jr-tone-green { background: var(--tile-green-bg); color: var(--tile-green-text); }
.jr-tone-rose { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.jr-tone-yellow { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.jr-tone-violet { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.jr-tone-blush { background: var(--tile-blush-bg); color: var(--tile-blush-text); }
.jr-tone-cream { background: var(--tile-cream-bg); color: var(--text-3); }

/* Схема: слева действие, справа веер того, что из него вышло. */
.jr-wrap { container: jrflow / inline-size; min-width: 0; --jr-hook: 22px; }
/* Действие стоит вверху, а не посередине веера: схема разбора высокая, и
   искать глазами, откуда всё пошло, человек не должен. Стрелки выходят и
   входят на одной высоте от верха карточки (`--jr-hook`). */
.jr-flow {
  display: grid; grid-template-columns: minmax(180px, 290px) minmax(0, 1fr);
  column-gap: 48px; align-items: start;
}
.jr-flow.jr-flow-alone { grid-template-columns: minmax(180px, 420px); }
.jr-src { position: relative; min-width: 0; }
/* От действия к стволу веера. */
.jr-flow:not(.jr-flow-alone) > .jr-src::after {
  content: ''; position: absolute; top: var(--jr-hook); right: -24px; width: 24px;
  border-top: 2px solid var(--jr-line);
}
.jr-fan { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }
.jr-kid { position: relative; min-width: 0; }
/* Ствол: у каждой цели свой кусок — от стрелки первой до стрелки последней. */
.jr-kid::before {
  content: ''; position: absolute; left: -24px; top: -5px; bottom: -5px;
  border-left: 2px solid var(--jr-line);
}
.jr-kid:first-child::before { top: var(--jr-hook); }
.jr-kid:last-child::before { bottom: auto; height: calc(var(--jr-hook) + 6px); }
.jr-kid:only-child::before { display: none; }
/* Отвод от ствола к цели и наконечник. */
.jr-kid::after {
  content: ''; position: absolute; left: -24px; top: var(--jr-hook); width: 17px;
  border-top: 2px solid var(--jr-line);
}
.jr-arrow {
  position: absolute; left: -9px; top: calc(var(--jr-hook) - 4.5px); width: 8px; height: 11px;
  background: var(--jr-line); clip-path: polygon(0 0, 100% 50%, 0 100%);
}
/* Сделано самим действием — сплошная акцентная стрелка; разнесено CRM следом —
   пунктир. */
.jr-kid.jr-direct::after { border-top-color: var(--accent); }
.jr-kid.jr-direct > .jr-arrow { background: var(--accent); }
.jr-kid.jr-cascade::after { border-top-style: dashed; }

/* Действие — карточка с подписью «кто» и временем. */
.jr-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 9px 11px; min-width: 0; border-left: 3px solid var(--line);
}
.jr-card-board { border-left-color: var(--c-4a7c59-t); }
.jr-card-agent { border-left-color: var(--c-7c6a92-t); }
.jr-card-system { border-left-color: var(--c-a8742f-t); }
.jr-card-top { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.jr-card-title { font-size: 13px; font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.jr-card-compact .jr-card-title { font-weight: 500; font-size: 13px; }
.jr-card-quiet { opacity: .62; background: transparent; }
.jr-card-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 7px; }
.jr-card-foot .jr-pills { justify-content: flex-start; }
.jr-fold { margin-top: 6px; }
.jr-card-foot .jr-fold { margin: 0 0 0 auto; }
.jr-card > .log-items-list { margin-top: 6px; }
.jr-quote { margin: 8px 0 0; font-size: 13px; }
.jr-card > .trace-msg-meta { margin-top: 8px; }
.jr-shots { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.jr-thumb {
  width: 56px; height: 56px; object-fit: cover; border-radius: 7px;
  border: 1px solid var(--line); cursor: zoom-in; background: var(--panel-3);
}
.jr-thumb-gone { font-size: 12px; color: var(--muted); }
.jr-quote .trace-msg-text.clamped { -webkit-line-clamp: 4; }

/* Что поменялось в одном разделе — туда и указывает стрелка. */
.jr-eff { border-radius: var(--radius-sm); padding: 8px 11px; min-width: 0; }
.jr-eff-sec {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  opacity: .85; margin-bottom: 3px;
}
.jr-eff-lines { display: flex; flex-direction: column; gap: 2px; }
.jr-eff-line { font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; color: var(--text); }
.jr-eff-label { font-weight: 700; }
.jr-eff-name { color: var(--text-3); }
.jr-eff .trace-field-to { font-weight: 600; }
.jr-more-lines { padding: 0; height: auto; border: 0; background: none; font-size: 12px; margin-top: 3px; }

/* ── копирование контактов: одна кнопка «Скопировать адрес» ──────────────── */
/* Выпадашка с выбором языка подписей убрана 24.09.2026: адрес копируют одним
   видом — 名称 / 地址 / 电话, — и выбирать было не из чего. */
.copy-menu { position: relative; display: inline-flex; }

/* Селект с кнопкой копирования в одной строке формы. */
.row-inline { display: flex; gap: 6px; align-items: center; min-width: 0; }
.row-inline > :first-child { flex: 1; min-width: 0; }

/* Адрес и контакты в досье фабрики. */
.factory-contact {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.factory-contact-text { white-space: pre-wrap; word-break: break-word; font-size: 13px; }
.factory-contact .entity-card-actions { margin-top: 0; flex-shrink: 0; }
/* В узкой панели справа (18.10.2026: ссылка на фабрику открывает досье панелью)
   три кнопки забирали всю ширину, и адрес вставал столбиком по букве. Тесно —
   кнопки уходят строкой ниже, адрес занимает строку целиком. */
.factory-contact { flex-wrap: wrap; }
.factory-contact .factory-contact-text { flex: 1 1 220px; min-width: 0; }
/* Адрес из анкеты (17.10.2026): кнопок три — им тесно рядом, они уходят строкой ниже. */
.factory-contact.from-anketa { flex-wrap: wrap; }
.factory-contact.from-anketa .factory-contact-text { flex: 1 1 260px; min-width: 0; }
.factory-anketa-address { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }

.script-preview {
  white-space: pre-wrap;
  word-break: break-word;
  font: inherit;
  font-size: 13px;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin: 0 0 12px;
}
/* Пока текст скрипта не подставлен — рамка вокруг пустоты незачем. */
.script-preview:empty { display: none; }

/* ── перенос разработки, списки выбора и история карточки ─── */

.transfer-choices { display: grid; gap: var(--gap); margin-top: 14px; }
.transfer-choice {
  display: grid; gap: 4px; text-align: left; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  cursor: pointer; font: inherit; color: inherit;
}
.transfer-choice:hover { border-color: var(--accent); }
.transfer-choice strong { font-size: 14px; }
.transfer-choice small { color: var(--muted); line-height: 1.4; }

.pick-row {
  display: flex; align-items: center; gap: var(--gap);
  padding: 7px 10px; border-bottom: 1px solid var(--line); cursor: pointer;
}
.pick-row:last-child { border-bottom: 0; }
.pick-row .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pick-row .nm { font-size: 13px; }
.pick-group {
  position: sticky; top: 0; z-index: 1;
  padding: 6px 10px; background: var(--bg);
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.pick-row .muted { font-size: 11px; }

.card-history { margin-top: 14px; }
.card-history > summary {
  cursor: pointer; font-size: 12px; color: var(--muted);
  padding: 6px 0; list-style: none;
}
.card-history > summary::-webkit-details-marker { display: none; }
.card-history > summary::before { content: '▸ '; }
.card-history[open] > summary::before { content: '▾ '; }

.dev-table-move { white-space: nowrap; }
.dev-table-move .btn { margin-right: 6px; }

/* ── шапка: кнопка «назад» ──────────────────────────────── */
.icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--muted); cursor: pointer;
  /* `button` не наследует шрифт сам: внутри значка сейчас только svg, но
     буква, поставленная сюда завтра, набралась бы Arial'ом 13.33 px —
     единственным местом в CRM, где вылезает шрифт браузера (аудит
     24.09.2026). */
  font: inherit;
}
.icon-btn:hover:not(:disabled) { background: var(--hover); color: var(--text); border-color: var(--accent); }
.icon-btn:disabled { opacity: .35; cursor: default; }

/* ── две пары стрелок, которые нельзя путать ───────────────
 *
 * «Назад/вперёд» — ходьба по CRM: данных они не трогают. «Отменить/вернуть» —
 * правка базы. Раньше рядом стояли две пары похожих стрелок без единого
 * признака, что одна из них меняет данные.
 *
 * Различаем тремя способами сразу: формой значка (уголок против загнутой
 * стрелки), группировкой (навигация — одной кнопкой из двух половин) и
 * разделителем между парами.                                              */
.nav-arrows { display: flex; flex: 0 0 auto; }
.nav-arrows .icon-btn { border-radius: 0; }
.nav-arrows .icon-btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.nav-arrows .icon-btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; margin-left: -1px; }
.nav-arrows .icon-btn:hover:not(:disabled) { z-index: 1; }
.topbar-split {
  width: 1px; height: 20px; flex: 0 0 auto;
  background: var(--line); margin: 0 2px;
}
/* Отмена — действие над данными, и в наведении она отзывается своим цветом. */
.undo-arrow:hover:not(:disabled) { border-color: var(--ink-rose); color: var(--ink-rose); }

/* Стрелки отмены — одной группой, на том же шаге, что и раньше в самой шапке.
 * Кнопки «История правок» под ними с 18.10.2026 нет: это экран раздела «Лог». */
.undo-group { display: flex; gap: 12px; flex: 0 0 auto; }
/* «История правок» — экран раздела «Лог» (18.10.2026; до этого — панель под
 * стрелками в шапке). Список своих действий одной карточкой. */
.undo-history-screen { max-width: 760px; }
.undo-history-head { display: flex; align-items: center; gap: 6px; margin: 4px 2px 8px; }
.undo-history-list {
  display: grid; gap: 2px; padding: 4px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.undo-history-item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--gap);
  padding: 8px 10px; border-radius: var(--radius-sm);
}
.undo-history-item:hover { background: var(--hover); }
.undo-history-label {
  font-size: 13px; line-height: 1.35; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.undo-history-item.undone .undo-history-label { color: var(--muted); text-decoration: line-through; }
.undo-history-meta { font-size: 11px; margin-top: 2px; }

/* Окно «после вас это уже изменили — что из этого сделать?» (03.10.2026).
 * Ответы — те же крупные кнопки с пояснением, что у «различия в цене». */
.undo-conflict-panel { width: min(560px, 94vw); }
.undo-conflict-panel:focus { outline: none; }
.undo-conflict-lead { font-weight: 600; overflow-wrap: anywhere; }
.undo-conflict-but { margin-top: 10px; }
.undo-conflict-list { margin: 6px 0 0; padding-left: 18px; display: grid; gap: 6px; overflow-wrap: anywhere; }
.undo-conflict-values { font-size: 12px; margin-top: 2px; }
.undo-conflict-ask { margin-top: 14px; font-weight: 600; }

/* Переключатель темы: только значок, в правом верхнем углу шапки.
 *
 * Стоял внизу меню; 17.09.2026 переехал сюда по просьбе пользователя. Своего
 * размера у него нет — он такая же `icon-btn`, как стрелки, и ряд шапки от
 * него не разъезжается. Подписи нет: солнце, месяц и половинка говорят сами,
 * а текущий режим — в подсказке при наведении (её ставит `ui/theme.js`). */
.topbar-theme { color: var(--muted); }

/* Часы в шапке (20.10.2026, ui/clock.js): ваше время, Москва, Пекин — подпись
 * мелко сверху, цифры под ней. Ваше время подсвечено. Нажатие — выбор пояса. */
.topbar-clock {
  display: inline-flex; align-items: center; gap: 12px; height: 32px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
  color: var(--text); font: inherit; cursor: pointer; flex: 0 0 auto;
}
.topbar-clock:hover { background: var(--hover); }
.tc-item { display: inline-flex; flex-direction: column; align-items: center; line-height: 1; }
.tc-label { font-size: 9px; color: var(--muted); letter-spacing: .02em; white-space: nowrap; }
.tc-time { margin-top: 2px; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tc-mine .tc-label { color: var(--ink-green); font-weight: 600; }
.clock-pop { gap: var(--gap); }
.clock-pick, .clock-pick .combo-input { width: 100%; box-sizing: border-box; }

/* ── контрагенты: анкета фабрики и расчёт по артикулам ──── */
.party-card .entity-card-head { flex-wrap: wrap; }
/* «+ Продукт» с фабриками (13.10.2026): выбор фабрик галочками и письма каждой. */
.new-card-factories { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.new-card-factory-list {
  max-height: 240px; overflow-y: auto; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.new-card-factory {
  display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-radius: 7px; cursor: pointer;
}
.new-card-factory:hover { background: var(--bg); }
/* «Заказать ещё образец» (20.10.2026): у фабрики подпись справа, уже шьющая не нажимается. */
.new-card-factory > .muted { margin-left: auto; font-size: 12px; text-align: right; }
.new-card-factory.busy { cursor: default; opacity: .6; }
.new-card-factory.busy:hover { background: none; }
/* «Выгрузить несколько товаров» (03.11.2026): у товара фото. */
.card-export-list { max-height: 420px; }
.card-export-thumb {
  width: 40px; height: 40px; flex: none; border-radius: 6px; overflow: hidden; background: var(--bg);
}
.card-export-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* «Заказать ещё образец» у действующего товара (28.10.2026): переделка или замена. */
.order-sample-kind {
  margin-left: auto; flex: 0 0 auto; font-size: 11px; border-radius: 999px; padding: 1px 8px;
  color: var(--muted); border: 1px solid var(--line);
}
.order-sample-kind.repl { color: var(--tile-violet-text); border: 1px dashed var(--orchid-petal); background: var(--c-fbf9fd-s); }
.new-card-plan { min-height: 1.2em; }
.new-card-script { padding: 12px 0; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.new-card-script-head { font-weight: 600; }
/* Основная модель бренда — первой в списке и подсвечена рамкой (13.10.2026). */
.party-card.party-default { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.party-card .entity-card-head strong { min-width: 0; word-break: break-word; }
/* Адрес фабрики бывает в три строки китайского — в списке хватает двух. */
.party-card .entity-card-title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.party-card .entity-card-meta .chip {
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Счётчики прижаты к кнопкам, а не к середине: `margin-top: auto` уже есть
   у полосы действий, и два таких отступа делили бы пустоту пополам. */
.party-counters { color: var(--muted); }

.fact-list { display: flex; flex-direction: column; gap: 1px; background: var(--line); border-radius: var(--radius-sm); overflow: hidden; }
/* Третья колонка — правка. Ширина фиксированная и пустая, пока курсор не над
   строкой: значение не должно ездить вбок от одного наведения. */
.fact-row {
  display: grid; grid-template-columns: 150px 1fr 76px;
  gap: 12px; padding: 8px 12px; background: var(--panel); align-items: start;
}
.fact-label { font-size: 12px; color: var(--muted); }
.fact-value { font-size: 13px; white-space: pre-line; word-break: break-word; }
.fact-value a { color: var(--accent-ink, var(--text)); }

.quote-wrap { overflow-x: auto; }
.quote-table { width: 100%; table-layout: fixed; }
.quote-table th { font-size: 11px; }
.quote-table td, .quote-table th { padding: 6px 8px; }
.quote-photo img {
  width: 44px; height: 58px; object-fit: cover; display: block;
  border-radius: 6px; border: 1px solid var(--line); cursor: zoom-in;
}
.quote-cell {
  font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Звёзды, которые посчитала CRM: показываем, но не даём нажимать. */
.stars.readonly .star { cursor: default; opacity: 1; }
.stars.readonly .star:not(.on) { opacity: .35; }
/* Пояснение под названием авто-показателя — там, где у ручных оценок поле
   комментария, поэтому строка держит ту же высоту. */
.metric-note-static {
  font-size: 12px; color: var(--muted); line-height: 1.4; margin-top: 2px;
}

/* «Мало данных» вместо звёзд — состояние, а не прочерк: прочерк молчал, а
   молчание на месте оценки читается как ноль. Счёт наблюдений уехал под «ⓘ»
   у названия (24.09.2026). */
.metric-nodata { text-align: right; min-width: 100px; }
.metric-nodata-title { font-size: 12px; font-weight: 600; color: var(--muted); }
/* Название и значение — одной строкой: «На сколько опаздывает · 4 дня». */
.metric-name { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.metric-value {
  font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--ink-green);
}
/* Показатель без звёзд по замыслу: цифра и слово «справка» вместо оценки. */
.metric-plain { text-align: right; min-width: 90px; }
.metric-plain-value {
  font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums;
}

/* Удаление в «Завершено»: кнопка проявляется по наведению на строку — чтобы
   её нельзя было задеть, листая архив, но и искать её не приходилось. */
/* Ячейке достаётся общее правило `.row-actions` (flex + отступ сверху) — оно
   писалось для рядов кнопок в окнах, а здесь выбивало ✕ из строки на 6px вниз
   и вытесняло колонку из табличной раскладки. Возвращаем ячейке ячейкино. */
.closed-table td.row-actions {
  display: table-cell; margin: 0; width: 34px; text-align: right;
  padding-right: 8px; vertical-align: middle;
}
.closed-table .icon-btn {
  border: 0; background: none; cursor: pointer; font-size: 13px; line-height: 1;
  padding: 4px 6px; border-radius: 6px; opacity: 0; transition: opacity .12s ease;
  color: var(--muted);
}
.closed-table tr:hover .icon-btn,
.closed-table .icon-btn:focus-visible { opacity: 1; }
.closed-table .icon-btn.danger:hover { background: var(--c-f6e3dd-s); color: var(--c-a8422a-t); }
@media (prefers-reduced-motion: reduce) { .closed-table .icon-btn { transition: none; } }

/* Состав заказа: цифры в колонку, итог отделён линией. */
.items-table { width: 100%; font-size: 13px; }
.items-table td, .items-table th { padding: 7px 10px 7px 0; }
.items-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Подчёркивание тут осталось от времён, когда сам артикул был ссылкой на 1688.
   Артикул давно ведёт в свою карточку, а наружу — отдельный значок рядом. */
.items-table .code a { color: inherit; text-decoration: none; }
.items-table .items-total td { border-top: 1px solid var(--line, var(--line-2)); font-weight: 600; }
/* Узкая панель заказа (09.11.2026, жалоба владелицы: карточка 00226 уезжала влево):
   кнопки строки — поверх суммы, без своей ширины; таблица шире панели —
   прокручивается сама, а не тянет вбок всю карточку. */
#o-items { overflow-x: auto; }
.items-table td, .items-table th { padding-right: 6px; }
#order-modal .items-table td, #order-modal .items-table th { padding-right: 4px; }
#order-modal .items-table th { white-space: normal; }
#order-modal .items-table .item-thumb { width: 36px; padding-right: 6px; }
#order-modal .items-table .item-thumb img { width: 32px; height: 42px; }
.items-table td.item-edit { width: 0; padding: 0; position: relative; }
.items-table .item-edit-btns {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; gap: 4px; white-space: nowrap;
}
.items-table tr:not(:hover) .item-edit-btns:not(:focus-within) { pointer-events: none; }
/* 11.11.2026 («оформление поехало»): артикул и размер не ломаются на дефисе и скобке,
   название — две строки, кнопки строки — значки на подложке поверх суммы. */
.items-table td.code, .items-table td.item-size { white-space: nowrap; }
.items-table .item-title-text {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.items-table .item-edit-btns { gap: 2px; padding-left: 6px; border-radius: 6px; }
.items-table tr:hover .item-edit-btns,
.items-table .item-edit-btns:focus-within { background: var(--panel, var(--panel-4)); }
.items-table .item-edit-btns .btn { min-width: 22px; padding: 2px 4px; }

/* Миниатюра товара в составе заказа: маленькая и одинаковой высоты у всех
   строк, чтобы таблица не прыгала. */
.items-table .item-thumb { width: 46px; padding-right: 10px; }
.items-table .item-thumb img {
  width: 40px; height: 52px; object-fit: cover; border-radius: 5px;
  background: var(--panel, var(--panel-4)); display: block; cursor: zoom-in;
}

/* Временный раздел беты: отделён линией и приглушён, чтобы не читался наравне
   с основными разделами CRM. Уедет вместе с бетой. */
.side-item-beta { margin-top: 10px; border-top: 1px dashed var(--line, var(--line-2)); padding-top: 12px; opacity: .62; }
.side-item-beta:hover, .side-item-beta.active { opacity: 1; }

/* Группа меню с подразделами (27.10.2026, «Аналитика»): свёрнута по умолчанию, стрелка
   поворачивается, подразделы — с отступом. Свёрнутая и закрытая группа с открытым
   подразделом подсвечена сама. */
.side-group .side-group-chevron { margin-left: auto; opacity: .55; transition: transform .15s; }
.side-group.open .side-group-chevron { transform: rotate(90deg); }
.side-sub { display: flex; flex-direction: column; gap: 3px; padding-left: 14px; }
.shell.nav-collapsed .side-sub { padding-left: 0; align-items: center; }
.shell.nav-collapsed .side-group .side-group-chevron { display: none; }
.side-item-beta .label { font-size: 13px; }
.beta-mark {
  margin-left: auto; font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line, var(--line-2));
  border-radius: 4px; padding: 1px 4px;
}

/* ── Отладка Гермеса (временный раздел) ─────────────────────────────────── */
.trace-list { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.trace-card { background: var(--panel, var(--panel-4)); border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm); }
.trace-card .fold-head { margin: 0; padding: 0; }
.trace-card .fold-toggle {
  display: flex; align-items: center; gap: var(--gap); width: 100%;
  padding: 11px 14px; background: none; border: 0; cursor: pointer; text-align: left;
}
.trace-title { font-weight: 600; font-size: 14px; }
.trace-when { margin-left: auto; font-size: 12px; white-space: nowrap; }
/* Исход виден до раскрытия: по цвету полосы слева понятно, где искать ошибку. */
.trace-card { border-left: 3px solid var(--line, var(--line-2)); }
.trace-card.trace-applied { border-left-color: var(--c-7fae8c-l); }
.trace-card.trace-review { border-left-color: var(--c-d0a43f-l); }
.trace-card.trace-unchanged { border-left-color: var(--c-c9c7bf-l); }
.trace-card.trace-refused, .trace-card.trace-error { border-left-color: var(--c-c47a63-l); }
.trace-mark { font-size: 11px; }
.trace-mark-review { background: var(--c-f6ecd4-s); color: var(--c-7a5c12-t); }
.trace-mark-refused, .trace-mark-error { background: var(--c-f4e2dc-s); color: var(--c-8f4028-t); }

.trace-card .fold-body { padding: 4px 14px 14px; }
/* Кнопка «Открыть «Ревью»» без причины лежит прямо в теле после шагов. */
.trace-card .fold-body > .btn { margin-top: 7px; }
.trace-step { display: grid; grid-template-columns: 168px 1fr; gap: var(--gap); padding: 7px 0; align-items: start; }
.trace-step + .trace-step { border-top: 1px dashed var(--line, var(--line-2)); }
.trace-step-label { font-size: 12px; color: var(--muted); padding-top: 2px; }
.trace-step-body { font-size: 13px; line-height: 1.5; }

.trace-msg { border-left: 2px solid var(--line, var(--line-2)); padding: 2px 0 2px 10px; margin-bottom: 8px; }
.trace-msg.out { border-left-color: var(--c-b9cdbf-l); }
.trace-msg-meta { display: flex; gap: var(--gap); font-size: 12px; color: var(--muted); }
.trace-msg-text { white-space: pre-wrap; word-break: break-word; }
.trace-msg-ru { color: var(--muted); font-size: 13px; margin-top: 2px; }
/* Файл-основание: имя и вид документа над его текстом. */
.trace-msg-file { color: var(--muted); font-size: 13px; margin-top: 6px; font-weight: 600; }

.trace-change + .trace-change { margin-top: 8px; }
.trace-change-section { font-size: 12px; color: var(--muted); margin-bottom: 3px; }
.trace-field { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; font-size: 13px; }
.trace-field-name { min-width: 150px; }
.trace-field-from { color: var(--muted); text-decoration: line-through; }
.trace-arrow { color: var(--muted); }
.trace-field-to { font-weight: 600; }
.trace-line { font-size: 13px; line-height: 1.5; }
.trace-line + .trace-line { margin-top: 2px; }
.trace-untouched { color: var(--muted); }

/* Свёрнутая строка должна опознаваться без раскрытия: чей чат и о чём речь.
   Обе подписи ужимаются первыми — дату справа и метку исхода они не двигают. */
.trace-where {
  font-size: 12px; white-space: nowrap; flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis;
}
/* Суть просьбы — предложение, а не подпись: капслок и разрядка тут только
   мешают читать. Ужимается она первой: это подсказка, а не название строки. */
.trace-gist {
  font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1 1 auto; min-width: 0;
  text-transform: none; letter-spacing: 0; font-weight: 400;
}
/* Заголовок ужимается последним и не короче своего полного слова: строка
   обязана помещаться целиком, но узнаётся она именно по нему. */
.trace-title {
  flex: 0 1 auto; min-width: 24ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.trace-card .fold-toggle > .chip { flex: 0 0 auto; }
.trace-mark-rolled { background: var(--c-ece7f1-s); color: var(--tile-violet-text); }
/* Значения, которых в карточках уже нет: запись о них остаётся, сила — нет. */
.trace-changes.rolled { opacity: .55; text-decoration: line-through; }
.trace-changes.rolled .trace-field-from { text-decoration: none; }
.trace-msg-text.clamped {
  display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical;
  overflow: hidden;
}
.trace-msg-more { padding: 0; height: auto; border: 0; background: none; font-size: 12px; }
.trace-cut { margin-top: 8px; }

/* Что Гермес выучил: список правил в шапке раздела. */
.trace-rules {
  margin-top: 14px; background: var(--panel, var(--panel-4));
  border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm);
  border-left: 3px solid var(--c-b3d0be-l);
}
.trace-rules .fold-head { margin: 0; padding: 0; }
.trace-rules .fold-toggle {
  display: flex; align-items: center; gap: var(--gap); width: 100%;
  padding: 11px 14px; background: none; border: 0; cursor: pointer; text-align: left;
}
.trace-rules .fold-body { padding: 0 14px 12px; }
.trace-rule-row {
  display: flex; align-items: start; gap: var(--gap); padding: 8px 0;
  border-top: 1px dashed var(--line, var(--line-2));
}
.trace-rule-body { flex: 1; min-width: 0; }
.trace-rule-name { font-size: 13px; }
.trace-rule-src { font-size: 12px; margin-top: 2px; }

/* Экраны раздела и то, что стоит между переключателем и лентой. */
.trace-screens { margin: 0 0 10px; }
.trace-untranslated {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; margin: 0 0 10px;
}
/* Кучи причин на экране «Не смог записать»: та же карточка журнала, только
   внутри лежит список, а не шаги. */
.trace-losses { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.trace-losses > .trace-card > .fold-body { padding-top: 0; }
.trace-losses .trace-list { margin-top: 6px; }
.trace-rules-screen { display: flex; flex-direction: column; gap: var(--gap); }
.trace-rules-screen .trace-rules { margin-top: 0; }
/* Заголовок целой коробки, а не строки в свёрнутом виде: обрезать его по
   ширине нечего — переносим. */
.trace-rules > .trace-title {
  display: block; margin: 0; padding: 11px 14px 4px; font-size: 13px;
  min-width: 0; overflow: visible; white-space: normal;
}
.trace-sections { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 720px) {
  .trace-step { grid-template-columns: 1fr; gap: 2px; }
  .trace-field-name { min-width: 0; }
  .trace-gist { display: none; }
}

/* Кликабельные номера и названия. Ни цвета, ни подчёркивания — по просьбе:
   текст остаётся текстом, о том, что он ведёт в карточку, говорит курсор и
   подсказка. Обводка появляется только при переходе с клавиатуры. */
/* Внешняя ссылка позиции заказа на 1688 — значком рядом с артикулом: сам
   артикул ведёт в карточку товара CRM (29.08.2026), и две двери не должны
   притворяться одной. */
.item-1688 { margin-left: 6px; text-decoration: none; color: var(--muted); font-size: 12px; }
.item-1688:hover { color: var(--ink-green); }
.item-link-input { width: 100%; min-width: 140px; font-size: 12px; padding: 3px 6px; }

/* Кликабельная сущность: при наведении подсвечивается, но НЕ подчёркивается.
   Решение пользователя 30.08.2026. Без подсветки ссылка была неотличима от
   обычного текста — о том, что имя артикула открывает его карточку, узнать
   было неоткуда. */
.entity-link {
  cursor: pointer;
  border-radius: 4px;
  padding: 0 2px; margin: 0 -2px;
  text-decoration: none;
}
.entity-link:hover { background: var(--accent-dim); color: var(--ink-green); }
.entity-link:focus-visible { outline: 2px solid var(--accent, var(--c-0e5d59-l)); outline-offset: 2px; border-radius: 3px; }

/* ── перевод китайского по нажатию ─────────────────────── */

/* Кнопка стоит у каждого китайского куска во всех разделах. Мелкая и
   приглушённая нарочно: мест, где она появляется, много, и она не должна
   спорить с самим текстом. Сам по себе перевод не запускается — только
   нажатием, и оригинал остаётся на месте. */
.nt-btn {
  display: inline-block;
  /* У обрезающего узла кнопка встаёт следующей строкой — и в колонке из
     `flex`/`grid` растянулась бы на всю ширину карточки. Ширина по тексту и
     прижатие к началу строки нужны именно там. */
  align-self: start;
  justify-self: start;
  width: fit-content;
  max-width: 100%;
  margin-left: 6px;
  padding: 0 5px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.5;
  font-weight: 500;
  color: var(--muted);
  background: var(--panel-2);
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
}
.nt-btn:hover { color: var(--text); border-color: var(--accent); }
.nt-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nt-btn[data-busy="1"] { cursor: default; opacity: .6; }

/* Перевод встаёт под оригиналом, а не вместо него: сверить с исходником иначе
   будет нечем. Отдельной строкой — так он не сливается с китайским. */
.nt-ru {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: .92em;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ── список горячих клавиш ─────────────────────────────── */

.keys-list { display: grid; gap: 8px; }
.keys-row { display: grid; grid-template-columns: 92px 1fr; gap: 12px; align-items: baseline; }
.keys-row kbd {
  font-family: var(--font-display);
  font-size: 13px;
  text-align: center;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 7px;
  background: var(--panel-2);
  color: var(--text);
}
.keys-row span { font-size: 13px; color: var(--muted); }

/* Строка свежести открывает итог последнего разбора — если он был. */
.brand-sub.has-digest { cursor: pointer; text-decoration-line: underline; text-decoration-style: dotted; text-underline-offset: 3px; }

/* Строка, которую уже убрали с экрана, но ещё можно вернуть тостом. */
.row-removing { opacity: .35; pointer-events: none; }

/* «Сохранено» вместо кнопки «Сохранить»: поля уходят на сервер сами. */
.save-mark {
  font-size: 11px;
  color: var(--ink-green);
  opacity: 0;
  transition: opacity .18s ease;
}
.save-mark.on { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .save-mark { transition: none; } }

/* «Выполнить всю группу» — та же галочка, что и в строке, правее счётчика. */
.task-lane-all { margin-left: auto; margin-top: 0; }

/* ── выделение пачки заказов на доске ──────────────────── */

.card.picked {
  outline: 2px solid var(--gossamer-green);
  outline-offset: 1px;
}
/* Над доской плашка выделения висит поверх: доска — ряд колонок, и обычная
   плашка встала бы в него ещё одной колонкой. */
.bulkbar.floating {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  z-index: 30; margin-top: 0;
  box-shadow: 0 6px 20px var(--c-rgba-80-66-48-16-s);
}
body.order-open .bulkbar.floating { left: calc(50% - 210px); }
/* Кнопка «Выбрать» и галочки карточек (03.11.2026): выбор без ⌘ — и на касании. Галочка
   видна, когда выбор включён или карточка отмечена ⌘-щелчком. */
.board-pick { order: 10; margin-left: auto; }
.board-pick.on { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-ink); }
#board .card { position: relative; }
.card-pick {
  display: none; position: absolute; top: 8px; right: 8px; width: 18px; height: 18px;
  border: 1.5px solid var(--muted); border-radius: 5px; background: var(--panel);
  align-items: center; justify-content: center; pointer-events: none;
}
.board.picking .card { cursor: pointer; }
.board.picking .card-pick, .card.picked .card-pick { display: inline-flex; }
.card.picked .card-pick { background: var(--accent); border-color: var(--accent); }
.card.picked .card-pick::after {
  content: ''; width: 5px; height: 9px; margin-top: -2px;
  border: solid var(--on-accent-strong); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
/* В режиме выбора касание по номеру или названию на карточке тоже отмечает её, а не открывает
   (04.11.2026: и на доске образцов). */
.board.picking .card .entity-link { pointer-events: none; }
/* «Выбрать» в «Задачах» (04.11.2026): та же галочка у строк плана и просьб фабрик. */
.task-board.task-picking .tw-item[data-task-id]:not(.tw-group):not(.done),
.task-board.task-picking .task-factory-block .task-row[data-task-id] { cursor: pointer; position: relative; }
.task-bulk-box {
  display: none; position: absolute; top: 8px; right: 8px; width: 18px; height: 18px;
  border: 1.5px solid var(--muted); border-radius: 5px; background: var(--panel);
  align-items: center; justify-content: center; pointer-events: none; z-index: 1;
}
.task-board.task-picking .task-bulk-box, .picked > .task-bulk-box { display: inline-flex; }
.tw-item.picked, .task-row.picked { outline: 2px solid var(--gossamer-green); outline-offset: 1px; }
.picked > .task-bulk-box { background: var(--accent); border-color: var(--accent); }
.picked > .task-bulk-box::after {
  content: ''; width: 5px; height: 9px; margin-top: -2px;
  border: solid var(--on-accent-strong); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.task-board.task-picking .tw-give, .task-board.task-picking .task-answer-toggle { visibility: hidden; }
.task-board.task-picking .entity-link { pointer-events: none; }
.task-bulkbar select { max-width: 200px; }

/* Выполненные живут на своей вкладке и занимают ту же ширину, что и активные:
   узкой колонки, ради которой текст обрезался тремя строками, больше нет. */
.task-lane.done .task-row .task-text { overflow-wrap: anywhere; }

/* ── продукты: список слева, досье справа ──────────────── */

/* Раздел отдаёт «Продуктам» всю высоту, а прокручиваются колонки по
   отдельности: список слева и досье справа. Иначе, уехав по списку вниз,
   человек уводил за собой и карточку — она оказывалась выше экрана. */
.section-view:has(.card-split) {
  display: flex; flex-direction: column; overflow: hidden; padding-bottom: 18px;
}
.card-split { display: grid; grid-template-columns: 306px minmax(0, 1fr); gap: 14px; flex: 1; min-height: 0; }
.card-list {
  background: var(--panel); border-radius: var(--radius); padding: 8px;
  display: flex; flex-direction: column; gap: 2px;
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s); overflow-y: auto;
}
/* Заголовок группы — кнопка: группы свёрнуты, пока их не раскроют. */
.card-group {
  display: flex; align-items: center; gap: 6px;
  width: 100%; padding: 8px 8px 7px; margin-top: 4px;
  border: none; background: transparent; border-radius: var(--radius-sm);
  font: inherit; text-align: left; cursor: pointer;
}
.card-group:hover { background: var(--panel-2); }
.card-group:focus-visible { outline: 2px solid var(--ink-green); outline-offset: -2px; }
.card-group-arrow {
  display: inline-flex; color: var(--muted); flex: 0 0 auto;
  transition: transform .14s ease;
}
.card-group.open .card-group-arrow { transform: rotate(90deg); }
.card-group-pill {
  border-radius: 999px; padding: 3px 10px;
  font-size: 12px; font-weight: 600; letter-spacing: 0; white-space: nowrap;
}
.card-group .lane-count { margin-left: 0; }
.card-group-body { display: flex; flex-direction: column; gap: 2px; }
/* Категории внутри этапа (11.11.2026): подпункты «Все», «Джинсы»… с отступом под этапом. */
.card-subgroup { margin-top: 0; padding: 5px 8px 5px 22px; font-size: 13px; }
.card-subgroup-name { font-weight: 600; color: var(--text-2); }
.card-subgroup-body { padding-left: 14px; }
.card-category { min-width: 140px; }
.card-category-input { width: 100%; }
.card-category-error { color: var(--danger); font-size: 12px; min-height: 16px; }
@media (prefers-reduced-motion: reduce) { .card-group-arrow { transition: none; } }
.card-row {
  display: flex; align-items: center; gap: var(--gap); padding: 7px 9px;
  border: none; border-radius: var(--radius-sm); background: transparent;
  font: inherit; text-align: left; cursor: pointer; width: 100%;
}
/* Товар на «Образце», который уже мерили или переделывают (11.11.2026): ниже в группе, фон чуть зеленее. */
.card-row.tried { background: color-mix(in srgb, var(--ok) 30%, transparent); }
:root[data-theme="dark"] .card-row.tried { background: color-mix(in srgb, var(--ok) 14%, transparent); }
.card-row:hover { background: var(--panel-2); }
/* Открытый товар — бежевый фон и тёмная полоса слева, а не зелёный (11.11.2026, её «да, сделай»):
   зелёным он сливался с примеренными, и БЧ8 выглядел «примеренным». */
.card-row.on { background: var(--line); box-shadow: inset 3px 0 0 var(--ink-green); }
.card-row:focus-visible { outline: 2px solid var(--ink-green); outline-offset: -2px; }
.card-thumb {
  width: 30px; height: 38px; border-radius: 6px; background: var(--c-f2ede2-s);
  flex: 0 0 auto; overflow: hidden;
}
.card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-row-main { min-width: 0; flex: 1; }
.card-row-name { font-family: var(--font-display); font-size: 14px; }
.card-row-sub {
  font-size: 11px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }

.card-detail { overflow-y: auto; }
/* ДОСЬЕ ЮНИТА МЕРИТ СВОЁ МЕСТО, А НЕ ОКНО (17.09.2026).
   Одна и та же разметка стоит в двух разных по ширине местах: правой колонкой
   «Продуктов» (там под неё метров 700) и боковой панелью поверх раздела (404).
   Переносы при этом были описаны через `@media (max-width: 1080px)` — то есть
   по ОКНУ. На большом экране панель получала вёрстку широкой колонки: две
   колонки досье по 170 px, внутри них ещё две колонки показателей по 80,
   шесть кнопок этапов в один ряд — и текст лез за края.
   Поэтому `.dossier` объявлен контейнером, а все его переносы считаются от
   собственной ширины. Панель, колонка и узкое окно чинятся одним правилом.
   `overflow-wrap: anywhere` — страховка на длинное имя артикула без пробелов:
   он переносится внутри слова вместо того, чтобы вылезти за рамку. */
.dossier {
  container-type: inline-size; container-name: dossier;
  background: var(--panel); border-radius: var(--radius); padding: 18px 20px;
  display: flex; flex-direction: column; gap: 14px;
  box-shadow: 0 1px 2px var(--c-rgba-80-66-48-06-s);
  min-width: 0; overflow-wrap: anywhere;
}
/* Поле ввода несёт собственную ширину (по умолчанию ~20 знаков) и в узкой
   колонке распирало строку: цена, причина отказа, дата в ленте. */
.dossier input, .dossier select, .dossier textarea { max-width: 100%; min-width: 0; }
.dossier-top { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; }
.dossier-name { font-family: var(--font-display); font-size: 24px; min-width: 0; }
.status-pill[data-stage="development"] { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.status-pill[data-stage="sample"] { background: var(--tile-rose-bg-3); color: var(--ink-rose); }
.status-pill[data-stage="testing"] { background: var(--tile-yellow-bg); color: var(--ink-yellow); }
.status-pill[data-stage="active"] { background: var(--accent-dim); color: var(--ink-green); }
/* «Сформировать скрипт» стоит в шапке досье, но не спорит с названием:
   прижимаем к правому краю, чтобы этап и номер остались рядом с именем. */
.dossier-script { margin-left: auto; flex: 0 0 auto; }
/* «Выгрузить образец» встаёт вплотную за «Скриптами» (01.10.2026). */
.dossier-export { flex: 0 0 auto; }

/* Решение по примерке правится прямо в окне: моноширинный текст, чтобы
   «???» и «?» стояли ровно и было видно, где ещё не заполнено. */
.fitting-script {
  width: 100%;
  min-height: 300px;
  font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
}

/* Полоса этапов — она же переключатель. */
/* Кнопок в полосе шесть. В узкой панели шесть колонок по 55 px — это
   обрезанные слова, поэтому полоса переносится рядами, а не сжимается. */
.stage-path { display: flex; gap: 6px; flex-wrap: wrap; }
.stage-step {
  flex: 1 1 104px; min-width: 0; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--panel-6); color: var(--muted); border: 1px solid transparent;
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .12s ease, transform .12s ease;
}
.stage-step.done { background: var(--accent-dim); color: var(--ink-green); }
.stage-step.now { background: var(--tile-yellow-bg); color: var(--ink-yellow); border-color: var(--c-e6d9a3-l); }
.stage-step:hover:not(:disabled) { border-color: var(--gossamer-green); transform: translateY(-1px); }
.stage-step:disabled { cursor: default; }
.stage-name { font-size: 10px; text-transform: uppercase; letter-spacing: .4px; }
/* Дня нет — строка пустая (прочерк убран 20.10.2026), но место под неё
   держится: иначе кнопки полосы, перенесённой рядами, были бы разной высоты. */
.stage-when { font-size: 12px; font-weight: 700; margin-top: 4px; min-height: 1.45em; }
/* «Замена» и «Отложено» — не этапы пути, а свои группы раздела. Пунктир и
   приглушённый фон говорят об этом без подписи: они стоят в одном ряду с
   этапами, но чередой перехода не являются. */
.stage-step.stage-repl { border-style: dashed; border-color: var(--orchid-petal); }
.stage-step.stage-repl.now { background: var(--c-fbf9fd-s); color: var(--tile-violet-text); }
.stage-step.stage-park { border-style: dashed; }
/* Аудит 03.11.2026, Р-В-06: плитки равные. Влезают все — одним рядом; не влезают —
   по три в ряд (по две в совсем узкой панели), последняя не тянется на всю строку. */
.stage-path { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 6px; }
@container dossier (max-width: 700px) {
  .stage-path { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@container dossier (max-width: 330px) {
  .stage-path { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) { .stage-step { transition: none; } }
/* Одна плашка этапа на всю ширину карточки (11.11.2026); остальные этапы — списком по нажатию. */
.stage-box { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.stage-current {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  padding: 10px 14px; border-radius: var(--radius-sm); font: inherit; text-align: left; cursor: pointer;
  background: var(--tile-yellow-bg); color: var(--ink-yellow); border: 1px solid var(--c-e6d9a3-l);
  transition: border-color .12s ease;
}
.stage-current.parked { background: var(--panel-6); color: var(--muted); border-style: dashed; border-color: var(--line); }
.stage-current:hover, .stage-current.open { border-color: var(--gossamer-green); }
.stage-current-name { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; }
.stage-current-when { font-size: 12px; margin-top: 2px; }
.stage-current-change { font-size: 12px; white-space: nowrap; opacity: .8; }
.stage-menu[hidden] { display: none; }

/* Замена — работа над действующим артикулом, вложенная в его же карточку. */
.replacement {
  border: 1px dashed var(--orchid-petal); border-radius: var(--radius-sm);
  padding: 13px 14px; background: var(--c-fbf9fd-s);
  display: flex; flex-direction: column; gap: var(--gap);
}
.replacement.done { opacity: .72; border-style: solid; }
/* Закрытая замена — свёрткой (09.11.2026): заголовок со стрелкой, открытая —
   с прежними отступами между частями. */
details.replacement.done:not([open]) { gap: 0; }
details.replacement.done > summary { cursor: pointer; list-style: none; }
details.replacement.done > summary::-webkit-details-marker { display: none; }
details.replacement.done > summary strong::before { content: '▸ '; }
details.replacement.done[open] > summary strong::before { content: '▾ '; }
details.replacement.done:hover { opacity: 1; }
.replacement-head { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; }
.replacement-head strong { font-size: 13px; color: var(--tile-violet-text); }
.replacement-chips { display: flex; gap: 6px; flex-wrap: wrap; }
/* Заметки и записи истории приходят многострочными — нумерованный список
   правок, реплика в несколько абзацев. Без этого они слипались в один
   сплошной кусок текста, хотя в старых разделах читались по пунктам. */
.replacement-notes { font-size: 13px; white-space: pre-wrap; }

.card-warn {
  background: var(--tile-rose-bg-2); color: var(--ink-rose);
  border-radius: var(--radius-sm); padding: 11px 13px; font-size: 13px;
}

/* Чек-лист закрыт, а карточка ещё на тестировании: последний шаг делает
   человек, и кнопка для него стоит там же, где список. */
.card-ready {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  background: var(--tile-green-bg); color: var(--tile-green-text);
  border-radius: var(--radius-sm); padding: 11px 13px; font-size: 13px;
}

/* Две колонки, пока обе шире 236 px, иначе одна. `min(…, 100%)` вместо голых
   пикселей: в контейнере уже 236 колонка не ужимается и вылезает за край. */
.dossier-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(236px, 100%), 1fr));
}
.dossier-grid > * { min-width: 0; }
.blk { font-size: 10px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--muted); }

.price-reductions { display: flex; flex-direction: column; gap: 6px; }
.price-reduction {
  border: 1px solid var(--c-bfd8c7-l); border-radius: var(--radius-sm); padding: 10px 12px;
  background: var(--c-eef6f0-s); color: var(--tile-green-text);
}
.price-reduction-main { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; }
.price-reduction-main strong { font-size: 13px; }
.price-reduction-delta {
  border-radius: 999px; padding: 2px 7px; background: var(--c-d7eadc-s);
  color: var(--c-2f6941-t); font-size: 12px; font-weight: 700;
}
.price-reduction .muted { margin-top: 3px; font-size: 12px; }
/* Где снижение в бонусе (15.10.2026): одной строкой под снижением. */
.price-reduction-bonus { margin-top: 4px; font-size: 12px; font-weight: 600; color: var(--c-2f6941-t); }

.card-timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.card-timeline li { display: flex; gap: var(--gap); align-items: baseline; font-size: 13px; }
.tl-date { color: var(--muted); flex: 0 0 128px; white-space: nowrap; }
.card-timeline li { flex-wrap: wrap; }
.tl-text { flex: 1; min-width: 0; white-space: pre-wrap; }
.tl-src { font-size: 11px; color: var(--c-a89e8d-t); white-space: nowrap; }

/* Правка записи прямо в строке ленты (17.09.2026).
   Строка, которую можно поправить, отзывается на наведение — иначе щелчок по
   ней нечем предугадать. Выведенные строки ленты («уехал к модели») этого
   класса не получают и выглядят как раньше. */
.card-timeline li.tl-editable { cursor: text; border-radius: 6px; margin: -2px -6px; padding: 2px 6px; }
.card-timeline li.tl-editable:hover { background: var(--panel-2); }
.card-timeline li.tl-editing {
  align-items: flex-start; background: var(--panel-2);
  border-radius: 6px; margin: -3px -6px; padding: 3px 6px;
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.tl-date-input { flex: 0 0 128px; font-size: 13px; padding: 2px 6px; }
.tl-text-input { flex: 1; min-width: 0; font-size: 13px; padding: 3px 6px; resize: vertical; }
/* «Убрать запись» — маленькой ссылкой справа от правки, не кнопкой: действие редкое. */
.card-timeline li.tl-editing .tl-remove { flex: 0 0 auto; align-self: center; font-size: 12px; white-space: nowrap; }

/* Раскладка САМОГО раздела считается по окну — это правильно: слева список
   карточек, и решает, помещается ли он рядом с досье, именно окно. */
@media (max-width: 1080px) {
  .card-split { grid-template-columns: minmax(0, 1fr); }
}

/* Досье в узком месте описано в конце файла, после всех правил, которые оно
   переопределяет: запрос к контейнеру веса селектору не добавляет, и правило
   `.card-sample-sub` из «образцов внутри карточки» ниже перебивало бы его. */

/* ── новый групповой чат ─────────────────────────────────────────────────────
   По названию группы вспомнить, кто это, невозможно, поэтому вопрос идёт
   вместе с приметами чата и последними репликами. */
.ci-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 10px;
}
.ci-preview {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 168px;
  overflow-y: auto;
  padding: 8px 10px;
  margin-bottom: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  font-size: 12px;
}
.ci-preview:empty { display: none; }
.ci-meta:empty { display: none; }
.ci-msg { display: flex; gap: 8px; }
.ci-msg .ci-who { flex: none; color: var(--muted); }
.ci-msg.out .ci-who { color: var(--ink-green); }
.ci-kinds { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 4px; }
.ci-kind {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.ci-kind[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-dim); }

/* «Похоже, эта фабрика у нас уже есть»: строка совпадения — она же кнопка
   ответа. Того же приёма, что плитки в «Ревью»: нажал на саму вещь, а не
   на номер рядом с ней. */
.ci-matches { display: flex; flex-direction: column; gap: 6px; margin: 12px 0 4px; }
.ci-matches-head { font-size: 12px; color: var(--muted); }
.ci-match {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.ci-match:hover { border-color: var(--accent); }
.ci-match[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-dim); }
.ci-match-name { font-weight: 600; white-space: nowrap; }
.ci-suggest { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; margin: -4px 0 4px; }
.ci-suggest .hint { flex: 1 1 auto; }
.ci-match-why { flex: 1 1 100%; font-size: 12px; color: var(--muted); }

/* Пометка «заменяется» на действующем товаре: по артикулу идёт работа.
   Она же ссылка — открывает карточку и показывает саму замену. */
.card-row-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 7px; min-width: 0; }
/* Имя не сжимается мимо самого себя (аудит 20.10.2026: «Б» вместо «ББФ» при двух
   плашках) — плашки уходят на вторую строку; очень длинное режется троеточием. */
.card-row-name > span:first-child { flex: 0 0 auto; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-repl {
  flex: 0 0 auto;
  font-family: var(--font-display); font-size: 10px;
  border: 1px dashed var(--orchid-petal); border-radius: 999px;
  padding: 1px 7px; color: var(--tile-violet-text); background: var(--c-fbf9fd-s);
  cursor: pointer;
}
.card-repl:hover { background: var(--tile-violet-bg-3); border-style: solid; }
/* «драфт 2» и «отложено» в строке товара (13.10.2026): прежний драфт в «Архив»
   своей строкой не уходит, отложенный товар стоит в «Архиве» — пометка говорит
   об этом в самой строке. */
.card-draft, .card-parked {
  flex: 0 0 auto;
  font-family: var(--font-display); font-size: 10px;
  border-radius: 999px; padding: 1px 7px;
}
.card-draft { color: var(--tile-yellow-text); background: var(--tile-yellow-bg); border: 1px solid var(--tile-yellow-line); }
.card-parked { color: var(--text-3); background: var(--panel-3); }
.replacement.just-came { box-shadow: 0 0 0 2px var(--orchid-petal); }

/* Заголовок истории с кнопкой записи этапа. */
.hist-head { display: flex; align-items: center; gap: var(--gap); }
.hist-add { margin-left: auto; letter-spacing: 0; text-transform: none; }
/* «Замена» в ленте помечена отдельно: это работа над тем же артикулом,
   а не запись из другой карточки. */
.tl-src.tl-repl { color: var(--tile-violet-text); background: var(--tile-violet-bg-3); border-radius: 999px; padding: 1px 7px; }

/* ── оценка решения агента в «Отладке Гермеса» ─────────── */

.trace-verdict {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: var(--gap);
}
/* У ассистентки кнопок оценки нет (учит владелица): пустой блок не рисует черту. */
.trace-verdict:empty { display: none; }
.trace-verdict-head { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.trace-verdict-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* Переключатель «неразобранное / оценённое» на экране решений. */
.trace-scope { margin: 0 0 10px; }

/* Крестик «убрать запись»: тихий, пока на карточку не навели. Оценкой он не
   является, поэтому и не должен спорить за внимание с «Верно» и «Неверно». */
.trace-drop {
  margin-left: auto; flex: none; width: 24px; height: 24px; line-height: 1;
  border: 1px solid transparent; border-radius: 6px; background: transparent;
  color: var(--muted); cursor: pointer; opacity: 0; transition: opacity .12s;
}
.trace-card:hover .trace-drop, .trace-drop:focus-visible { opacity: 1; }
.trace-drop:hover { color: var(--text); border-color: var(--line); }

.trace-verdict-clear { background: transparent; border-color: transparent; color: var(--muted); }
.trace-verdict-clear:hover { color: var(--text); border-color: var(--line); }
/* Метка на свёрнутой строке: видно, что запись уже оценена. */
.trace-verdict-mark {
  border-radius: 999px; padding: 1px 8px; font-size: 11px; white-space: nowrap;
}
.trace-verdict-mark.correct { background: var(--accent-dim); color: var(--ink-green); }
.trace-verdict-mark.wrong { background: var(--tile-rose-bg-2); color: var(--ink-rose); }
.trace-rule-text {
  background: var(--panel-5); border-radius: var(--radius-sm); padding: 9px 11px;
  font-size: 13px; white-space: pre-wrap;
}
.trace-correction { display: flex; flex-direction: column; gap: 4px; }
.trace-correction-text {
  background: var(--tile-rose-bg-2); color: var(--ink-rose); border-radius: var(--radius-sm); padding: 9px 11px;
  font-size: 13px; white-space: pre-wrap;
}
.trace-correction-form { display: flex; flex-direction: column; gap: 8px; }
.trace-correction-form textarea { width: 100%; }

/* Выбор, куда переместить карточку. */

/* Незаполненное поле анкеты: видно, чего не хватает, но глаз оно не тянет —
   это подсказка, а не проблема. */
.fact-row.fact-missing .fact-value { opacity: .55; font-style: italic; }
.fact-row.fact-missing .fact-input { width: 100%; }

/* Окно разбора: строка производства, у которого нового нет, — приглушена.
   Она не ошибка, просто в этот раз читать нечего. */
.plan-stale { opacity: .6; }
.plan-reread { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }

/* Отметки об оплате внутри карточки заказа: справка, а не рабочее поле —
   поэтому они мельче и стоят под причиной простоя. */
.pay-marks { gap: 16px; font-size: 13px; color: var(--muted); }
.pay-marks label { display: inline-flex; align-items: center; gap: 6px; }

/* «Примерка» в строке списка карточек: видна, но не спорит с названием. */
.card-row-script { flex: none; margin-left: auto; }

/* Упоминание, которое уже стало основанием карточки: видно, что оно не новое. */
.msg.msg-linked { opacity: .68; }

/* Деньги на этапе воронки: цифра справочная, поэтому мельче названия этапа. */

/* Сколько дошло: блок под составом заказа. Расхождение подсвечиваем — это
   разговор с фабрикой о деньгах, а не справка. */
.items-received { margin-top: 12px; }
.hint.items-gap { color: var(--ink); font-weight: 600; }

/* Сравнение анкет: таблица широкая, поэтому едет по горизонтали внутри себя,
   а не растягивает окно. */
.scroll-x { overflow-x: auto; }
/* ── сравнение анкет фабрик ──────────────────────────────
 *
 * На живых данных это 25 колонок и 14 строк, а в одном ответе 1718 символов
 * ссылок. Свободная ширина колонок растягивала таблицу так, что сравнивать
 * приходилось, прокручивая её в обе стороны и теряя из виду и вопрос, и чей
 * это столбец. Поэтому ширины фиксированные, шапка и первая колонка
 * закреплены, а длинное значение сворачивается, а не раздвигает столбец.   */
.anketa-bar { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.anketa-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.anketa-chips {
  display: flex; flex-wrap: wrap; gap: 4px;
  max-height: 92px; overflow-y: auto;
  padding: 6px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
}
/* Прокрутка тут одна на обе оси и живёт на этом слое: `position: sticky`
   у шапки и первой колонки считается относительно ближайшего прокручиваемого
   предка, и без него закрепление молча не работало бы. */
.anketa-scroll {
  overflow: auto;
  /* Подпись под таблицей должна оставаться в окне: высота считается от
     экрана за вычетом шапки, полосы кнопок и самой подписи. */
  max-height: min(calc(100vh - 300px), 640px);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.anketa-table {
  border-collapse: separate; border-spacing: 0;
  table-layout: fixed; width: max-content; min-width: 100%;
  font-size: 12px;
}
/* Ширина считается на месте, под число колонок: мало колонок — занимают всё
   окно, много — ужимаются до читаемого минимума. Запасное значение стоит на
   случай, когда переменную ещё не успели проставить. */
.anketa-col-q { width: 140px; }
.anketa-col-a { width: var(--anketa-col, 168px); }
@media (max-width: 900px) { .anketa-col-q { width: 116px; } }
.anketa-table th, .anketa-table td {
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 5px 7px; vertical-align: top; text-align: left;
  overflow-wrap: anywhere;
}
.anketa-table th:last-child, .anketa-table td:last-child { border-right: none; }
.anketa-table tr:last-child td, .anketa-table tr:last-child th { border-bottom: none; }

/* Закреплённая шапка: имя фабрики видно, куда бы ни уехала прокрутка. */
.anketa-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel-2); font-weight: 600;
}
.anketa-head-name {
  font-weight: 700;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Закреплённая первая колонка: вопрос виден при прокрутке вправо. */
.anketa-table th.anketa-q {
  position: sticky; left: 0; z-index: 1;
  background: var(--panel); font-weight: 600; white-space: normal;
  /* Тень справа: при прокрутке вбок под закреплённой колонкой всегда торчит
     край наполовину уехавшего столбца. С тенью это читается как «содержимое
     проходит под колонкой», а без неё — как поехавшая вёрстка. */
  box-shadow: 3px 0 6px -3px var(--c-rgba-80-66-48-22-s);
}
.anketa-table tbody tr:nth-child(even) th.anketa-q,
.anketa-table tbody tr:nth-child(even) td { background: var(--panel-2); }
.anketa-table tbody tr:hover td, .anketa-table tbody tr:hover th.anketa-q {
  background: var(--accent-dim);
}
/* Угол — на пересечении двух закреплений, поэтому слой выше обоих. */
.anketa-table th.anketa-corner { z-index: 3; background: var(--panel-2); }

/* Длинный ответ свёрнут в три строки; щелчок по ячейке разворачивает. */
.anketa-val {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; cursor: pointer;
}
.anketa-val.open { display: block; max-height: 260px; overflow-y: auto; }
.anketa-line + .anketa-line { margin-top: 2px; }
/* Кнопка «Перевести» в анкете нужна — половина ответов китайские, — но в
   таблице она должна быть мелкой, иначе съедает строку, которую свернули
   до трёх. */
.anketa-table .nt-btn { font-size: 10px; padding: 0 4px; margin-left: 3px; }
.anketa-table .nt-ru { font-size: 11px; }

/* Широкое окно — только для таблиц. Формы в нём читались бы хуже. */
.modal-wide { width: min(1580px, calc(97vw - var(--chat-room))); max-height: 92vh; }
.modal-wide .modal-body { padding: 12px 14px; }

/* Деньги и условия оплаты в строке фабрики: справка под названием. */
.split-money { display: flex; gap: 8px; align-items: baseline; font-size: 12px; width: 100%; }
.split-money-sum { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── образцы внутри карточки товара ───────────────────────────────────────
   Товар один, образцов у него бывает несколько — по одному на фабрику.
   Строка образца устроена как строка карточки в списке: снимок, номер,
   производство и цена. Ведущий помечен рамкой слева. */
.card-samples { display: flex; flex-direction: column; gap: 8px; }
.card-sample {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2); min-width: 0;
}
/* «читать по нему» — кнопка, и сжиматься ей нельзя: в узкой панели её текст
   ложился в три строки по одному слову. Переносится целиком под строку. */
.card-sample > .btn { flex: 0 0 auto; margin-left: auto; }
.card-sample.leading { border-left: 3px solid var(--accent); }
/* Строка образца открывает его форму — курсор об этом говорит. */
.card-sample { cursor: pointer; }
/* Список образцов внутри формы «Изменить»: у каждого своя строка-кнопка. */
.form-samples { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 6px; }
.form-sample-row { justify-content: flex-start; text-align: left; }
.card-sample:hover { border-color: var(--accent); }
/* Уже примеренный образец (11.11.2026): ниже в списке и чуть зеленее фон — тихо, без плашки. */
.card-sample.fitted { background: color-mix(in srgb, var(--ok) 14%, var(--panel-2)); }
/* Обложки в строке образца больше нет (16.09.2026): главная фотография у юнита
   одна и стоит выше, а шесть её копий подряд ничего не добавляли. Собственные
   снимки образца — брак, ткань, версия — живут в его панели. */
.card-sample-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.card-sample-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-sample-code { font-weight: 700; font-variant-numeric: tabular-nums; }
/* «По нему карточка» — не решение о производстве, а якорь отображения.
   Поэтому и выглядит тихо: это подпись, а не награда. */
.card-sample-lead {
  font-size: 11px; color: var(--muted); text-transform: lowercase;
  border: 1px dashed var(--line); border-radius: 4px; padding: 0 5px;
}
.card-sample-sub {
  font-size: 13px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.status-pill.sm { font-size: 11px; padding: 1px 7px; }
/* Статус образца своими цветами: коды у него свои, не заказные. */
.status-pill[data-sample="sample"] { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.status-pill[data-sample="sample_ok"] { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.status-pill[data-sample="fitting"] { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.status-pill[data-sample="done"] { background: var(--c-ece9e3-s); color: var(--c-55504a-t); }

/* Мультивыбор товаров в окне «Новые образцы». */
.nsm-label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.nsm-card {
  width: 100%; padding: 7px 10px; margin-bottom: 8px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--ink); font: inherit; font-size: 13px;
}
.nsm-cards {
  max-height: 260px; overflow: auto; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
}
.nsm-card-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 8px;
  align-items: center; padding: 7px 10px; border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.nsm-card-row:last-child { border-bottom: 0; }
.nsm-card-row:hover { background: var(--panel-2); }
.nsm-card-row input { margin: 0; }
/* Сколько образцов одного товара: счётчик виден только у отмеченного. */
.nsm-card-row:not(.on) .nsm-qty { display: none; }
.nsm-qty {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
}
.nsm-qty.many { border-color: var(--ink); }
.nsm-qty-btn {
  width: 22px; height: 22px; border: 0; border-radius: 999px; padding: 0;
  background: none; color: var(--ink); font: inherit; font-size: 15px; line-height: 1;
  cursor: pointer;
}
.nsm-qty-btn:hover:not(:disabled) { background: var(--panel-2); }
.nsm-qty-btn:disabled { color: var(--muted); opacity: .45; cursor: default; }
.nsm-qty-value { min-width: 14px; text-align: center; font-size: 13px; font-weight: 600; }
.nsm-new-chip .nsm-qty { background: transparent; border-color: currentColor; }
.nsm-new-chip .nsm-qty-btn { color: inherit; width: 18px; height: 18px; font-size: 13px; }

/* Что случалось с фабрикой: простои и перенесённые даты отгрузки.
   Список фактов, а не оценка — потому и выглядит как журнал, а не как плитки. */
.event-log { display: flex; flex-direction: column; gap: 6px; }
.event-row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.event-text { flex: 1; min-width: 0; font-size: 13px; }
.event-meta { flex: 0 0 auto; font-size: 12px; color: var(--muted); }

/* Отменённое действие в «Логе»: строка остаётся, но больше не утверждает
   того, чего в CRM уже нет. */
.log-action.log-undone, .jr-title.log-undone, .jr-card-title.log-undone {
  text-decoration: line-through; color: var(--muted);
}

/* Что вышло у каждой фабрики: утверждена или нет, по какой цене и почему. */
.card-results { display: flex; flex-direction: column; gap: 6px; }
.card-result {
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.card-result.rejected { border-color: var(--danger); }
.card-result-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-result-name { font-weight: 600; min-width: 0; }
.card-result-reason { width: 100%; min-width: 0; }

/* Выбранный, но ещё не подтверждённый ответ в «Ревью»: цифра выделяет, Enter
   подтверждает — промах по клавише больше не отвечает агенту сразу. */
.review-actions button.picked {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* «За мной»: вопрос в «Ревью», который человек взял на себя. Остаётся в списке
   и ждёт — но видно, что о нём уже помнят. */
.review-mine { display: flex; align-items: center; gap: 8px; margin: 6px 0; }

/* Куда что везти: у фабрики бывает офис и цех, оба верные. */
.address-list { display: flex; flex-direction: column; gap: 8px; }
.address-row {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.address-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.address-text { font-size: 13px; }
.address-edit { display: flex; flex-direction: column; gap: 12px; }
.address-edit-row {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.address-marks { display: flex; gap: 14px; }
.address-mark { display: flex; align-items: center; gap: 6px; font-size: 13px; }

/* Окно «Google-таблица»: ключ сервисного аккаунта, шаги настройки и путь к
   файлу ключа. Путь показываем моноширинным и с переносом по символам — его
   копируют глазами так же часто, как кнопкой. */
.sheet-step { margin-bottom: 16px; }
.sheet-step .btn { margin-top: 8px; }
.sheet-ok { font-size: 13px; font-weight: 600; }
/* Почта для доступа одной строкой с кнопкой (`sheetAccessEmail`). */
.sheet-email { margin-bottom: 16px; align-items: center; }
.sheet-steps {
  margin: 8px 0 0; padding-left: 18px;
  font-size: 12px; line-height: 1.75; color: var(--muted);
}
.sheet-path {
  margin-top: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; word-break: break-all;
}

/* Отложенный артикул: пауза объясняет себя прямо в шапке досье. */
.parked-plate {
  margin: 10px 0; padding: 10px 12px;
  border: 1px solid var(--line); border-left: 3px solid var(--hushed-violet);
  border-radius: var(--radius-sm); background: var(--panel-2); font-size: 13px;
}
.parked-plate div { margin-top: 4px; color: var(--muted); }

/* ── общий импорт файлов ─────────────────────────────────────────────────── */
/* Окно читается сверху вниз: что принесли → что прочиталось → что предлагают
   внести. Галочка слева, потому что именно её человек и ищет. */
.fi-files { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.fi-file {
  display: grid; gap: 2px; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--panel-2); border: 1px solid var(--rule);
}
.fi-preview {
  margin: 4px 0 0; padding: 6px 8px; border-radius: 6px; max-height: 88px; overflow: auto;
  background: var(--panel); border: 1px solid var(--rule);
  font: 500 11.5px/1.5 var(--mono); white-space: pre-wrap; color: var(--muted);
}
.fi-plan { display: flex; flex-direction: column; gap: 14px; margin: 4px 0 14px; }
.fi-group { border: 1px solid var(--rule); border-radius: var(--radius-sm); overflow: hidden; }
.fi-group-head {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: var(--panel-2); border-bottom: 1px solid var(--rule);
}
.fi-group-head .muted { margin-right: auto; }
.fi-item {
  display: flex; gap: var(--gap); align-items: flex-start; padding: 8px 10px;
  border-top: 1px solid var(--rule); cursor: pointer;
}
.fi-item:first-of-type { border-top: 0; }
.fi-item:hover { background: var(--panel-2); }
.fi-item input { margin-top: 3px; flex: none; }
.fi-item-text { display: grid; gap: 2px; }
/* Спорное видно сразу: галочка снята, а рядом — оба значения. */
.fi-item.conflict { background: color-mix(in srgb, var(--warn, var(--c-b8860b-s)) 8%, transparent); }
.fi-was { font-size: 13px; color: var(--warn, var(--c-b8860b-t)); }
.fi-done { font-size: 13px; color: var(--ok, var(--c-2f7d4f-t)); }
.fi-fail { font-size: 13px; color: var(--danger, var(--c-b3261e-t)); }

/* ── «Сокращение расходов» ────────────────────────────────────────────────── */
/*
 * Раздел читают ради цифр, поэтому числа в нём набраны в одну ширину и прижаты
 * вправо: колонку «Экономия ¥» сравнивают глазами по вертикали, а не читают.
 */
.savings-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--gap); margin: 14px 0 6px;
}
.savings-tile {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.savings-tile-value {
  font-family: var(--font-display); font-size: 24px; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.savings-tile-label { font-size: 12px; color: var(--muted); margin-top: 4px; }
.savings-tile-note { font-size: 11px; color: var(--muted); margin-top: 4px; font-style: italic; }
/* Плашки раздела — плитки «Аналитики» (аудит 20.10.2026): суммы с копейками
   длиннее счётчиков, поэтому плитка шире и цифра чуть мельче. */
.analytics-tiles.savings-an-tiles {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 170px), 1fr)); margin: 14px 0 6px;
}
.savings-an-tiles .analytics-tile-value { font-size: 22px; }
/* Поиск в разделе (18.10.2026): плашки ниже считают только найденное — сказать это строкой. */
.savings-found { margin: 14px 0 -6px; font-size: 13px; color: var(--muted); }

.savings-table { width: 100%; border-collapse: collapse; margin: 10px 0 18px; font-size: 13px; }
.savings-table th {
  text-align: left; font-weight: 500; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
  padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: bottom;
}
.savings-table td { padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.savings-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.savings-table tr.limit-reached td { background: var(--panel-2); }
.savings-article { font-family: var(--font-display); font-size: 14px; }
/* Строка с пробелами расчёта: не ошибка, но и не цифра — отдельным тоном. */
.savings-gap td {
  font-size: 12px; color: var(--muted); font-style: italic;
  padding-top: 0; border-bottom: 1px solid var(--line);
}
.savings-total td { font-weight: 600; border-top: 2px solid var(--line); border-bottom: none; }

.savings-bar {
  height: 4px; background: var(--panel-2); border-radius: 2px;
  margin-top: 4px; overflow: hidden;
}
.savings-bar-fill { height: 100%; background: var(--accent, var(--c-7a9-s)); border-radius: 2px; }

/* ── вкладка «Остаток лимита» (17.09.2026) ───────────────
   Сам «Бонус в ожидании» — плиткой над вкладками; здесь одна строка о том,
   сколько единиц впереди (аудит 20.10.2026). */
.savings-pending-note { font-size: 12px; color: var(--muted); margin: 4px 0 10px; }
.savings-left { font-size: 15px; font-weight: 650; }
.savings-future-bonus { font-size: 13px; font-weight: 600; }
/* Свёртки раздела — строками «Аналитики» (`analyticsBlock`, аудит 20.10.2026). */
.savings-fold { margin: 8px 0; }

.savings-status { font-size: 12px; white-space: nowrap; }
.savings-status.full { font-weight: 600; }
.savings-orders { margin: 4px 0 18px; font-size: 12px; }
.savings-orders summary { cursor: pointer; color: var(--muted); }
/* Десять колонок в узком окне не помещаются: прокручиваем таблицу, а не страницу. */
.savings-scroll { overflow-x: auto; max-width: 100%; }
.savings-scroll > .savings-table { min-width: 940px; }
/*
 * Журнал по месяцам: месяц — карточка, в шапке одно число (бонус), внутри
 * короткие строки в одну линию. Подробности месяца — приглушённой строкой
 * внизу. Кнопок в строках нет: строку открывают щелчком.
 */
.savings-block-head { display: flex; align-items: baseline; justify-content: flex-end; gap: 12px; }
.savings-block-head .section-subhead { margin-bottom: 6px; }
.savings-month-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  margin: 10px 0; overflow: hidden;
}
.savings-month-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 10px 14px; cursor: pointer; user-select: none;
}
.savings-month-head:hover { background: var(--panel-2); }
.savings-month-title { display: flex; align-items: baseline; gap: 8px; }
.savings-chevron {
  display: inline-block; width: 10px; color: var(--muted); font-size: 10px;
  transition: transform .15s;
}
.savings-month-head.open .savings-chevron { transform: rotate(90deg); }
.savings-month-name { font-family: var(--font-display); font-size: 16px; }
.savings-month-total { display: flex; align-items: baseline; gap: 8px; font-variant-numeric: tabular-nums; }
.savings-month-total-label { font-size: 12px; color: var(--muted); }
.savings-month-total-value { font-family: var(--font-display); font-size: 16px; }
/* «Обновить курс» — в шапке каждого месяца, справа от итога (01.10.2026). На
   узком экране шапка переносится, а не вылезает за край карточки. */
.savings-month-head { flex-wrap: wrap; }
.savings-month-total { flex-wrap: wrap; justify-content: flex-end; }
.savings-rate-btn { margin-left: 6px; align-self: center; }
.savings-month-body { border-top: 1px solid var(--line); overflow-x: auto; }
.savings-rows { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 820px; }
.savings-rows th {
  text-align: left; font-weight: 500; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em; padding: 8px 14px 4px;
}
.savings-rows th.num, .savings-rows td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.savings-rows td { padding: 7px 14px; vertical-align: baseline; }
.savings-rows tbody tr.savings-row td { border-top: 1px solid var(--line); }
.savings-row.editable, .savings-row.savings-row-open { cursor: pointer; }
.savings-row.editable:hover td, .savings-row.savings-row-open:hover td { background: var(--panel-2); }
.savings-order { color: var(--muted); white-space: nowrap; }
.savings-article { font-family: var(--font-display); font-size: 14px; margin-right: 8px; }
/* Пометка источника только там, где она что-то меняет: строку CRM здесь не правят. */
.savings-src {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  padding: 1px 5px; border-radius: 4px; color: var(--muted); border: 1px solid var(--line);
  vertical-align: middle; white-space: nowrap;
}
.savings-src.crm { background: var(--accent-dim); color: var(--ink-green); border-color: transparent; }
/* Кто сторговался и снижения, ждущие её решения (15.10.2026). */
.savings-who { margin-left: 6px; font-size: 11px; color: var(--muted); white-space: nowrap; }
.savings-drops {
  margin: 12px 0 16px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--panel);
}
.savings-drops .section-subhead { margin: 0 0 8px; }
.savings-drop-row {
  display: flex; gap: 12px; align-items: center; justify-content: space-between;
  padding: 8px 0; border-top: 1px solid var(--line);
}
.savings-drop-text { min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
.savings-drop-text .muted { font-size: 12px; margin-top: 2px; }
.savings-price-arrow { color: var(--muted); margin: 0 4px; }
.savings-rate { color: var(--muted); }
.savings-bonus { font-weight: 600; }
/* Комментарий — колонкой справа, как в таблице до CRM: две строки, целиком по
   щелчку. Ширина задана колонке, иначе длинный текст растянул бы её на всё. */
.savings-comment-head, .savings-comment-cell { width: 34%; min-width: 240px; }
.savings-comment-cell { white-space: normal; font-size: 12px; color: var(--muted); }
.savings-comment {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; cursor: pointer; overflow-wrap: anywhere;
}
/* Свёрнутый комментарий РАЗВОРАЧИВАЕТСЯ, и об этом надо сказать глазами
   (аудит 24.09.2026): курсор-палец виден только под мышью, а многоточие в
   конце второй строки читается как «текст такой», а не как «есть ещё».
   Подчёркивание под курсором — самый тихий способ это показать. */
.savings-comment:hover { color: var(--text); text-decoration: underline; text-decoration-style: dotted; }
.savings-comment.open { display: block; overflow: visible; white-space: pre-line; }
.savings-comment.open:hover { text-decoration: none; }
.savings-issue-line { color: var(--ink-yellow); margin-top: 2px; overflow-wrap: anywhere; }
.savings-month-foot {
  padding: 8px 14px 10px; font-size: 12px; color: var(--muted);
  border-top: 1px solid var(--line); display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
.savings-warn { font-size: 11px; color: var(--ink-yellow); }
/* Форма строки: расчёт под полями обновляется на лету. */
.savings-form-preview { margin-top: 12px; font-size: 13px; }
.savings-form-preview:empty { display: none; }
.savings-form-quota { font-size: 12px; color: var(--muted); margin-top: 4px; }
.savings-form-quota.full { color: var(--ink-yellow); }
.savings-form-error { color: var(--ink-rose); font-size: 12px; margin-top: 6px; }
.savings-form-error:empty { display: none; }
.savings-form-delete { margin-left: auto; color: var(--ink-rose); }
/* «Такой заказ есть в CRM»: подсказка под полями, строка на каждый артикул заказа. */
.savings-order-suggest {
  margin-top: 10px; padding: 8px 10px; background: var(--panel-2); border-radius: var(--radius-sm); font-size: 12px;
}
.savings-order-suggest-title { color: var(--muted); margin-bottom: 4px; }
.savings-order-suggest-line {
  display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 3px 0;
}

/* ── «Таблицы»: слева список, справа превью и действия ────────────────────
   Список слева держит только название и тип — этого хватает, чтобы выбрать;
   всё остальное живёт справа. Состояние книги стоит НАД кнопками намеренно:
   выгрузка переписывает чужой документ целиком, и «Google Таблица не
   подключена» читают до нажатия, а не в тосте после. */
.table-row-type { font-size: 11px; color: var(--muted); }
/* Точка подключения: зелёная — книга привязана, тихая — ещё нет. */
.table-dot {
  width: 8px; height: 8px; border-radius: 50%; margin-left: auto;
  flex: 0 0 auto; background: var(--line);
}
.table-dot.on { background: var(--ink-green); }
.table-badge {
  padding: 2px 8px; border-radius: 999px; background: var(--accent-dim);
  font-size: 11px; white-space: nowrap;
}
/* Excel — вторая форма таблицы, а не её основной вид: плашка тише. */
.table-badge.ghost { background: var(--panel-2); color: var(--muted); }
.table-state { font-size: 13px; margin-top: 2px; }
/* Идущая выгрузка: строка состояния говорит о ней, а не о прошлом разе.
   Цвет — чернильный, а не заливочный `--accent`: это ТЕКСТ, и бледная мята на
   светлой бумаге не читается вовсе. */
.table-state.working { color: var(--ink-green); font-weight: 600; }
.table-state.failed { color: var(--ink-rose); font-weight: 600; }
/* Работающая кнопка: кружок и подпись в одну строку. Кнопка остаётся на месте
   и не «схлопывается» — иначе ряд прыгал бы на каждой выгрузке. */
.btn.btn-working { display: inline-flex; align-items: center; gap: 6px; }
.btn.btn-working .spinner { border-top-color: currentColor; }
/* Действия двумя рядами: сверху Google-книга, снизу за чертой — Excel.
   Это разные вещи, и одним рядом они читались как список равных кнопок. */
.table-actions { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 16px; }
.table-actions select { max-width: 230px; }
.table-excel { padding-top: 10px; border-top: 1px solid var(--line); }

/* ── «Примерка»: лист сеткой, над ним — что CRM из него поняла ───────────────
 *
 * С 29.09.2026 таблица модели показывается сеткой, как остальные книги
 * (`.tp-*` ниже). Над сеткой — строка открытого листа: день примерки и по чипу
 * на блок («МОДЕЛЬ 1 · О-053 · записано»). Строка — CRM-овская, не часть
 * листа, поэтому и цвета у неё свои. */
.fit-status { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 10px; }
.fit-day-head {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding-bottom: 4px; border-bottom: 1px solid var(--line);
}
.fit-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.fit-chip {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 3px 8px; border-radius: 999px; font-size: 12px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.fit-chip.ok-chip { border-color: var(--ok); }
.fit-chip.warn { border-color: var(--warn); }
.fit-chip.danger { border-color: var(--danger); }
.fit-block { font-size: 11px; color: var(--muted); white-space: nowrap; }
/* Запись модели в вопросе «Ревью»: колонка узкая, и длинный ответ уходит на
   следующую строку, а не за край. */
.review-fitting .review-pair { flex-wrap: wrap; }
.review-fitting .review-pair > span { min-width: 0; overflow-wrap: anywhere; }
/* Длинная подпись оценки («Брак в изделии: молния, пуговицы, ассиметрия») — тоже
   переносом, а не под плитки образцов (22.10.2026, вопрос 320). */
.review-fitting .review-pair > strong { flex-shrink: 1; min-width: 0; overflow-wrap: anywhere; }
/* Фото, снятые с таблицы примерки (09.10.2026): по ним и решают, какой это
   образец, — поэтому левая сторона шире обычной пары, а снимки сеткой по три. */
.review-fitting .review-compare-side { flex: 0 0 280px; }
.review-fitting-photos {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 8px;
}
.review-fitting-photos .review-compare-photo { height: 120px; cursor: zoom-in; }
.review-fitting-check { margin-top: 8px; font-size: 12px; color: var(--muted); }
/* Догадка Гермеса — одним видом во всех вопросах (цена, примерка, выбор
   артикула): рамка и мягкая заливка, подпись «догадка Гермеса». */
.review-compare-option.guess { border-color: var(--accent); background: var(--accent-dim); }
/* Посылка из нескольких вещей: слева все её снимки сеткой. */
.review-compare-side.many { flex: 0 0 280px; }
@media (max-width: 720px) {
  .review-fitting .review-compare-side,
  .review-compare-side.many { flex: 1 1 auto; }
}

/* ── превью листа книги ───────────────────────────────────────────────────
 *
 * Сетку собирает сервер из той же книги, что уезжает в Google
 * (`core/tables-preview.js`), и цвета шапок, заливок и рамок приходят
 * ГОТОВЫМИ — прямо из просьб к Google. Поэтому бумага здесь светлая в любой
 * теме: это превью чужого документа, а не часть оформления CRM, и тёмный лист
 * под светлой шапкой шаблона выглядел бы поломкой. Тёмные двойники токенов
 * ниже намеренно равны светлым.
 */
.tp-box { margin-top: 4px; }
/* Вкладки одной полосой, как в самой книге: их бывает тринадцать, и в два
   ряда полоса отжимала лист вниз. Лишние уезжают прокруткой. */
.tp-tabs {
  display: flex; flex-wrap: nowrap; gap: 4px; overflow-x: auto;
  padding-bottom: 0; scrollbar-width: thin;
}
.tp-tab {
  --tab-color: var(--line);
  padding: 5px 10px; border: 1px solid var(--sheet-frame); border-bottom: none;
  border-left: 3px solid var(--tab-color); border-radius: 7px 7px 0 0;
  background: var(--panel-2); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.tp-tab:hover { color: var(--text); }
.tp-tab.on { background: var(--sheet-paper); color: var(--sheet-ink); font-weight: 600; }
.tp-wrap {
  overflow: auto; max-height: 540px;
  border: 1px solid var(--sheet-frame); border-radius: 0 6px 6px 6px;
  background: var(--sheet-paper);
}
.tp-tabs:empty + .tp-wrap { border-radius: 6px; }
.tp-grid {
  border-collapse: collapse; background: var(--sheet-paper); color: var(--sheet-ink);
  /* Шрифт таблицы, а не CRM: книгу так и видят в Google. */
  font-family: Arial, Helvetica, sans-serif;
}
.tp-grid td, .tp-grid th {
  border: 1px solid var(--sheet-grid); padding: 2px 5px;
  text-align: left; vertical-align: middle; overflow: hidden;
}
/* Колонки — ширинами книги (`tablesGrid` ставит `table-layout: fixed` и ширину
   таблицы), и длинная ссылка без пробелов переносится, а не вылезает. */
.tp-grid { table-layout: fixed; }
.tp-grid td { overflow-wrap: anywhere; }
.tp-letter, .tp-gutter {
  position: sticky; background: var(--sheet-head); color: var(--sheet-head-ink);
  font-weight: 400; font-size: 10px; text-align: center;
}
.tp-letter { top: 0; z-index: 2; }
.tp-gutter { left: 0; z-index: 1; width: 34px; min-width: 34px; }
.tp-grid thead .tp-gutter { top: 0; z-index: 3; }
.tp-gutter-col { width: 34px; }
/* Закрепление листа: в книге за этой чертой шапка остаётся на месте. */
.tp-frozen-row td, .tp-frozen-row th { border-bottom: 2px solid var(--sheet-frame); }
.tp-frozen-col { border-right: 2px solid var(--sheet-frame); }
.tp-check { font-size: 13px; }
.tp-photos { display: flex; gap: 3px; align-items: flex-start; }
.tp-photos img { max-height: 84px; max-width: 100%; border-radius: 2px; object-fit: cover; }
/* Уголок заметки — тот же, которым её показывает сама таблица. */
.tp-note { position: relative; }
.tp-note::after {
  content: ''; position: absolute; top: 0; right: 0;
  border: 4px solid transparent;
  border-top-color: var(--sheet-note); border-right-color: var(--sheet-note);
}
.tp-more { margin-top: 6px; font-size: 12px; color: var(--muted); }
/* «Править таблицу» — заметной кнопкой под сеткой (11.11.2026). */
.tp-edit-row { display: flex; justify-content: center; margin-top: 12px; }
.tp-edit-btn { padding: 10px 28px; font-size: 15px; font-weight: 600; border-radius: 10px; }
/* ── что ещё не выгружено ────────────────────────────────────────────────
   Полоса над листом отвечает на единственный вопрос, ради которого сюда
   заходят: надо ли жать «Синхронизировать». Нечего выгружать — полосы нет. */
.tp-changes {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px; padding: 7px 10px; border-radius: var(--radius-sm);
  background: var(--panel-2); font-size: 13px;
}
.tp-changes-text { font-weight: 600; }
/* Пока сравнивать не с чем — та же полоса, но тихая: это не новость, а
   состояние, и жирной строкой оно кричало бы попусту. */
.tp-changes.quiet { background: transparent; padding: 2px 0; color: var(--muted); }
.tp-changes .btn { margin-left: auto; }
/* Ярлык вкладки с несохранённым: число прямо на нём — иначе вкладку пришлось
   бы искать, перебирая все тринадцать. */
.tp-tab.has-changes { border-left-color: var(--sheet-new-edge); }
.tp-tab-mark {
  display: inline-block; margin-left: 5px; min-width: 15px; padding: 0 4px;
  border-radius: 999px; background: var(--sheet-new-edge); color: var(--sheet-new-ink);
  font-size: 10px; line-height: 15px; text-align: center; vertical-align: middle;
}
.tp-tab-mark:empty { min-width: 7px; height: 7px; padding: 0; line-height: 7px; }
/* Строка, которой в книге ещё нет, и ячейка, значение которой стало другим.
   Заливка идёт ПОВЕРХ цвета из книги — это и есть смысл подсветки, — но рамка
   слева оставлена узкой: лист должен остаться похожим на себя. */
.tp-grid tr.tp-row-new td { background: var(--sheet-new) !important; }
.tp-grid tr.tp-row-new .tp-gutter { box-shadow: inset 3px 0 0 var(--sheet-new-edge); }
.tp-grid tr.tp-row-changed .tp-gutter { box-shadow: inset 3px 0 0 var(--sheet-changed-edge); }
.tp-grid td.tp-changed {
  background: var(--sheet-changed) !important;
  box-shadow: inset 0 0 0 1px var(--sheet-changed-edge);
}

/* ── «Править таблицу» (10.11.2026, `ui/sheet-editor.js`) ──────────────────
   Живой лист Google на весь экран: сетка — та же, что у превью (`.tp-grid`),
   поверх — выбор ячейки, поле правки и строка формулы. */
.se-modal { z-index: 45; }
.se-panel {
  width: calc(100vw - var(--chat-room) - 32px); max-width: none;
  height: calc(100vh - 32px); max-height: none; padding: 12px 14px; gap: 8px;
}
.se-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.se-title { font-weight: 600; font-size: 15px; }
.se-status { flex: 1; font-size: 12px; min-width: 160px; }
.se-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.se-addr {
  min-width: 52px; padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 12px; text-align: center; color: var(--muted);
}
.se-formula {
  flex: 1; min-width: 200px; padding: 5px 8px; font: inherit; font-size: 13px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); color: var(--text);
}
.se-tools { flex-wrap: wrap; }
.se-wrap { flex: 1; max-height: none; min-height: 0; }
.se-focus { outline: none; }
.se-grid td { cursor: cell; }
.se-grid .tp-check { cursor: pointer; font-size: 16px; }
.se-grid .tp-gutter { cursor: pointer; }
.se-grid td.se-sel { box-shadow: inset 0 0 0 2px var(--accent); }
.se-grid td.se-own { box-shadow: inset 3px 0 0 var(--sheet-changed-edge); }
.se-grid td.se-own.se-sel { box-shadow: inset 0 0 0 2px var(--accent), inset 5px 0 0 var(--sheet-changed-edge); }
.se-grid td.se-dirty { background: var(--sheet-changed) !important; }
/* Поле правки лежит в слое сетки (`.se-focus`), а не в ячейке: `position: relative` у ячейки
   таблицы WebKit не всегда держит, и поле улетало в левый верхний угол окна (11.11.2026). */
.se-focus { position: relative; }
.se-input {
  position: absolute; z-index: 5; box-sizing: border-box;
  padding: 2px 5px; font: inherit; resize: none; min-width: 120px;
  border: 2px solid var(--accent); background: var(--sheet-paper); color: var(--sheet-ink);
  box-shadow: 0 4px 14px var(--shadow-soft);
}
.se-locked .se-wrap { opacity: .6; pointer-events: none; }

/* ── тёмная тема ────────────────────────────────────────────────────────── */
/* Активная тема стоит на <html data-theme="dark|light">: её ставит theme.js до первой
   отрисовки — системная (prefers-color-scheme), ручной выбор или, если системную
   узнать нельзя, вечернее время. Правила ниже — единственное место, где живёт
   тёмная палитра: остальной CSS ссылается только на переменные. */
/* ── КИЗы ───────────────────────────────────────────────── */
/*
 * Раздел про номера, поэтому главное на экране — табло: последний
 * использованный, следующий свободный, остаток и то, что уйдёт в файл.
 * Цифры крупные и моноширинные по цифрам (`tabular-nums`): их сверяют
 * глазами с прежней таблицей, и прыгающая ширина знака этому мешает.
 */
.kiz-form {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: var(--pad-lg); margin: 14px 0 6px;
}
.kiz-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px; align-items: end;
}
.kiz-form > .form-field { margin-top: 12px; }
/* Табло — плитки «Аналитики» (20.10.2026, «идеальный пример визуала»): узкие плитки рядом
   слева, а не три бежевые плашки во всю ширину; цифра крупно, подпись коротко и серым,
   беда — цветом цифры (`analytics-tone-bad`). Диапазон «1110–1129» в узкой плитке
   переносится по тире, а не вылезает за край. */
.kiz-board {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 168px), 1fr));
  gap: var(--gap); margin-top: 16px;
}
.kiz-cell {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: 12px 14px;
}
.kiz-cell-value {
  font-family: var(--font-display); font-size: 26px; font-weight: 600; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.kiz-cell.analytics-tone-bad .kiz-cell-value { color: var(--an-ink); }
.kiz-cell-label { font-size: 12px; color: var(--muted); line-height: 1.3; }
.kiz-cell-note { font-size: 12px; color: var(--muted); line-height: 1.3; }
@media (max-width: 640px) {
  .kiz-cell { padding: 10px 12px; }
  .kiz-cell-value { font-size: 22px; }
}

/* Итог выдачи держится на экране, пока его не уберут: за файлом уходят в
   «Загрузки» и возвращаются сверить номера. */
.kiz-done {
  margin-top: 16px; padding: 12px 14px;
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  background: var(--accent-dim);
}
.kiz-done-title { font-family: var(--font-display); font-size: 17px; }
.kiz-done-file {
  margin-top: 4px; font-size: 12px; color: var(--text-2);
  word-break: break-all;
}
.kiz-empty { text-align: left; }
.kiz-empty-title { font-family: var(--font-display); font-size: 16px; }

/* Зов прочитать таблицу: стоит между формой и табло, потому что читать его
   надо ДО нажатия, а не после. */
.kiz-notice {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-top: 16px; padding: 10px 14px;
  border: 1px solid var(--warn); border-radius: var(--radius-sm);
  background: var(--tile-yellow-bg);
}
.kiz-notice-text { flex: 1 1 320px; font-size: 13px; color: var(--tile-yellow-text); }

/* Окно чтения таблицы: сверки читают глазами, поэтому они текстом в строке, а
   не значком с подсказкой по наведению. */
.kiz-read-table { min-width: 640px; }
.kiz-read-table td { vertical-align: top; }
.kiz-check { font-size: 12px; color: var(--muted); line-height: 1.6; }
.kiz-check-sign { display: inline-block; width: 14px; font-weight: 600; }
.kiz-check-ok { color: var(--ink-green); }
.kiz-check-bad { color: var(--ink-rose); }
.kiz-check-none { color: var(--muted); }
.kiz-check-warn { color: var(--ink-yellow); }
/* Последняя выдача из файла: тот же итог, но видно, что КИЗы кончились. */
.kiz-done-last { border-color: var(--warn); background: var(--tile-yellow-bg); }

.kiz-scroll { overflow-x: auto; }
.kiz-table {
  width: 100%; border-collapse: collapse; font-size: 13px; min-width: 860px;
  margin: 4px 0 18px;
}
.kiz-table th {
  text-align: left; font-weight: 500; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
  padding: 6px 8px; border-bottom: 1px solid var(--line);
}
.kiz-table td { padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
/* «Аналитика» (13.10.2026; 18.10.2026 — «видно глазами, читать по нажатию»): крупные цифры,
   находки строками «значок · что · число», текст под стрелкой, блоки данных свёрнуты. */
.analytics-since { margin-bottom: 12px; }
.analytics-tone-bad { --an-bg: var(--tile-rose-bg); --an-ink: var(--tile-rose-text); }
.analytics-tone-warn { --an-bg: var(--tile-yellow-bg); --an-ink: var(--tile-yellow-text); }
.analytics-tone-ok { --an-bg: var(--tile-green-bg); --an-ink: var(--tile-green-text); }
.analytics-tone-plain { --an-bg: var(--panel-2); --an-ink: var(--muted); }
.analytics-tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 128px), 1fr));
  gap: var(--gap); margin-bottom: 18px;
}
.analytics-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; cursor: pointer; color: var(--text); font: inherit; min-width: 0;
  transition: border-color .15s, transform .15s;
}
.analytics-tile:hover:not(:disabled) { border-color: var(--an-ink); transform: translateY(-1px); }
.analytics-tile:disabled { cursor: default; }
.analytics-tile-top { display: flex; align-items: center; gap: 8px; }
.analytics-tile-icon {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 28px; height: 28px; border-radius: 50%; background: var(--an-bg); color: var(--an-ink);
}
.analytics-tile-value {
  font-family: var(--font-display); font-size: 26px; font-weight: 600; line-height: 1.1;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.analytics-tile-label { font-size: 12px; color: var(--muted); line-height: 1.3; }
.analytics-improve { margin-bottom: 22px; }
.analytics-improve-title, .analytics-data-title {
  margin: 0 0 10px; font-size: 16px; display: flex; align-items: center; gap: 6px;
}
.analytics-data-title { color: var(--muted); font-size: 14px; font-weight: 600; }
.analytics-findings {
  display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
}
.analytics-f + .analytics-f { border-top: 1px solid var(--line); }
.analytics-f-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 12px;
  padding: 10px 14px; cursor: pointer; list-style: none;
}
.analytics-f-row::-webkit-details-marker, .analytics-block-head::-webkit-details-marker { display: none; }
.analytics-f-row:hover { background: var(--hover); }
.analytics-f-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; background: var(--an-bg); color: var(--an-ink);
}
.analytics-f-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.analytics-f-label { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.analytics-f-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 12px; color: var(--muted); }
.analytics-f-now {
  background: var(--tile-rose-bg); color: var(--tile-rose-text); border-radius: 999px; padding: 0 7px; font-weight: 600;
}
.analytics-who { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.analytics-chip {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px;
  white-space: nowrap; color: var(--text-2);
}
.analytics-chip b { font-weight: 600; }
.analytics-chip-more { color: var(--muted); }
.analytics-f-nums { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.analytics-f-value {
  font-family: var(--font-display); font-size: 20px; font-weight: 600; line-height: 1.1;
  color: var(--an-ink); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.analytics-tone-plain .analytics-f-value { color: var(--text); }
.analytics-f-value2 { font-size: 12px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.analytics-chevron { display: inline-flex; color: var(--muted); transition: transform .15s; }
details[open] > summary > .analytics-chevron { transform: rotate(90deg); }
.analytics-f-more {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 0 14px 12px 60px; font-size: 13px;
}
.analytics-f-text { color: var(--text-2); }
.analytics-f-lines { display: flex; flex-direction: column; gap: 4px; width: 100%; }
.analytics-f-line {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--gap); align-items: baseline;
}
.analytics-f-code { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.analytics-f-what { color: var(--text-2); min-width: 0; }
.analytics-f-whom { color: var(--muted); }
.analytics-f-lval { color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.analytics-f-action {
  display: flex; gap: 8px; align-items: flex-start; background: var(--accent-dim); color: var(--text);
  border-radius: var(--radius-sm); padding: 8px 10px;
}
.analytics-f-bulb { display: inline-flex; color: var(--ink-green); flex: 0 0 auto; margin-top: 1px; }
.analytics-all-good {
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: var(--radius);
  background: var(--tile-green-bg); color: var(--tile-green-text);
}
.analytics-more-btn { margin-top: 8px; }
.analytics-blocks {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 460px), 1fr));
  gap: var(--gap); align-items: start;
}
.analytics-block {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  min-width: 0; scroll-margin-top: 16px;
}
.analytics-block[open] { padding-bottom: 12px; }
.analytics-block > :not(summary) { margin: 0 16px 6px; }
.analytics-block-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 16px; cursor: pointer; list-style: none;
}
.analytics-block-head:hover { background: var(--hover); border-radius: var(--radius); }
.analytics-block-icon { display: inline-flex; color: var(--muted); }
.analytics-block-title { font-weight: 600; display: flex; align-items: center; gap: 6px; min-width: 0; }
.analytics-block-figure {
  margin-left: auto; font-size: 13px; color: var(--text-2); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.analytics-subtitle { margin-top: 8px; font-weight: 600; font-size: 13px; color: var(--muted); }
.analytics-bar-row {
  display: grid; grid-template-columns: minmax(90px, 32%) 1fr auto; gap: 4px 10px; align-items: center;
}
.analytics-bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.analytics-bar-track { height: 10px; background: var(--bg); border-radius: 4px; overflow: hidden; }
.analytics-bar { height: 100%; background: var(--accent); border-radius: 0 4px 4px 0; }
.analytics-bar-value { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 13px; }
.analytics-bar-detail { grid-column: 1 / -1; color: var(--muted); font-size: 12px; margin-top: -2px; }
.analytics-examples { font-size: 12px; color: var(--muted); margin: 0 0 4px; }
.analytics-examples summary { cursor: pointer; }
.analytics-example { padding: 2px 0 2px 12px; }
.analytics-scroll { overflow-x: auto; }
.analytics-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.analytics-table th { text-align: left; color: var(--muted); font-weight: 500; padding: 4px 6px; border-bottom: 1px solid var(--line); }
.analytics-table td { padding: 5px 6px; border-bottom: 1px solid var(--line); }
.analytics-table .num { text-align: right; white-space: nowrap; }
@media (max-width: 640px) {
  .analytics-f-row { grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--gap); padding: 10px 12px; }
  .analytics-f-row > .analytics-chevron { display: none; }
  .analytics-f-more { padding-left: 12px; }
  .analytics-tile { padding: 10px 12px; }
  .analytics-tile-value { font-size: 22px; }
}

/* «Тренды WB» (27.10.2026, `ui/trends.js`): строки категорий как в «Работе фабрик», плюс
   маленький год спроса в строке; под стрелкой — графики и плитки товаров с фото. */
.trends-date { width: 150px; }
.trends-row { grid-template-columns: auto minmax(0, 1fr) auto auto auto; }
.trends-mini { display: inline-flex; width: 104px; height: 30px; }
.trends-chart { display: block; width: 100%; height: auto; overflow: visible; }
.trends-chart-mini { width: 104px; height: 30px; }
.trends-bar-season { fill: var(--tile-green-text); }
.trends-bar-up { fill: var(--accent); }
.trends-bar-down { fill: var(--muted); fill-opacity: .3; }
.trends-bar-empty { fill: var(--muted); fill-opacity: .18; }
.trends-zero { stroke: var(--line-2); stroke-width: 1; }
.trends-mark { stroke: var(--tile-rose-text); stroke-width: 1.5; stroke-dasharray: 3 2; }
.trends-mark-label { fill: var(--tile-rose-text); font-size: 11px; }
.trends-axis { fill: var(--muted); font-size: 11px; }
.trends-month-band { fill: var(--tile-yellow-bg); }
.trends-line { stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
.trends-line-0, .trends-legend-0 { stroke: var(--tile-green-text); color: var(--tile-green-text); }
.trends-line-1, .trends-legend-1 { stroke: var(--tile-violet-text); color: var(--tile-violet-text); }
.trends-line-2, .trends-legend-2 { stroke: var(--muted); color: var(--muted); }
/* Прошлые годы — пунктиром: два тёмных цвета рядом глаз не различает. */
.trends-line-1 { stroke-dasharray: 7 4; }
.trends-line-2 { stroke-dasharray: 2 4; stroke-width: 2; }
.trends-legend-1 .trends-legend-dot, .trends-legend-2 .trends-legend-dot {
  background: none; height: 0; border-top: 2.5px dashed currentColor; width: 14px;
}
.trends-legend-2 .trends-legend-dot { border-top-style: dotted; }
.trends-legend { display: flex; gap: 14px; font-size: 12px; margin-top: 4px; }
.trends-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.trends-legend-dot { width: 10px; height: 3px; border-radius: 2px; background: currentColor; }
.trends-more { padding-left: 60px; }
.trends-more > .trends-chart { max-width: 640px; }
.trends-lines { display: flex; flex-direction: column; gap: 3px; color: var(--text-2); }
/* Проверка по нише WB (02.11.2026) — под шапкой категории. */
.trends-niche { margin: 10px 0 14px; padding: 10px 14px; border-radius: var(--radius); background: var(--panel-2); }
.trends-niche-title { display: flex; align-items: center; gap: 6px; font-weight: 600; color: var(--text); margin-bottom: 2px; }
.trends-later-title { margin-top: 18px; }
.trends-yoy { border-radius: 999px; padding: 0 7px; font-weight: 600; }
.trends-yoy.up { background: var(--tile-green-bg); color: var(--tile-green-text); }
.trends-yoy.down { background: var(--panel-2); color: var(--muted); }
.trends-goods { width: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.trends-goods > .trends-grid, .trends-goods > .trends-sku { align-self: stretch; }
.trends-goods-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.trends-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 132px), 1fr)); gap: var(--gap);
}
.trends-tile {
  display: flex; flex-direction: column; gap: 3px; text-align: left; min-width: 0; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 6px; font: inherit; color: var(--text); transition: border-color .15s, transform .15s;
}
.trends-tile:hover, .trends-tile.on { border-color: var(--tile-green-text); }
.trends-tile:hover { transform: translateY(-1px); }
.trends-photo {
  position: relative; display: block; aspect-ratio: 3 / 4; border-radius: var(--radius-sm); overflow: hidden; background: var(--panel-2);
}
.trends-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trends-badge {
  position: absolute; left: 6px; top: 6px; border-radius: 999px; padding: 1px 7px; font-size: 12px; font-weight: 700;
  background: var(--panel); color: var(--text);
}
.trends-badge.up { background: var(--tile-green-bg); color: var(--tile-green-text); }
.trends-badge.down { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.trends-tile-name {
  font-size: 13px; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.trends-tile-price { font-weight: 700; font-variant-numeric: tabular-nums; }
.trends-tile-sales { font-size: 12px; color: var(--muted); }
.trends-more-btn { align-self: center; }
.trends-sku {
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; background: var(--panel);
  display: flex; flex-direction: column; gap: 6px;
}
.trends-sku-head { display: flex; align-items: center; gap: var(--gap); justify-content: space-between; }
.trends-sku-name { font-weight: 600; min-width: 0; }
.trends-sku .trends-chart { max-width: 640px; }
.trends-none { padding: 12px 14px; }
.trends-rest { margin-top: 14px; }
.trends-rest > .analytics-findings { margin: 0 0 6px; border: 0; border-top: 1px solid var(--line); border-radius: 0; }
.trends-connect {
  max-width: 620px; display: flex; flex-direction: column; gap: 8px; padding: 16px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.trends-connect-gear { margin-bottom: 14px; }
.trends-connect-title { font-weight: 700; font-size: 16px; }
.trends-connect-row { display: flex; gap: 8px; }
.trends-connect-row input { flex: 1; min-width: 0; }
.trends-disconnect { align-self: flex-start; }
/* Раскрытая категория (28.10.2026): вкладки «Что ищут · Цвета и размеры · Сезон · Товары»;
   детали — пилюлями с долей и ростом, запросы — строками с полосой доли, под строкой —
   карточки из поиска WB; цвета и размеры — две колонки полос. */
.trends-root { width: auto; max-width: 220px; }
.trends-tabs { align-self: flex-start; max-width: 100%; overflow-x: auto; }
.trends-pane { width: 100%; }
.trends-tab-pane { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; width: 100%; }
.trends-tab-pane > .trends-chart { max-width: 640px; }
.trends-busy { width: 100%; max-width: 520px; margin: 0; }
.trends-label { font-size: 13px; color: var(--muted); margin-top: 4px; }
.trends-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.trends-chip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit; font-size: 13px;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.trends-chip:hover { border-color: var(--tile-green-text); }
.trends-chip.on { background: var(--tile-green-bg); border-color: var(--tile-green-text); color: var(--tile-green-text); font-weight: 600; }
.trends-chip-share { color: var(--muted); font-variant-numeric: tabular-nums; }
.trends-chip-more { border-style: dashed; color: var(--muted); }
.trends-chip.on .trends-chip-share { color: inherit; }
.trends-growth {
  font-size: 12px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.trends-growth.up { color: var(--tile-green-text); }
.trends-growth.down { color: var(--tile-rose-text); }
.trends-tile-grow { white-space: normal; }
.trends-queries { display: flex; flex-direction: column; align-self: stretch; max-width: 860px; }
.trends-query { border-bottom: 1px solid var(--line); }
.trends-query-row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(60px, 180px) 56px 56px auto; align-items: center; gap: var(--gap);
  width: 100%; padding: 7px 4px; border: 0; background: none; font: inherit; color: var(--text); text-align: left; cursor: pointer;
}
.trends-query-row:hover { background: var(--panel-2); }
.trends-query-row > .analytics-chevron { transition: transform .15s; }
.trends-query.open > .trends-query-row > .analytics-chevron { transform: rotate(90deg); }
.trends-query-text { min-width: 0; overflow-wrap: anywhere; }
.trends-query-bar { display: block; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.trends-query-fill { display: block; height: 100%; border-radius: 3px; background: var(--tile-green-text); }
.trends-query-share { text-align: right; font-variant-numeric: tabular-nums; font-size: 13px; }
.trends-query-row > .trends-growth { text-align: right; }
.trends-query-cards { display: flex; flex-direction: column; gap: 8px; padding: 4px 4px 12px; }
.trends-query-cards > .trends-grid, .trends-query-cards > .trends-sku { align-self: stretch; }
.trends-look { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 12px 32px; width: 100%; max-width: 860px; }
.trends-look-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.trends-share { display: grid; grid-template-columns: minmax(0, 130px) minmax(40px, 1fr) 56px; align-items: center; gap: var(--gap); font-size: 13px; }
.trends-share-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trends-share.other { color: var(--muted); }
.trends-share.other .trends-query-fill { background: var(--muted); opacity: .4; }
/* «Что продаётся», «заказать до», сезон до приезда (28.10.2026). */
.trends-seg-row { grid-template-columns: minmax(0, 1fr) minmax(60px, 160px) 56px 56px minmax(0, 150px) auto; }
.trends-crowd { font-size: 13px; color: var(--muted); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trends-crowd.one { color: var(--warn-ink); }
.trends-seg-actions { margin: 2px 0; }
.trends-warn { border-radius: 999px; padding: 0 7px; background: var(--warn); color: var(--warn-ink); font-weight: 600; }
.trends-warn-text { color: var(--warn-ink); }
/* Срок заказа и сведения о данных — одна плашка над моделями (28.10.2026, «приятнее»). */
.trends-summary {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 18px;
  margin: 4px 0 12px; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.trends-summary-since { font-size: 13px; display: inline-flex; align-items: center; gap: 4px; }
/* Прошлые советы, сверенные с продажами через 8 недель (12.11.2026) — своей строкой плашки. */
.trends-summary-past { font-size: 13px; flex-basis: 100%; }
/* Проверка прошлым (14.11.2026): итог строкой и кнопка рядом; окно — две кнопки в ряд. */
.trends-backtest { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.trends-backtest-actions { display: flex; gap: 8px; margin-top: 14px; }
/* Ткань, посадка, длина модели (12.11.2026) — под цветами и размерами. */
.trends-model-make { display: flex; flex-direction: column; gap: 4px; max-width: 860px; margin-top: 12px; }
.trends-own { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.trends-own-days { width: 58px; padding: 1px 6px; text-align: right; font-variant-numeric: tabular-nums; }
.nw-busy.trends-search-big { max-width: none; margin: 4px 0 12px; padding: 14px 18px; }
.trends-search-big .nw-busy-text, .trends-search-big .nw-busy-pct { font-size: 18px; }
.trends-search-note { grid-column: 1 / -1; }
/* Модели к дате — главный экран (28.10.2026, её макет): вкладки итога, фильтры слева, модель справа. */
.trends-models { display: flex; flex-direction: column; gap: var(--gap); margin-bottom: 18px; }
.trends-models-empty { margin: 8px 0; }
.trends-models-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; border-bottom: 1px solid var(--line); }
.trends-models-tabs { display: flex; gap: 4px; margin-right: auto; }
.trends-models-tab {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 0; border-bottom: 2px solid transparent;
  background: none; font: inherit; font-size: 14px; color: var(--muted); cursor: pointer; margin-bottom: -1px;
}
.trends-models-tab:hover { color: var(--text); }
.trends-models-tab.on { color: var(--text); font-weight: 600; border-bottom-color: var(--tile-green-text); }
.trends-models-count { font-size: 12px; padding: 0 6px; border-radius: 999px; background: var(--panel-2); font-variant-numeric: tabular-nums; }
.trends-models-sort { width: auto; min-width: 170px; }
.trends-models-grid { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 16px; align-items: start; }
.trends-filters {
  display: flex; flex-direction: column; gap: 14px; padding: 14px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--panel); position: sticky; top: 8px;
}
.trends-filter { display: flex; flex-direction: column; gap: 6px; }
.trends-filter-title { font-size: 13px; font-weight: 600; }
.trends-filter-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.trends-filter-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trends-filter-n { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.trends-filter-price { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.trends-filter-price input { min-width: 0; }
.trends-filter-reset { align-self: stretch; }
.trends-model {
  display: flex; flex-direction: column; gap: 14px; padding: 16px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--panel); min-width: 0;
}
.trends-model-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.trends-model-path { font-size: 13px; }
.trends-model-nav { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }
.trends-verdict { border-radius: 999px; padding: 3px 10px; font-size: 13px; font-weight: 600; }
.trends-verdict.ok { background: var(--tile-green-bg); color: var(--tile-green-text); }
.trends-verdict.warn { background: var(--warn); color: var(--warn-ink); }
.trends-verdict.bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.trends-model-title { margin: 2px 0 0; font-family: var(--font-display); font-size: 26px; line-height: 1.2; }
.trends-model-parts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: -6px; }
.trends-mtiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr)); gap: var(--gap); }
.trends-mtile {
  display: flex; flex-direction: column; gap: 3px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--panel-2); min-width: 0;
}
.trends-mtile-label { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }
.trends-mtile-value { font-family: var(--font-display); font-size: 22px; font-weight: 600; line-height: 1.15; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.trends-mtile-sub { font-size: 12px; color: var(--muted); }
.trends-mtile.up .trends-mtile-value { color: var(--tile-green-text); }
.trends-mtile.down .trends-mtile-value { color: var(--tile-rose-text); }
.trends-model-mid { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 12px; align-items: stretch; }
.trends-model-mid > * { min-width: 0; }
.trends-model-chart, .trends-why { padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); min-width: 0; }
.trends-model-chart-body { display: flex; flex-direction: column; gap: 6px; }
.trends-model-look { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); min-width: 0; }
.trends-model-look:empty { display: none; }
.trends-model-table td.trends-model-query { overflow-wrap: anywhere; }
.trends-model-card-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
.trends-model-card-thumb { width: 28px; height: 37px; object-fit: cover; border-radius: 4px; flex: none; }
.trends-why { background: var(--panel-2); }
.trends-why.ok { background: var(--tile-green-bg); }
.trends-why.warn { background: var(--tile-cream-bg); }
.trends-why.bad { background: var(--tile-rose-bg); }
.trends-why-title { font-weight: 600; margin-bottom: 6px; }
.trends-why-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.trends-why-list li.con { color: var(--warn-ink); }
.trends-why-lost { margin-top: 8px; }
.trends-model-cards { display: flex; flex-direction: column; gap: 8px; }
.trends-model-cards > .trends-grid, .trends-model-cards > .trends-sku { align-self: stretch; }
.trends-model-actions { gap: 8px; padding-top: 14px; border-top: 1px solid var(--line); }
.trends-cats-body { display: flex; flex-direction: column; gap: 8px; padding-top: 8px; }
.trends-cats-refresh { align-self: flex-start; }
/* Два экрана (28.10.2026): растущие категории кнопками → открытая категория и её модели. */
.trends-view-frame, .trends-cats-list { display: flex; flex-direction: column; gap: 12px; }
.trends-list-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.trends-list-head .analytics-improve-title { margin: 0; }
.trends-row-btn { width: 100%; border: 0; background: none; font: inherit; color: inherit; text-align: left; }
.trends-row-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.trends-row-models { font-size: 12px; font-weight: 600; color: var(--tile-green-text); }
.trends-back { align-self: flex-start; }
.trends-models > .btn { align-self: center; }
.trends-cat-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 14px;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.trends-cat-title { margin: 0; font-family: var(--font-display); font-size: 24px; line-height: 1.2; }
.trends-cat-head .analytics-f-sub { font-size: 13px; }
.trends-cat-more .analytics-block-head .hint { margin-right: auto; }
.trends-mlist { gap: 12px; }
.trends-mlist-title { display: flex; align-items: center; gap: 6px; }
.trends-mlist-title.ok { color: var(--tile-green-text); }
.trends-mlist-title.bad { color: var(--tile-rose-text); }
.trends-mlist-row {
  display: flex; flex-direction: column; gap: 1px; width: 100%; padding: 7px 10px; border: 1px solid transparent;
  border-radius: var(--radius-sm); background: none; font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.trends-mlist-row:hover { background: var(--hover); }
.trends-mlist-row.on { background: var(--panel-2); border-color: var(--line-2); }
.trends-mlist-name { font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.trends-mlist-sub { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Стадия, три строки надёжности, жалобы, сохранённые (28.10.2026, третье и четвёртое ТЗ). */
.trends-stage { border-radius: 999px; padding: 3px 10px; font-size: 13px; background: var(--panel-2); color: var(--muted); }
.trends-stage.rise, .trends-stage.grow { background: var(--tile-green-bg); color: var(--tile-green-text); }
.trends-stage.mature { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.trends-stage.fall { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.trends-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  border: 1px solid var(--line); border-radius: var(--radius);
}
.trends-fact { display: flex; flex-direction: column; gap: 2px; padding: 10px 14px; font-size: 14px; min-width: 0; }
.trends-fact + .trends-fact { border-left: 1px solid var(--line); }
.trends-fact-label { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }
.trends-fact-text { font-weight: 600; font-variant-numeric: tabular-nums; }
.trends-ok-text { color: var(--tile-green-text); }
.trends-complaint { font-size: 13px; }
.trends-saved-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.trends-saved-photo { width: 64px; height: 84px; border-radius: var(--radius-sm); overflow: hidden; background: var(--panel-2); }
.trends-saved-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trends-saved-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.trends-saved-title { font-weight: 600; }
.trends-saved-check { display: flex; flex-direction: column; gap: 2px; }
@media (max-width: 900px) {
  .trends-fact + .trends-fact { border-left: 0; border-top: 1px solid var(--line); }
  .trends-models-grid { grid-template-columns: minmax(0, 1fr); }
  .trends-filters { position: static; }
  .trends-model-mid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .trends-seg-row { grid-template-columns: minmax(0, 1fr) 52px 52px auto; }
  .trends-seg-row > .trends-crowd { display: none; }
  .trends-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .trends-row > .trends-mini { display: none; }
  .trends-cat-head { grid-template-columns: auto minmax(0, 1fr) auto; }
  .trends-cat-head > .trends-mini { display: none; }
  .trends-more { padding-left: 12px; }
  .trends-connect-row { flex-direction: column; }
  .trends-query-row { grid-template-columns: minmax(0, 1fr) 52px 52px auto; }
  .trends-query-row > .trends-query-bar { display: none; }
}
/* «Заказать КИЗы» (13.10.2026): заявка прямо во вкладке, под ней история заказов.
   Выбор вкладки — ДВЕ БОЛЬШИЕ КНОПКИ (13.10.2026, просьба владелицы: «нарезать» и
   «заказать» намного заметнее и больше): со значком, выбранная залита мятой; справа —
   шестерёнка «Папка и таблица». На узком окне кнопки встают одна под другой. */
.kiz-tabs { display: flex; align-items: stretch; gap: 12px; margin: 4px 0 16px; flex-wrap: wrap; }
.kiz-tab {
  flex: 1 1 240px; max-width: 380px; min-height: 64px;
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  padding: 12px 22px; border-radius: var(--radius);
  border: 2px solid var(--accent); background: var(--panel); color: var(--text);
  font: inherit; font-size: 17px; font-weight: 700; cursor: pointer;
  transition: background .15s ease, transform .15s ease, box-shadow .15s ease;
}
.kiz-tab svg { flex: 0 0 auto; width: 26px; height: 26px; }
.kiz-tab:hover { background: var(--accent-dim); transform: translateY(-1px); }
.kiz-tab.on {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent-strong);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--accent) 45%, transparent);
}
.kiz-tab:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 2px; }
.kiz-tabs .kiz-gear { align-self: center; }
/* «Журнал выдач» (11.11.2026) — справа от двух больших кнопок, прижат к правому краю. */
.kiz-tabs .kiz-tab-ledger { flex: 0 1 auto; margin-left: auto; font-size: 15px; padding: 12px 18px; border-color: var(--line); }
.kiz-tabs .kiz-tab-ledger svg { width: 22px; height: 22px; }
.kiz-tabs .kiz-tab-ledger.on { border-color: var(--accent); }
/* Открытая панель «Нарезать» / «Заказать» (03.11.2026): по нажатию большой кнопки, со своей
   шапкой — значок, название, «Свернуть». Главный экран — кнопки и журнал выдач. */
.kiz-tab:not(.on) { box-shadow: 0 1px 3px color-mix(in srgb, var(--text) 8%, transparent); }
.kiz-panel {
  border: 1px solid var(--line); border-top: 3px solid var(--accent); border-radius: var(--radius);
  background: var(--panel); padding: 16px var(--pad-lg) var(--pad-lg); margin: 0 0 22px;
  box-shadow: 0 4px 18px color-mix(in srgb, var(--text) 7%, transparent);
  animation: kiz-panel-in .18s ease-out;
}
@keyframes kiz-panel-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .kiz-panel { animation: none; } }
.kiz-panel-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid var(--line);
}
.kiz-panel-icon {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--accent-dim); color: var(--ink-green);
}
.kiz-panel-icon svg { width: 22px; height: 22px; }
.kiz-panel-title { margin: 0; font-family: var(--font-display); font-size: 19px; font-weight: 600; }
.kiz-panel-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.kiz-panel > .hint { margin-top: 12px; }
.kiz-panel .kiz-form { border: 0; background: none; padding: 0; margin: 16px 0 0; }
.kiz-panel .kiz-request-inline { border: 0; padding: 0; margin: 14px 0 18px; background: none; }
.kiz-panel .kiz-cell { background: var(--bg); }
/* «Под заказ» (09.11.2026) и «Вручную» (11.11.2026): две одинаковые плашки, между ними «или». */
.kiz-mode {
  margin-top: 16px; padding: 14px 16px;
  border: 1px solid var(--accent); border-radius: var(--radius);
  background: var(--accent-dim);
}
.kiz-mode-title { display: block; font-family: var(--font-display); font-size: 16px; font-weight: 600; }
.kiz-mode-hint { display: block; margin: 2px 0 10px; font-size: 13px; color: var(--text-2); }
/* Свёрнутые плашки (11.11.2026): шапка — кнопка со стрелкой, тело — по нажатию. */
.kiz-mode-head {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.kiz-mode-text { flex: 1; min-width: 0; }
.kiz-mode-arrow { flex: none; font-size: 22px; line-height: 1; color: var(--ink-green); transform: rotate(90deg); transition: transform .15s ease; }
.kiz-mode.collapsed .kiz-mode-arrow { transform: none; }
.kiz-mode.collapsed .kiz-mode-hint { margin-bottom: 0; }
.kiz-mode.collapsed > :not(.kiz-mode-head) { display: none; }
.kiz-mode.collapsed:hover { background: color-mix(in srgb, var(--accent) 22%, var(--panel)); }
.kiz-mode-head:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 4px; border-radius: 4px; }
.kiz-mode-order select, .kiz-mode-order .combo { width: 100%; max-width: 560px; }
/* «Вручную» (11.11.2026) — та же плашка, что «Под заказ»: два равных варианта. */
.kiz-panel .kiz-form.kiz-mode-manual {
  margin-top: 0; padding: 14px 16px;
  border: 1px solid var(--accent); border-radius: var(--radius);
  background: var(--accent-dim);
}
.kiz-mode-manual .kiz-mode-hint { margin-bottom: 14px; }
.kiz-mode-or {
  display: flex; align-items: center; gap: 12px; margin: 12px 0;
  font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em;
}
.kiz-mode-or::before, .kiz-mode-or::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
.kiz-go { min-width: 220px; padding: 11px 22px; font-size: 15px; font-weight: 600; border-radius: var(--radius-sm); }
.kiz-form .row-actions { margin-top: 18px; }
@media (max-width: 640px) {
  .kiz-panel { padding: 14px 14px 16px; }
  .kiz-go { width: 100%; }
}
.kiz-request-inline {
  padding: 14px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); margin-bottom: 18px;
}
/* Бланк заявки в журнале выдач: имя файла и «Показать». */
.kiz-ledger .kiz-file { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.kiz-ledger .kiz-file .kiz-sub { overflow-wrap: anywhere; }
.kiz-table th.num, .kiz-table td.num {
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.kiz-range { font-variant-numeric: tabular-nums; white-space: nowrap; }
.kiz-file { font-size: 12px; color: var(--text-2); word-break: break-all; }
/* Строка не из выдачи (перенос прежнего счёта, чтение таблицы) — тише. */
.kiz-row-past td { color: var(--muted); font-style: italic; }
.kiz-mark {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px;
  background: var(--panel-2); color: var(--muted);
  font-size: 10px; font-style: normal; text-transform: uppercase; letter-spacing: .04em;
}

/* Заявка на КИЗы: строка будущего бланка. Два поля из четырнадцати правятся
   прямо в таблице — вид товара и ТНВЭД, остальное CRM знает и показывает
   текстом, чтобы его было видно, а не чтобы его правили здесь. */
/* ЗАЯВКА НА КИЗЫ. Верх окна — три поля в ряд, ниже строки будущего бланка.
   Ширину колонкам задаём явно: в таблице правятся два поля из семи, и
   раздавать место поровну значило бы отдать половину экрана составу, который
   только читают. */
.kiz-request-head {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end;
  margin-bottom: 4px;
}
.kiz-request-head .form-field:first-child { flex: 1 1 380px; max-width: 560px; }
.kiz-request-head .form-field { flex: 0 1 200px; }
.kiz-request-body { margin-top: 12px; }
.kiz-request-empty { padding: 28px 12px; }
/* Таблица фабрики не прочиталась — не серая подсказка, а отказ (как `.chip.danger`). */
.kiz-request-failed { color: var(--ink); border: 1px solid var(--danger); background: var(--danger); }
.kiz-request-table { min-width: 900px; table-layout: fixed; }
.kiz-request-table th:nth-child(1), .kiz-request-table td:nth-child(1) { width: 12%; }
.kiz-request-table th:nth-child(2), .kiz-request-table td:nth-child(2) { width: 6%; }
.kiz-request-table th:nth-child(3), .kiz-request-table td:nth-child(3) { width: 10%; }
.kiz-request-table th:nth-child(4), .kiz-request-table td:nth-child(4) { width: 19%; }
.kiz-request-table th:nth-child(5), .kiz-request-table td:nth-child(5) { width: 9%; }
.kiz-request-table th:nth-child(6), .kiz-request-table td:nth-child(6) { width: 18%; }
.kiz-request-table th:nth-child(7), .kiz-request-table td:nth-child(7) { width: 26%; }
/* Артикул не переносится: это опознавательный знак строки, и «КРТ5-» на одной
   строке, «черный» на другой читается как две разные вещи. */
.kiz-cell-article { white-space: nowrap; font-variant-numeric: tabular-nums; }
.kiz-cell-fabric { font-size: 12px; line-height: 1.4; }
.kiz-request-table .combo, .kiz-request-table input, .kiz-request-table select {
  width: 100%; min-width: 0;
}
.kiz-request-table .kiz-mark { display: block; margin: 4px 0 0; width: fit-content; }
.kiz-cell-tnved .btn-xs { margin-top: 4px; }

/* Факт от фабрики: кнопки таблицы стоят в ряду полей, по нижнему краю. */
.kiz-request-source { display: flex; align-items: center; gap: 6px; padding-bottom: 2px; }
.kiz-request-head .kiz-request-file { flex: 1 1 380px; max-width: 560px; }
.kiz-table-chip {
  display: flex; align-items: center; gap: 6px; min-height: 34px;
  padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.kiz-table-name { font-weight: 600; word-break: break-all; }
.kiz-table-chip .btn-xs { margin-left: auto; }
.kiz-table-warnings { margin: 6px 0; }
.kiz-table-warnings .hint { margin: 2px 0; }
/* Файл тащат над окном — окно показывает, что его примет. */
.kiz-drop-over { outline: 2px dashed var(--accent); outline-offset: -6px; border-radius: var(--radius-sm); }
/* Заказ таблицы — строка-заголовок перед своими строками. */
.kiz-request-table .kiz-group-row td {
  padding-top: 14px; border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.kiz-group-code { font-weight: 600; }
.kiz-group-qty { float: right; font-variant-numeric: tabular-nums; }
.kiz-cell-qty input { text-align: right; font-variant-numeric: tabular-nums; }
/* Пометка под числом («заказ 80 · нет в таблице») переносится внутри своей
   ячейки, а не лезет в соседнюю: у `num` по умолчанию запрет переноса. */
.kiz-request-table td.kiz-cell-qty { white-space: normal; }
.kiz-request-table .kiz-cell-qty .kiz-mark { width: auto; max-width: 100%; margin-left: auto; text-align: right; }
/* Ноль — строка в бланк не едет: гасим её число. */
.kiz-qty-off input { color: var(--muted); }

:root[data-theme="dark"] {
  color-scheme: dark;
  --marys-rose: #4f3034;
  --gossamer-green: #2f4a3a;
  --pastel-yellow: #4a4325;
  --orchid-petal: #3d3549;
  --heavenly-pink: #4a383d;
  --cappuccino-foam: #2a2822;
  --person-1: #4f7d60;
  --person-2: #a8616a;
  --person-3: #6c5d93;
  --person-4: #a87a2f;
  --person-5: #457594;
  --person-6: #8b6550;
  --person-ink: #fbf7f0;
  --hushed-violet: #463a3b;
  --ink: #f2ede4;
  --paper: #232019;
  --bg: #1b1916;
  --panel: #232019;
  --panel-2: #2a2721;
  --line: #37332c;
  --text: #e8e1d5;
  /* Тоже поднят до нормы (было #a39a8b). На большинстве фонов тёмной темы он
     её держал (5,8–6,4), но на подсвеченной строке «Завершено» давал 4,00: так
     набраны заголовки сортировки «Номер», «Производство», «Размещён». Плюс
     «Показать 6 заказов» на доске (4,29) и подписи этапов «Замена»,
     «Отложено» кеглем 9,5 (4,47). Стало 4,56 на худшем фоне. */
  --muted: #aea595;
  --accent: #8fb59d;
  --accent-dim: #2c3a32;
  --ok: #8fb59d;
  --warn: #4a4325;
  --danger: #4f3034;
  --ink-green: #bfe0cc;
  --ink-rose: #f2b8bd;
  --ink-yellow: #e9dcaa;

  --c-d4a514-l: #e9b516;
  --c-c96a70-l: #5e3b3d;
  --c-rgba-80-66-48-1-s: rgba(80, 66, 48, 0.16);
  --c-rgba-47-66-56-16-s: rgba(47, 66, 56, 0.26);
  --c-rgba-122-51-57-12-s: rgba(122, 51, 57, 0.19);
  --c-d4a514-t: #e8ddba;
  --c-rgba-20-12-16-82-s: rgba(20, 12, 16, 1);
  --hover: #2f2b25;
  --tile-violet-bg: #2e2637;
  --c-46405a-t: #cecbd7;
  --c-a3c6b0-s: #a3c6b0;
  --c-f4f1e8-s: #383324;
  --c-rgba-60-50-35-08-s: rgba(0, 0, 0, 0.18);
  --c-eef2e9-s: #2e3527;
  --panel-3: #2a2721;
  --text-2: #d9d1c3;
  --c-rgba-255-255-255-7-s: rgba(255, 255, 255, 0.084);
  --tile-rose-bg-3: #3e2123;
  --tile-rose-text-2: #d9c9ca;
  --tile-yellow-bg: #37331e;
  --tile-yellow-text: #e1dbc2;
  --tile-blush-bg: #342626;
  --tile-blush-text: #d5cdcf;
  --tile-violet-text: #d0ccd6;
  --tile-green-bg: #253229;
  --tile-green-text-2: #cbd7d0;
  --c-f8f6ef-s: #3d3826;
  --c-fdf3f4-s: #432427;
  --tile-cream-bg: #403b22;
  --c-faf5f5-s: #3e2929;
  --tile-violet-bg-2: #342b3d;
  --tile-green-bg-2: #293b2f;
  --c-f7f5ef-s: #3b3627;
  --c-eef4f0-s: #2a362e;
  --c-rgba-120-104-80-18-l: rgba(120, 104, 80, 0.29);
  --c-rgba-255-255-255-72-s: rgba(255, 255, 255, 0.086);
  --c-rgba-120-104-80-3-l: rgba(120, 104, 80, 0.48);
  --c-rgba-80-66-48-06-s: rgba(0, 0, 0, 0.13);
  --c-e3dbc9-s: #e3dbc9;
  --c-rgba-80-66-48-08-s: rgba(0, 0, 0, 0.18);
  --c-ddb0b4-s: #ddb0b4;
  --c-9c9282-t: #d5d2cd;
  --text-3: #c9c0b0;
  --c-fbf5da-s: #39341f;
  --tile-rose-bg-2: #3b2021;
  --c-ece7d8-s: #554e3a;
  --c-rgba-90-74-55-08-s: rgba(0, 0, 0, 0.18);
  --c-fdf9ee-s: #423923;
  --line-4: #5b513e;
  --c-f3efe4-s: #373122;
  --panel-6: #393423;
  --c-a09684-t: #d6d2cc;
  --panel-5: #433b24;
  --c-rgba-80-66-48-05-s: rgba(0, 0, 0, 0.11);
  --c-d8b26a-t: #d8b26a;
  --c-e2dccc-t: #e2dccc;
  --c-rgba-255-255-255-66-s: rgba(255, 255, 255, 0.079);
  --c-ddd3e6-l: #4d4257;
  --c-cfe3d7-l: #42574a;
  --c-c0b6a2-t: #c0b6a2;
  --c-6f7f74-t: #cfd4d0;
  --c-eef2f6-s: #273039;
  --c-4a5866-t: #cbd1d7;
  --c-f3eef8-s: #31253d;
  --c-574a66-t: #d1cbd7;
  --c-eef2ec-s: #2d3429;
  --c-47563f-t: #cfd7cb;
  --c-f1ece0-s: #342f21;
  --c-a9cdb8-s: #3d5246;
  --c-f6f2e6-s: #3b3421;
  --c-f4efe3-l: #5d533c;
  --c-fdfbf5-s: #443c25;
  --c-f2ecdd-l: #5e543b;
  --c-d9b96a-s: #d9b96a;
  --c-b8515d-s: #b8515d;
  --c-4a7c59-l: #7fb38f;
  --c-3f6b4c-t: #c8dbcd;
  --c-a94550-l: #b54a56;
  --c-f9ecee-s: #3f2227;
  --c-8e3a44-t: #e1c2c5;
  --c-fdf3d8-s: #39321f;
  --c-e6d3a3-l: #625637;
  --c-6d5620-t: #e5d9bd;
  --c-c96a74-l: #5e3b3e;
  --panel-raw: #232019;
  --on-accent: #fff;
  --on-accent-strong: #17261d;
  --card: var(--panel);
  --star-off: #7a7365;
  --rule: var(--line);
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --shadow-soft: rgba(0, 0, 0, .55);
  --guide-scrim: rgba(0, 0, 0, .62);
  --crop-shade: rgba(0, 0, 0, .62);
  --crop-line: #fff;
  --crop-grid: rgba(255, 255, 255, .4);
  --guide-arrow: #ff6369;
  --guide-arrow-halo: rgba(255, 255, 255, .9);
  --warn-ink: var(--ink-yellow);
  --accent-ink: var(--ink-green);
  --c-a5454f-s: #7a3e44;
  --c-ece0e2-l: #564346;
  --c-e8d6d9-l: #574245;
  --c-fff8f9-s: #46262a;
  --c-a08b6f-t: #d9d2ca;
  --tile-rose-text: #e3bfc1;
  --tile-rose-bg: #3c2022;
  --tile-rose-line: #64353a;
  --c-fff9f9-s: #472626;
  --c-eef3ec-s: #2c3528;
  --tile-green-text: #cbd7d1;
  --c-dbe6d9-l: #475445;
  --tile-yellow-line: #615938;
  --c-rgba-40-34-28-14-s: rgba(0, 0, 0, 0.31);
  --c-rgba-40-34-28-10-s: rgba(0, 0, 0, 0.22);
  --tile-yellow-line-2: #605839;
  --c-rgba-255-255-255-18-s: rgba(255, 255, 255, 0.022);
  --c-rgba-255-255-255-35-l: rgba(255, 255, 255, 0.042);
  --c-rgba-40-34-28-12-s: rgba(0, 0, 0, 0.26);
  --line-3: #585141;
  --jr-line: #7a7365;
  --c-ddd5c4-s: #524b3d;
  --c-rgba-80-66-48-12-s: rgba(0, 0, 0, 0.26);
  --c-d9b96a-l: #635636;
  --c-rgba-59-50-39-72-s: rgba(59, 50, 39, 1);
  --c-4a7c59-t: #c8dacd;
  --c-7c6a92-t: #d1cbd7;
  --c-a8742f-t: #e6d4bc;
  --c-f6e3dd-s: #38241e;
  --c-a8422a-t: #e7c3bb;
  --line-2: #524f47;
  --panel-4: #3f3a2a;
  --c-7fae8c-l: #639c73;
  --c-d0a43f-l: #cd9e32;
  --c-c9c7bf-l: #504e49;
  --c-c47a63-l: #b96146;
  --c-f6ecd4-s: #61522e;
  --c-7a5c12-t: #e8dbba;
  --c-f4e2dc-s: #37241e;
  --c-8f4028-t: #e6c6bc;
  --c-b9cdbf-l: #46534a;
  --c-ece7f1-s: #2d2634;
  --c-b3d0be-l: #43564a;
  --c-cfcabb-l: #535046;
  --c-0e5d59-l: #4ee4dd;
  --c-rgba-80-66-48-16-s: rgba(0, 0, 0, 0.35);
  --c-f2ede2-s: #352f22;
  --c-e6d9a3-l: #625a37;
  --c-fbf9fd-s: #362646;
  --c-bfd8c7-l: #435649;
  --c-eef6f0-s: #27392c;
  --c-d7eadc-s: #3b5442;
  --c-2f6941-t: #c3dfcc;
  --c-a89e8d-t: #a89e8d;
  --tile-violet-bg-3: #302635;
  --c-rgba-80-66-48-22-s: rgba(0, 0, 0, 0.48);
  --c-ece9e3-s: #2f2c25;
  --c-55504a-t: #d4d1cf;
  --c-b8860b-s: #c08c0c;
  --c-b8860b-t: #e8dbba;
  --c-2f7d4f-t: #c0e2ce;
  --c-b3261e-t: #e8bdba;
  --c-7a9-s: #4b6d61;
  --c-2a7-t: #bae8d7;
  /* Бумага превью НЕ темнеет: в «Таблицах» это снимок чужого документа, а
     заливки его шапок приходят с сервера светлыми — тёмный лист под ними
     читался бы как поломка. Двойники равны светлым намеренно. */
  --sheet-paper: #ffffff;
  --sheet-ink: #1f2328;
  --sheet-grid: #e0e2e6;
  --sheet-head: #f1f3f4;
  --sheet-head-ink: #5f6368;
  --sheet-frame: #b9bcc2;
  --sheet-note: #f2a33c;
  /* Что ещё не уехало в Google: новая строка и изменённая ячейка. Цвета тоже
     «бумажные» — они лежат на листе и в тёмной теме не темнеют. */
  --sheet-new: #e3f6e6;
  --sheet-new-edge: #34a853;
  --sheet-new-ink: #ffffff;
  --sheet-changed: #fdf2c8;
  --sheet-changed-edge: #e0a800;
  --fin-track: #2c3a32;
  --fin-now: #8fb59d;
  --fin-later: #4d6b5a;
  --fin-c1: #3987e5;
  --fin-c2: #d95926;
  --fin-c3: #199e70;
  --fin-rest: #3a362f;
  --tw-own-line: #4d6b58;
  --tw-rec-bg: #2c2838;
  --tw-rec-line: #8c7cb8;
  --tw-crm-bg: #22303a;
  --tw-crm-line: #5f93b4;
  --tw-cal-bg: #35301f;
  --tw-cal-line: #b39550;
  --tw-subs-bg: #1f342f;
  --tw-subs-line: #4f9a8a;
  --tw-sat-bg: #2f2a1c;
  --tw-sat-line: #8a733a;
  --tw-sat-ink: #e3c98b;
  --tw-vac-bg: #3a2329;
  --tw-vac-line: #a95d74;
  --tw-vac-ink: #f0aec0;
  --tw-done-bg: #1f3320;
  --tw-done-line: #5f9c57;
  --tw-done-ink: #addaa4;
}
/* Снимки и логотип в тёмной теме чуть приглушены, чтобы не светить. */
:root[data-theme="dark"] img { filter: brightness(.92); }
:root[data-theme="dark"] .gate-logo, :root[data-theme="dark"] .side-logo { filter: none; }

/* ── ДОСКА ЗАДАЧ: ПРОИЗВОДСТВО × ДЕЛО ─────────────────────────────────────
   Строка — производство, колонка — вид дела, в клетке число открытых задач.
   Цвета у колонок нет вовсе: девять оттенков подряд читаются как график, а
   таблица здесь про числа. Половины — «о чём писать фабрике» и «что делаем
   сами» — разделены ОДНОЙ чертой. */
.task-board-head {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; margin: 0 0 10px;
}
.task-pick { flex: 0 0 auto; min-width: 220px; }
.task-pick-btn { white-space: nowrap; }
.task-pick-off {
  border: 1px solid var(--line); background: var(--accent-dim); color: var(--ink-green);
  border-radius: 999px; padding: 3px 10px; font: inherit; font-size: 12px; cursor: pointer;
}
.task-pick-off:hover { border-color: var(--accent); }

.task-mx-wrap {
  overflow-x: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius);
}
table.task-mx { border-collapse: collapse; width: 100%; font-size: 13px; }
table.task-mx th, table.task-mx td { border-bottom: 1px solid var(--line); padding: 0; }
table.task-mx tbody tr:last-child > th, table.task-mx tbody tr:last-child > td { border-bottom: 0; }
/* Шапка сидит ВПЛОТНУЮ к первой строке (24.09.2026): под её текстом стояли те
   же 9px, что и над строкой фабрики, и между подписью колонки и первой
   фабрикой лежала полоса пустоты в два отступа. Сверху место осталось — там
   шапка отделяется от кнопок раздела. */
table.task-mx thead th {
  background: var(--panel); font-weight: 400; color: var(--muted); font-size: 11px;
  line-height: 1.2; padding: 8px 6px 3px; text-align: center; vertical-align: bottom; width: 74px;
}
/* Имя производства стоит ЦЕЛИКОМ и в одну строку (24.09.2026, требование
   пользователя): «Jeans (F23) MD GROUP（裙子）» ломалось на две строки и растило
   всю строку доски вдвое. Колонка берёт ширину по самому длинному имени,
   остальные стоят по 74px, а если вместе они шире экрана — `.task-mx-wrap`
   прокручивается вбок. */
table.task-mx th.task-mx-name { text-align: left; width: auto; min-width: 200px; white-space: nowrap; }
table.task-mx tbody th.task-mx-name { font-weight: 400; padding: 0; }
.task-mx-fac {
  width: 100%; text-align: left; border: 0; background: transparent; font: inherit;
  padding: 9px 10px; cursor: pointer; color: var(--text); white-space: nowrap;
  display: flex; align-items: center; gap: 8px;
}
.task-mx-fac:hover { background: var(--panel-2); }
.task-mx-row.on .task-mx-fac { background: var(--accent-dim); font-weight: 600; }
.task-mx-cell {
  width: 100%; border: 0; background: transparent; font: inherit; cursor: pointer;
  padding: 6px 4px; color: var(--text); min-height: 34px;
}
.task-mx-cell:hover { background: var(--panel-2); }
/* Пустая клетка остаётся пустой — ни нуля, ни точки: глаз должен падать
   только на числа. Нажимать в ней нечего, и наведение тоже молчит. */
.task-mx-cell[disabled] { cursor: default; }
.task-mx-cell[disabled]:hover { background: transparent; }
/* Число в кружке (24.09.2026): в ряду одинаковых клеток глаз ловит пятно
   раньше, чем цифру, и «где работа есть» читается одним взглядом. */
.task-mx-cell .num {
  display: inline-flex; align-items: center; justify-content: center; position: relative;
  min-width: 26px; height: 26px; padding: 0 6px; border-radius: 999px;
  background: var(--accent-dim); color: var(--ink-green);
  font-family: var(--font-display); font-size: 14px; line-height: 1;
}
.task-mx-cell:hover .num { background: var(--accent); }
/* Залежавшееся — точка У КРАЯ кружка: под числом она растила строку, а сбоку
   от голой цифры читалась как звёздочка; на кружке это метка, как у счётчика
   непрочитанного. */
.task-mx-cell .dot {
  position: absolute; top: -1px; right: -1px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--c-b8515d-s);
}
table.task-mx th.split, table.task-mx td.split { border-left: 1px solid var(--line); }
.task-mx-open > td { padding: 8px 12px 10px; background: var(--bg); }

/* ── «НАСТРОЙКИ → ДОСТУП» (29.09.2026, упрощён 02.10.2026) ────────────────
   Кто работает в CRM и вход через интернет (`ui/access.js`). Человек — одна
   строка: буква в кружке, имя, роль, когда был; действия — под «⋯». Вход
   через интернет и копия базы — две плитки со статусом точкой. */
.access-body { display: grid; gap: 12px; }
.access-body > .section-subhead { margin: 6px 0 -2px; }
.access-users { display: grid; gap: 6px; }
.access-user {
  padding: 8px 8px 8px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.access-user.is-off { opacity: .6; }
.access-user-line { display: flex; align-items: center; gap: var(--gap); min-height: 32px; }
.access-avatar {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-weight: 700; font-size: 13px;
  background: var(--accent-dim); color: var(--ink-green);
}
.access-user.is-off .access-avatar { background: var(--panel-2); color: var(--muted); }
.access-who { flex: 1; min-width: 0; display: grid; gap: 1px; }
.access-who-top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.access-user-name { font-weight: 600; }
.access-user-meta { font-size: 12px; color: var(--muted); }
.access-more { flex: none; min-height: 26px; padding: 0 8px; color: var(--muted); letter-spacing: .08em; }
.access-user.open .access-more { background: var(--hover); color: var(--text); }
.access-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line);
}
.access-login { font-size: 12px; color: var(--muted); margin-right: 4px; }
.access-off > summary { cursor: pointer; font-size: 12px; color: var(--muted); padding: 2px 0; }
.access-off > summary:hover { color: var(--text); }
.access-off > .access-users { margin-top: 6px; }
.access-block { display: grid; gap: 8px; }
.access-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.access-inline input { flex: 1 1 200px; min-width: 0; }

/* ── «НАСТРОЙКИ → КОМУ ЧТО» (12.11.2026, `ui/task-routing.js`) ───────────────
   Вид дела × человек. Строка — что за дело и пример мелко, справа по кружку на
   человека, как «Кому» в окне задачи: выбран — в кольце с галочкой, нет — бледный.
   Шапка с людьми прилипает к верху, группы — тихими заголовками. */
.rt { display: grid; gap: 12px; }
/* Над шапкой таблицы — её фон тенью вверх (ниже): подпись стоит поверх, иначе тень срезала её низ. */
.rt-lead { position: relative; z-index: 4; margin: 0; font-size: 13px; line-height: 1.45; color: var(--muted); }
.rt-table {
  --rt-col: 84px;
  /* Сколько людей в таблице — ставит `ui/task-routing.js`; два — она и ассистент. */
  --rt-people: 2;
  display: grid; gap: 2px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: 4px 6px 8px;
}
.rt-row {
  display: grid; align-items: center; column-gap: 4px;
  grid-template-columns: minmax(0, 1fr) repeat(var(--rt-people, 2), var(--rt-col));
  min-height: 48px; padding: 4px 6px; border-radius: var(--radius-sm);
}
.rt-item:hover > .rt-row { background: var(--hover); }
.rt-head {
  position: sticky; top: 0; z-index: 3; min-height: 64px;
  background: var(--panel); border-bottom: 1px solid var(--line); border-radius: 0;
  margin-bottom: 2px;
  /* Отступ окна над прилипшей шапкой закрыт её же фоном — строки под ней не просвечивают. */
  box-shadow: 0 -24px 0 var(--panel);
}
.rt-person {
  display: grid; justify-items: center; gap: 3px; text-align: center; min-width: 0;
}
.rt-person .assign-avatar { width: 30px; height: 30px; font-size: 13px; }
.rt-person-name {
  max-width: 100%; font-size: 12px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rt-person-sub { font-size: 11px; line-height: 1.2; color: var(--muted); }
.rt-group { display: grid; gap: 1px; }
.rt-group + .rt-group { margin-top: 6px; }
.rt-group-title {
  margin: 8px 6px 2px; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.rt-what { min-width: 0; display: grid; gap: 1px; }
.rt-label { display: flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 500; color: var(--text); }
.rt-open {
  flex: none; min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px;
  display: inline-grid; place-items: center;
  font-size: 11px; font-weight: 700; line-height: 1;
  background: var(--accent-dim); color: var(--ink-green);
}
.rt-hint {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rt-cell { display: grid; place-items: center; }
.rt-pick { opacity: .32; }
.rt-pick .assign-avatar { width: 28px; height: 28px; font-size: 12px; }
.rt-pick:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 3px; }
/* «Отдать по-новому?» — под своей строкой, мягкой плашкой. */
.rt-ask {
  display: grid; gap: 8px; margin: 2px 6px 8px; padding: 10px 12px;
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm); background: var(--panel-2);
  animation: rt-ask-in .16s ease-out;
}
@keyframes rt-ask-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.rt-ask-head { display: grid; gap: 2px; font-size: 13px; }
.rt-ask-sub { font-size: 12px; color: var(--muted); }
.rt-ask-list { display: grid; gap: 2px; max-height: 220px; overflow: auto; }
.rt-ask-item {
  display: flex; align-items: flex-start; gap: 8px; padding: 5px 6px;
  border-radius: var(--radius-sm); cursor: pointer;
}
.rt-ask-item:hover { background: var(--hover); }
.rt-ask-item input { margin-top: 2px; flex: none; }
.rt-ask-words { display: grid; gap: 1px; min-width: 0; }
.rt-ask-text { font-size: 13px; color: var(--text); }
.rt-ask-meta { font-size: 12px; color: var(--muted); }
.rt-ask-actions { display: flex; flex-wrap: wrap; gap: 6px; }
@media (max-width: 560px) {
  .rt-table { --rt-col: 58px; padding: 2px; }
  .rt-hint { white-space: normal; }
}

/* Задача у нескольких (12.11.2026): кружки всех, кому она, и «кто первый». */
.task-shared { padding-left: 2px; gap: 0; }
.task-shared .assign-avatar + .assign-avatar { margin-left: -4px; box-shadow: 0 0 0 1.5px var(--paper); }
.task-shared > span:last-child { margin-left: 5px; }

/* «Ревью» по видам (12.11.2026): плашка «просит решить» над вопросом и свёртка чужих в списке. */
.review-routed {
  margin: 8px 0 0; padding: 6px 10px; border-radius: var(--radius-sm);
  font-size: 13px; background: var(--panel-2); color: var(--muted);
}
.review-routed.asked { background: var(--warn); color: var(--ink-yellow); font-weight: 600; }
.review-others-toggle {
  display: flex; align-items: center; gap: 6px; width: 100%;
  margin: 8px 0 2px; padding: 6px 10px; border: 0; border-top: 1px solid var(--line);
  background: transparent; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--muted); text-align: left; cursor: pointer;
}
.review-others-toggle::before { content: '▸'; font-size: 11px; }
.review-others-toggle[aria-expanded="true"]::before { content: '▾'; }
.review-others-toggle:hover { color: var(--text); }

/* Окно «<Имя>: ответ в «Ревью»» владелице (12.11.2026). */
.ra-list { display: grid; gap: 10px; max-height: 60vh; overflow: auto; }
.ra-card {
  display: grid; gap: 8px; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  transition: opacity .15s;
}
.ra-card.is-decided { opacity: .7; }
.ra-head { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.ra-head .assign-avatar { width: 22px; height: 22px; font-size: 11px; }
.ra-question { font-family: var(--font-display); font-size: 15px; color: var(--text); }
.ra-answer, .ra-changes { display: grid; gap: 2px; font-size: 13px; color: var(--text); }
.ra-label { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.ra-changes ul { margin: 0; padding-left: 18px; display: grid; gap: 2px; }
.ra-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.access-add {
  display: grid;
  gap: var(--gap);
  padding: 12px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
}
.access-handoff {
  display: grid;
  gap: 8px;
  padding: 12px;
  background: var(--accent-dim);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
}
.access-handoff-title { font-weight: 600; }
.access-handoff-text {
  margin: 0;
  font: 14px/1.5 ui-monospace, Menlo, monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  user-select: all;
}
.access-tiles {
  display: grid; gap: var(--gap); margin-top: 6px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.access-tile {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.access-tile-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.access-tile-title { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; }
.access-tile > .row-actions { margin-top: auto; }
.access-link { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.access-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.access-link.is-up .access-dot { background: var(--accent); }
.access-link.is-down .access-dot { background: var(--danger); }
.access-link-why {
  padding: 6px 10px;
  font-size: 13px;
  color: var(--ink);
  background: var(--danger);
  border-radius: var(--radius-sm);
}
.access-url { color: var(--accent-ink); font-size: 13px; overflow-wrap: anywhere; }
/* «Ключ от копий сохранён у меня» — подпись и переключатель строкой (29.10.2026). */
.access-key-saved { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; }
.access-key-saved .switch { flex: none; }

/* Схема «Лога» в узком месте — стрелки сверху вниз, а не вбок (30.09.2026).
   Стоит ниже правил схемы, у конца файла: запрос к контейнеру веса
   селектору не добавляет, и при равном весе побеждает тот, кто ниже. Мерит
   своё место, а не окно: вложенная схема внутри веера узкая и на большом
   экране. */
@container jrflow (max-width: 720px) {
  .jr-flow, .jr-flow.jr-flow-alone { display: block; }
  .jr-flow:not(.jr-flow-alone) > .jr-src::after { display: none; }
  .jr-fan { margin-top: 12px; padding-left: 22px; }
  .jr-kid::before { left: -14px; top: -12px; bottom: -5px; }
  .jr-kid:first-child::before { top: -12px; }
  .jr-kid:last-child::before { height: calc(var(--jr-hook) + 12px); }
  .jr-kid:only-child::before { display: block; }
  .jr-kid::after { left: -14px; width: 7px; }
}

/* «План недели» (13.10.2026, картинка владелицы): шапка с неделей и прогрессом,
   три плашки, семь колонок дней, цветные категории задач. */
.tw { display: flex; flex-direction: column; gap: 12px; }
.tw-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.tw-title { flex: 1 1 220px; min-width: 0; }
.tw-h { margin: 0; font-family: var(--font-display); font-size: 26px; font-weight: 600; color: var(--text); }
.tw-nav {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: var(--radius); padding: 2px 6px; background: var(--panel);
}
.tw-week { font-size: 14px; min-width: 170px; text-align: center; }
.tw-progress {
  flex: 0 1 260px; min-width: 200px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: 8px 12px; font-size: 13px;
}
.tw-progress-row { display: flex; justify-content: space-between; margin-bottom: 6px; }
.tw-progress-count { margin-top: 4px; text-align: right; }
.tw-bar { height: 6px; border-radius: 999px; background: var(--panel-3); overflow: hidden; }
.tw-bar > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.tw-bar.sm { height: 4px; }
.tw-tools { flex-wrap: wrap; }
.tw-panels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: start; }
/* Плашек две: «Скрипты» с 29.10.2026 — кнопкой над планом, окном «Заказов». */
.tw-panels.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tw-panel {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  padding: 10px 12px; min-width: 0;
}
.tw-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px;
  font-family: var(--font-display); font-size: 14px; color: var(--text);
}
.tw-panel-list { display: flex; flex-direction: column; }
.tw-panel-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 2px; font-size: 13px;
  border-top: 1px solid var(--line);
}
.tw-panel-row:first-child { border-top: 0; }
.tw-panel-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.tw-panel-when { font-size: 12px; white-space: nowrap; }
.tw-prio.done .tw-panel-text { color: var(--muted); text-decoration: line-through; }
/* «с прошлой недели» у перенесённого приоритета (11.11.2026, A10-Q9). */
.tw-prio-from { margin-left: 6px; font-size: 11px; color: var(--muted); white-space: nowrap; }
.tw-num {
  flex: none; width: 20px; height: 20px; border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--panel-3); color: var(--text-2); font-size: 11px; font-weight: 600;
}
.tw-days {
  /* Дней в плане: пять, с рабочей субботой — шесть (ставит доска на элементе). */
  --tw-cols: 5;
  display: grid; grid-template-columns: repeat(var(--tw-cols, 5), minmax(150px, 1fr)); gap: 8px;
  overflow-x: auto; padding-bottom: 4px;
}
/* Над пятницей — «+ Рабочая суббота», над рабочей субботой — «Убрать субботу»
   (15.10.2026). Место — первая строка сетки, колонка последнего дня. */
.tw-sat-slot { grid-column: var(--tw-cols, 5); display: flex; justify-content: flex-end; min-width: 0; }
.tw-sat-add {
  width: 100%; padding: 5px 8px; border: 1.5px dashed var(--tw-sat-line); border-radius: var(--radius);
  background: var(--tw-sat-bg); color: var(--tw-sat-ink); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
}
.tw-sat-add:hover { border-style: solid; }
.tw-sat-add.tw-sat-off { background: transparent; font-weight: 500; }
.tw-sat-add.tw-sat-off:hover { background: var(--tw-sat-bg); }
.tw-day {
  display: flex; flex-direction: column; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); padding: 8px;
}
.tw-day.today { border: 2px solid var(--accent); background: var(--tile-green-bg-2); }
/* Суббота — день по желанию (14.10.2026): тёплый фон и пунктирная рамка. */
.tw-day.sat { background: var(--tw-sat-bg); border: 1px dashed var(--tw-sat-line); }
.tw-day.sat .tw-day-name { color: var(--tw-sat-ink); }
.tw-day.sat.today { border: 2px solid var(--accent); }
.tw-day.drop { outline: 2px dashed var(--accent); outline-offset: -2px; }
/* День отпуска сотрудника (21.10.2026): своим цветом, задачи на него не ставят. */
.tw-day.vac { background: var(--tw-vac-bg); border: 1px dashed var(--tw-vac-line); }
.tw-day.vac.today { border: 2px solid var(--tw-vac-line); }
.tw-day.vac .tw-day-name, .tw-day.vac.today .tw-day-name { color: var(--tw-vac-ink); }
.tw-vac-tag {
  margin-left: 6px; padding: 1px 7px; border-radius: 999px; font-family: Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 11px; font-weight: 600; vertical-align: 1px;
  background: var(--paper); color: var(--tw-vac-ink); border: 1px solid var(--tw-vac-line);
}
.tw-vac-strip {
  display: flex; align-items: center; gap: var(--gap); padding: 8px 12px; margin: 0 0 8px;
  border: 1px solid var(--tw-vac-line); border-left-width: 3px; border-radius: var(--radius-sm);
  background: var(--tw-vac-bg); color: var(--tw-vac-ink); font-size: 13px; font-weight: 600;
}
.tw-vac-icon { flex: none; display: grid; place-items: center; color: var(--tw-vac-line); }
/* «<Имя>: отпуск закончился — передать задачи?» (11.11.2026): висит до её нажатия. */
.tw-handover {
  margin: 0 0 10px; padding: 8px 12px; border: 1px solid var(--tw-vac-line); border-left-width: 3px;
  border-radius: var(--radius-sm); background: var(--tw-vac-bg); color: var(--tw-vac-ink);
}
.tw-handover-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tw-handover-toggle {
  border: 0; background: none; padding: 0 2px; font-size: 14px; line-height: 1; cursor: pointer; color: var(--tw-vac-ink);
}
.tw-handover-title { font-size: 14px; font-weight: 700; }
.tw-handover-count { font-size: 13px; text-decoration: underline dotted; cursor: pointer; }
.tw-handover-actions { display: flex; gap: 6px; margin-left: auto; }
.tw-handover-list { display: flex; flex-direction: column; gap: 4px; margin: 8px 0 2px 22px; }
.tw-handover-list[hidden] { display: none; }
.tw-handover-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
.tw-handover-text { min-width: 0; overflow-wrap: anywhere; }
.tw-handover-note { font-size: 12px; color: var(--muted); }
.tw-vac-lines { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.btn.tw-vac-btn { display: inline-flex; align-items: center; gap: 6px; }
.btn.tw-vac-btn svg { color: var(--tw-vac-line); }
/* «В отпуске до 11 ноября» — мелко под именем (22.10.2026, её слово: «не в
   строку, иначе забирает очень много места»). */
.person-name-stack { display: inline-flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
.task-person-vac, .assign-pick-vac {
  font-size: 11px; font-weight: 600; color: var(--tw-vac-ink); white-space: nowrap;
}
.assign-menu-sub.vac { color: var(--tw-vac-ink); }
/* Окно «Отпуска сотрудников»: те же карточки, что у повторяющихся, своим цветом. */
.tw-vac-body .tw-rec-card { border-left-color: var(--tw-vac-line); }
.tw-vac-body .tw-rec-card:hover { border-color: var(--tw-vac-line); }
.tw-vac-body .tw-rec-icon { background: var(--tw-vac-bg); color: var(--tw-vac-line); }
.tw-vac-body .tw-rec-form { border-color: var(--tw-vac-line); background: var(--tw-vac-bg); }
.tw-vac-body .tw-rec-add:hover { border-color: var(--tw-vac-line); background: var(--tw-vac-bg); }
.tw-vac-body .tw-choice-btn:hover { border-color: var(--tw-vac-line); }
.tw-vac-body .tw-choice-btn.on { background: var(--tw-vac-line); border-color: var(--tw-vac-line); }
.tw-vac-card.now .tw-rec-when { color: var(--tw-vac-ink); font-weight: 600; }
.tw-vac-dates { display: flex; flex-wrap: wrap; gap: 10px 14px; }
.tw-vac-dates .form-field { flex: 1 1 150px; min-width: 0; }
.tw-vac-date { width: 100%; font-size: 14px; padding: 8px 10px; background: var(--paper); }
.tw-vac-who { font-size: 14px; }
.tw-day-head { display: flex; flex-direction: column; gap: 3px; margin-bottom: 6px; }
.tw-day-name { font-family: var(--font-display); font-size: 14px; color: var(--text); }
.tw-day.today .tw-day-name { color: var(--ink-green); }
.tw-day-sub { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); }
.tw-items { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.tw-item {
  display: flex; gap: 6px; align-items: flex-start; padding: 5px 4px; border-radius: 6px; cursor: pointer;
}
.tw-item:hover { background: var(--panel-2); }
.tw-item[draggable="true"] { cursor: grab; }
/* Выполненное не зачёркивается (22.10.2026, её слово): оно уходит плашкой под день. */
.tw-item.done .tw-text { color: var(--text-2); }
.tw-check {
  flex: none; width: 16px; height: 16px; margin-top: 1px; padding: 0;
  border: 1.5px solid var(--muted); border-radius: 4px; background: transparent;
  font-size: 11px; line-height: 13px; color: var(--on-accent-strong); cursor: pointer;
}
.tw-check.round { border-radius: 50%; }
.tw-check.on { background: var(--accent); border-color: var(--accent); }
.tw-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tw-text { font-size: 13px; line-height: 1.35; overflow-wrap: anywhere; }
.tw-meta { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.tw-late { font-size: 11px; color: var(--ink-rose); }
.tw-sub { font-size: 11px; color: var(--muted); }
/* Вид пункта плана (14.10.2026): полоса слева и мягкий фон. Своя — зелёная
   полоса, с подзадачами — бирюзовая, повторяющаяся — сиреневая, от CRM —
   голубая, запись календаря — песочная. */
.tw-item { border-left: 3px solid transparent; }
.tw-item.k-own { border-left-color: var(--tw-own-line); }
.tw-item.k-subs { border-left-color: var(--tw-subs-line); background: var(--tw-subs-bg); }
.tw-item.k-rec { border-left-color: var(--tw-rec-line); background: var(--tw-rec-bg); }
.tw-item.k-crm { border-left-color: var(--tw-crm-line); background: var(--tw-crm-bg); }
.tw-item.k-cal { border-left-color: var(--tw-cal-line); background: var(--tw-cal-bg); }
.tw-item.k-subs:hover, .tw-item.k-rec:hover, .tw-item.k-crm:hover, .tw-item.k-cal:hover {
  box-shadow: inset 0 0 0 1px var(--line);
}
.tw-legend { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-left: auto; font-size: 12px; color: var(--text-2); }
.tw-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.tw-legend-dot { width: 12px; height: 12px; border-radius: 3px; border-left: 3px solid var(--line); background: var(--panel); }
.tw-legend-item.k-own .tw-legend-dot { border-left-color: var(--tw-own-line); }
.tw-legend-item.k-subs .tw-legend-dot { border-left-color: var(--tw-subs-line); background: var(--tw-subs-bg); }
.tw-legend-item.k-rec .tw-legend-dot { border-left-color: var(--tw-rec-line); background: var(--tw-rec-bg); }
.tw-legend-item.k-crm .tw-legend-dot { border-left-color: var(--tw-crm-line); background: var(--tw-crm-bg); }
.tw-legend-item.k-cal .tw-legend-dot { border-left-color: var(--tw-cal-line); background: var(--tw-cal-bg); }
/* Свой цвет задачи (22.10.2026, её выбор — «у каждой задачи свой»): ставят в
   боковой панели, палитра — та же, что у записей календаря (`--cal-c`). */
.tw-item.tw-colored { border-left-color: var(--cal-c); background: color-mix(in srgb, var(--cal-c) 16%, var(--panel)); }
.tw-item.tw-colored:hover { box-shadow: inset 0 0 0 1px var(--line); }
/* Открытая в панели задача со своим цветом — цвет виден сразу, отметка «открыта» — рамкой
   (09.11.2026, её слово: «меняю цвет через боковое меню — нужно, чтобы применялось сразу, а не
   после того, как закрою меню»): зелёная заливка «открыта» перекрывала выбранный цвет. */
.tw-item.tw-colored.tp-current { background: color-mix(in srgb, var(--cal-c) 16%, var(--panel)); box-shadow: 0 0 0 2px var(--accent); }
/* Выполненное — плашкой под днём, своим цветом и без зачёркивания (22.10.2026).
   Плашки — следующая строка сетки дней: каждая стоит под своим днём. */
.tw-done-gap { min-width: 0; }
.tw-done {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; align-self: start;
  border: 1px solid var(--tw-done-line); border-radius: var(--radius); background: var(--tw-done-bg); padding: 6px 8px;
}
.tw-done-head { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--tw-done-ink); }
.tw-done-mark {
  flex: none; width: 16px; height: 16px; border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--tw-done-line); color: var(--paper); font-size: 10px; line-height: 1;
}
.tw-done-count { margin-left: auto; }
.tw-done-list .tw-item, .tw-done-list .tw-item.tw-colored {
  border-left-color: var(--tw-done-line); background: var(--paper);
}
.tw-done-list .tw-check.on { background: var(--tw-done-line); border-color: var(--tw-done-line); color: var(--paper); }
/* Подзадачи (14.10.2026): счёт «2/5» — кнопка, под задачей — список с галочками. */
.tw-subs-toggle {
  font: inherit; font-size: 11px; line-height: 16px; padding: 0 6px; cursor: pointer;
  border: 1px solid var(--tw-subs-line); border-radius: 999px; background: var(--panel); color: var(--text-2);
}
.tw-subs-toggle:hover, .tw-subs-toggle.on { background: var(--tw-subs-line); color: var(--paper); }
.tw-subs-toggle { display: inline-flex; align-items: center; gap: 3px; }
.tw-subs-toggle svg { transition: transform .15s; }
.tw-subs-toggle.on svg { transform: rotate(90deg); }
.tw-subs { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; cursor: default; }
.tw-subs-row { display: flex; gap: 6px; align-items: flex-start; }
.tw-subs-text { font-size: 12px; line-height: 1.35; overflow-wrap: anywhere; }
.tw-subs-row.done .tw-subs-text { color: var(--muted); }
.tw-check.sm { width: 13px; height: 13px; font-size: 9px; line-height: 10px; margin-top: 1px; }
.tw-add { margin-top: 6px; }
.tw-add-btn { width: 100%; justify-content: center; }
.tw-add-form { display: flex; flex-direction: column; gap: 4px; }
.tw-add-form input, .tw-add-form select { width: 100%; min-width: 0; font-size: 13px; }
.tw-plan-fields {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--gap); margin-top: 10px;
}
/* Срок задачи (13.10.2026): плашка «срок 17 октября»; завтра и сегодня —
   жёлтая, прошёл — красная. У того, кому можно, она же кнопка «перенести». */
.task-due {
  flex: 0 0 auto; font: inherit; font-size: 12px; line-height: 18px; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 999px; padding: 0 8px;
  background: var(--panel); color: var(--text-2);
}
.tw-meta .task-due { font-size: 11px; line-height: 16px; padding: 0 6px; }
.task-due.soon { background: var(--warn); color: var(--ink-yellow); border-color: transparent; }
.task-due.late { background: var(--danger); color: var(--ink-rose); border-color: transparent; font-weight: 600; }
button.task-due { cursor: pointer; }
button.task-due:hover { border-color: var(--muted); }
.task-due-set { white-space: nowrap; }
.due-menu-other {
  display: flex; flex-direction: column; gap: 4px; padding: 6px 10px 8px;
  font-size: 11px; color: var(--muted); border-top: 1px solid var(--line); margin-top: 2px;
}
.due-menu-other input { font-size: 13px; }
.tw-due-field { display: flex; align-items: center; gap: 6px; }
.tw-due-field input { flex: 1 1 auto; min-width: 0; }
/* Повторяющиеся задачи (14.10.2026): на плашке — только число, список — в окне
   шестерёнки: что, когда, в каком бренде. Плашка без списка не тянется по
   высоте соседей. */
.tw-panel-rec { align-self: start; }
.tw-panel-rec .tw-panel-head { margin-bottom: 0; }
.tw-panel-rec .muted { margin-top: 6px; }
.tw-count {
  margin-left: 6px; min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-grid; place-items: center; vertical-align: 2px;
  border: 0; border-radius: var(--radius-sm);
  font: 600 11.5px/1 Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--accent-dim); color: var(--accent-ink);
}
/* Окно повторяющихся задач (15.10.2026, её слово: «сделать более нативно
   приятным»): задача — карточкой со значком и неделей полоской, правка
   раскрывается на её месте формой, новая — пунктирной кнопкой внизу. */
.tw-rec-body { display: flex; flex-direction: column; gap: 12px; }
.tw-rec-list { display: flex; flex-direction: column; gap: 8px; }
.tw-rec-empty {
  padding: 18px 12px; text-align: center; font-size: 13px; color: var(--muted);
  border: 1px dashed var(--line); border-radius: var(--radius);
}
.tw-rec-card {
  display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 12px; cursor: pointer;
  border: 1px solid var(--line); border-left: 3px solid var(--tw-rec-line);
  border-radius: var(--radius-sm); background: var(--paper);
  transition: border-color .15s, box-shadow .15s;
}
.tw-rec-card:hover { border-color: var(--tw-rec-line); box-shadow: 0 2px 10px var(--shadow-soft); }
.tw-rec-icon {
  flex: none; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: var(--tw-rec-bg); color: var(--tw-rec-line);
}
.tw-rec-what { flex: 1; min-width: 0; }
.tw-rec-what strong { display: block; font-weight: 600; font-size: 14px; overflow-wrap: anywhere; }
.tw-rec-when { font-size: 12px; margin-top: 2px; color: var(--muted); }
.tw-rec-strip { display: inline-flex; gap: 3px; flex: none; }
.tw-rec-dot {
  width: 24px; height: 22px; border-radius: 6px; display: grid; place-items: center;
  font-size: 11px; color: var(--muted); background: var(--panel-3);
}
.tw-rec-dot.on { background: var(--tw-rec-line); color: var(--paper); font-weight: 700; }
.tw-rec-actions { display: inline-flex; gap: 2px; flex: none; }
.btn.tw-icon-btn {
  width: 30px; height: 30px; min-height: 0; padding: 0; display: inline-grid; place-items: center;
  border-color: transparent; background: transparent; color: var(--text-2);
}
.btn.tw-icon-btn svg { display: block; }
.btn.tw-icon-btn:hover { background: var(--panel-2); border-color: var(--line); color: var(--text); }
.btn.tw-icon-btn.danger:hover { background: var(--danger); border-color: var(--danger); color: var(--ink-rose); }
/* Форма: что делать, дни кнопками, бренд кнопками; внизу — «Удалить» слева. */
.tw-rec-form {
  display: flex; flex-direction: column; gap: 12px; padding: 14px;
  border: 1px solid var(--tw-rec-line); border-radius: var(--radius); background: var(--tw-rec-bg);
}
.tw-rec-form .form-label { font-size: 12px; color: var(--text-2); font-weight: 600; }
.tw-rec-form input { font-size: 14px; padding: 8px 10px; background: var(--paper); }
.tw-rec-when-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.tw-choice { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.tw-choice-btn {
  min-width: 40px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--paper); color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.tw-choice-btn:hover { border-color: var(--tw-rec-line); }
.tw-choice-btn.on { background: var(--tw-rec-line); border-color: var(--tw-rec-line); color: var(--paper); font-weight: 600; }
.tw-choice-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.tw-rec-presets { display: inline-flex; gap: 6px; }
.tw-rec-presets .tw-choice-btn { font-size: 12px; padding: 4px 10px; background: transparent; }
.tw-rec-presets .tw-choice-btn.on { background: var(--paper); color: var(--text); border-color: var(--tw-rec-line); }
.tw-rec-form-actions { display: flex; align-items: center; gap: 8px; }
.tw-rec-form-actions .grow { flex: 1; }
.btn.tw-rec-delete { color: var(--ink-rose); }
.btn.tw-rec-delete:hover { background: var(--danger); border-color: var(--danger); }
.tw-rec-add {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px; border: 1.5px dashed var(--line); border-radius: var(--radius);
  background: transparent; color: var(--text-2); font: inherit; font-size: 14px; cursor: pointer;
}
.tw-rec-add:hover { border-color: var(--tw-rec-line); color: var(--text); background: var(--tw-rec-bg); }
@media (max-width: 560px) {
  .tw-rec-card { flex-wrap: wrap; }
  .tw-rec-strip { order: 3; margin-left: 46px; }
}

/* Окно приоритетов недели (15.10.2026, её слово: «такой же визуал, как в
   повторяющихся задачах»): те же карточки, форма и пунктирная кнопка, только
   своим, зелёным цветом; номер — в кружке на месте значка. */
.tw-prio-body .tw-rec-card { border-left-color: var(--accent); }
.tw-prio-body .tw-rec-card:hover { border-color: var(--accent); }
.tw-prio-body .tw-rec-icon {
  background: var(--accent-dim); color: var(--ink-green); font-weight: 700; font-size: 14px;
}
.tw-prio-body .tw-rec-form { border-color: var(--accent); background: var(--tile-green-bg-2); }
.tw-prio-body .tw-rec-add:hover { border-color: var(--accent); background: var(--accent-dim); }
.tw-prio-card .tw-check { width: 20px; height: 20px; font-size: 12px; line-height: 17px; margin: 0; }
.tw-prio-card.done .tw-rec-what strong { color: var(--muted); text-decoration: line-through; }
.tw-prio-card.done .tw-rec-icon { background: var(--panel-3); color: var(--muted); }

/* «Задача ДШ20. Работа с товаром» (15.10.2026): задачи товара одной строкой,
   стрелка-значок раскрывает их, под каждой — её подзадачи. */
.tw-group .tw-main { flex: 1 1 auto; }
.tw-group-toggle {
  flex: none; width: 16px; height: 16px; margin-top: 1px; padding: 0; border: 0; border-radius: 4px;
  display: grid; place-items: center; background: transparent; color: var(--tw-subs-line); cursor: pointer;
}
.tw-group-toggle svg { transition: transform .15s; }
.tw-group.open .tw-group-toggle svg { transform: rotate(90deg); }
.tw-group-toggle:hover { background: var(--panel); }
.tw-group-title strong { font-weight: 700; }
.tw-group-count {
  font-size: 11px; line-height: 16px; padding: 0 6px; border-radius: 999px;
  border: 1px solid var(--tw-subs-line); background: var(--panel); color: var(--text-2);
}
.tw-group.done .tw-group-title { color: var(--text-2); }
.tw-group-list { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; cursor: default; }
.tw-group-row {
  display: flex; flex-direction: column; gap: 3px; padding: 5px 6px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
}
.tw-group-row:hover { border-color: var(--tw-subs-line); }
.tw-group-row.tp-current { background: var(--accent-dim); box-shadow: inset 2px 0 0 var(--accent); }
.tw-group-row-main { display: flex; gap: 6px; align-items: flex-start; }
.tw-group-row .tw-text { font-size: 12px; }
.tw-group-row.done .tw-text { color: var(--muted); }
.tw-group-row .tw-subs { margin-left: 22px; }

/* Пустые «Повторяющиеся задачи» и «Приоритеты недели» — узкой строкой с «+»
   (28.10.2026, ответ владелицы). */
.tw-panel-empty { padding: 5px 8px 5px 12px; }
.tw-panel-empty .tw-panel-head { margin-bottom: 0; }
@media (max-width: 900px) {
  .tw-panels, .tw-panels.two { grid-template-columns: 1fr; }
}

/* «Задачи» раздельно (13.10.2026): свои задачи сверху, просьбы фабрик — внизу
   большим блоком; у владелицы — крупный переключатель «Мои задачи / ассистент». */
.task-split { display: flex; flex-direction: column; gap: 14px; }
.task-person-switch {
  display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 4px;
  border-radius: 999px; background: var(--c-f4f1e8-s);
}
.task-person-btn {
  display: inline-flex; align-items: center; gap: 8px;
  border: 0; background: transparent; color: var(--text-2);
  padding: 5px 18px 5px 5px; border-radius: 999px;
  font: inherit; font-size: 15px; cursor: pointer; white-space: nowrap;
}
.task-person-btn:hover { color: var(--text); }
.task-person-btn.on {
  background: var(--paper); color: var(--text); font-weight: 650;
  box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s);
}
.task-person-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.task-person-btn .assign-avatar { width: 28px; height: 28px; font-size: 13px; }
.task-person-late { font-size: 12px; font-weight: 600; color: var(--ink-rose); }
/* Бренд задачника — крупными кнопками (14.10.2026). */
.task-brand-switch { align-self: flex-start; }
.task-brand-btn { padding: 9px 24px; font-size: 16px; }
/* «Личные задачи» — последней кнопкой ряда брендов (27.10.2026; с 21.10 стояли в
   ряду людей), отделены чертой. Значок в кружке — у своей кнопки «Я» ряда людей. */
.task-person-personal { position: relative; margin-left: 9px; }
.task-person-personal::before {
  content: ''; position: absolute; left: -7px; top: 8px; bottom: 8px; width: 1px; background: var(--line);
}
.task-person-icon {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--accent-dim); color: var(--ink-green);
}
.task-person-icon svg { flex: none; }
/* Личная задача во «Всех брендах» — маленькой пометкой рядом с рабочими. */
.tw-personal-mark {
  display: inline-flex; align-items: center; padding: 0 7px; border-radius: 999px;
  background: var(--c-f4f1e8-s); color: var(--text-2); font-size: 12px; line-height: 18px;
}
/* «Проекты» (02.11.2026): задача проекта в плане — его названием; вкладка — карточками. */
.tw-project-mark {
  display: inline-flex; align-items: center; padding: 0 7px; border-radius: 999px; max-width: 180px;
  background: var(--accent-dim); color: var(--ink-green); font-size: 11px; line-height: 18px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-new { display: flex; gap: 8px; align-items: center; margin: 4px 0 14px; max-width: 560px; }
.tp-new input { flex: 1 1 auto; min-width: 0; }
.tp-empty { margin-top: 8px; }
.tp-list { display: flex; flex-direction: column; gap: 12px; }
.tp-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px;
}
.tp-card.done { opacity: .75; }
.tp-head { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.tp-title {
  flex: 1 1 200px; min-width: 0; display: flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--text); overflow-wrap: anywhere;
}
.tp-progress { flex: 0 1 200px; min-width: 140px; display: flex; align-items: center; gap: 8px; font-size: 12px; }
.tp-progress .tw-bar { flex: 1 1 auto; }
.tp-actions { display: flex; gap: 2px; }
.tp-body { margin-top: 8px; padding-left: 26px; display: flex; flex-direction: column; gap: 2px; }
.tp-toggle svg { transition: transform .15s; }
.tp-toggle.on svg { transform: rotate(90deg); }
.tp-project-select { max-width: 100%; min-width: 0; font-size: 13px; }
.tp-done-toggle { margin-top: 16px; margin-bottom: 8px; font-size: 13px; line-height: 22px; padding: 0 10px; }
@media (max-width: 640px) {
  .tp-body { padding-left: 0; }
  .tp-new { flex-wrap: wrap; }
}
.task-lane {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px 12px;
}
.task-lane.task-own { border-color: var(--accent); }
.task-lane-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
  font-family: var(--font-display); font-size: 15px; color: var(--text);
}
.task-lane-head .lane-count { margin-left: 0; }
.task-given-line {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); font-size: 13px;
}
button.task-assigned-who {
  border: 0; background: transparent; font: inherit; color: var(--text); cursor: pointer;
  padding: 2px 6px; border-radius: 999px;
}
button.task-assigned-who:hover { background: var(--panel-2); }
/* Просьбы фабрик (13.10.2026, её слово: «поспокойнее, крупнее — какая фабрика,
   что спрашивает; каждая фабрика — отдельным пластом»): у каждой фабрики своя
   карточка, имя крупно, просьбы строками под ним; без красных плашек. */
.task-factory-block { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.task-factory-head { flex-wrap: wrap; gap: var(--gap); margin-bottom: 0; }
.task-factory-head .tw-h { font-size: 22px; }
.task-factory-head .task-board-head { margin-left: auto; }
.task-factory-cards { display: flex; flex-direction: column; gap: 12px; }
.task-factory-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px 6px;
}
.task-factory-name {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px;
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.task-factory-label {
  font-family: var(--font-display); font-size: 18px; font-weight: 600; color: var(--text);
}
.task-factory-count { font-size: 13px; color: var(--muted); }
.task-factory-card .task-list > .task-row { padding: 11px 6px; }
.task-factory-card .task-row .task-text { font-size: 14px; line-height: 1.45; }
.task-factory-card .task-age.age-warm,
.task-factory-card .task-age.age-hot { background: transparent; color: var(--muted); }
.task-row.task-request { align-items: center; }
.task-answer-toggle {
  flex: none; display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden;
}
.task-answer-toggle button {
  border: 0; background: transparent; font: inherit; font-size: 13px; padding: 4px 12px;
  color: var(--muted); cursor: pointer;
}
.task-answer-toggle button.on { background: var(--panel-3); color: var(--text-2); cursor: default; }
.task-answer-toggle button:not(.on):hover { background: var(--tile-green-bg); color: var(--ink-green); }
/* «Ответили» на месте (27.10.2026): переключатель зеленеет, строка сворачивается. */
.task-answered .task-answer-toggle button.on { background: var(--tile-green-bg); color: var(--ink-green); }
/* Снимки, о которых просьба, — сразу под текстом. */
.task-ref-photos { display: flex; gap: 6px; flex-wrap: wrap; margin: 2px 0; }
.task-ref-photo {
  padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden;
  background: var(--panel-2); cursor: zoom-in; width: 64px; height: 64px; flex: none;
}
.task-ref-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Переписка вокруг просьбы — как в WeChat: наши справа, сама просьба выделена. */
.task-chat-lines { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.task-chat-line {
  align-self: flex-start; max-width: 88%; padding: 5px 9px; border-radius: var(--radius-sm);
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.task-chat-line.ours { align-self: flex-end; background: var(--tile-green-bg); }
.task-chat-line.request { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.task-chat-who { font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.task-chat-line .task-source-text, .task-chat-line .task-source-ru { margin-top: 0; }
.task-chat-line .task-ref-photo { width: 120px; height: 120px; }
.tp .task-ref-photos .task-ref-photo { width: 110px; height: 110px; }
@media (max-width: 560px) {
  .task-row.task-request { flex-wrap: wrap; }
  .task-factory-head .task-board-head { margin-left: 0; }
}

/* «Нарезать из готовых» / «Заказать новые» (14.10.2026, просьба владелицы: «крупными и не
   выделяй заранее один из них»): окно «… запрашивает КИЗы» и шаг «КИЗы» окна «+ Заказ».
   Две равные крупные кнопки со значком, ни одна не залита; узко — одна под другой. */
.kiz-choice { display: flex; flex-wrap: wrap; gap: var(--gap); margin: 14px 0 4px; }
.kiz-choice-btn {
  flex: 1 1 200px; min-height: 58px;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--gap);
  padding: 10px 16px; border-radius: var(--radius);
  border: 2px solid var(--accent); background: var(--panel); color: var(--text);
  font: inherit; font-size: 16px; font-weight: 700; line-height: 1.2; cursor: pointer;
  transition: background .15s ease, transform .15s ease;
}
.kiz-choice-btn svg { flex: none; width: 24px; height: 24px; }
.kiz-choice-btn:hover:not(:disabled) { background: var(--accent-dim); transform: translateY(-1px); }
.kiz-choice-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 2px; }
.kiz-choice-btn:disabled { border-color: var(--line); color: var(--muted); cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) { .kiz-choice-btn { transition: none; } }
.nw-discard { color: var(--ink-rose); }
/* Окно «Нарезать готовые КИЗы»: строка заказа — артикул, количество, файл. */
.kiz-cut-rows { display: flex; flex-direction: column; gap: var(--gap); margin: 10px 0; }
.kiz-cut-row {
  display: grid; grid-template-columns: minmax(120px, 1fr) 90px minmax(180px, 2fr);
  gap: 6px 10px; align-items: center;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.kiz-cut-row .kiz-cut-note { grid-column: 1 / -1; margin: 0; }
.kiz-cut-row .kiz-cut-note:empty { display: none; }
.kiz-cut-qty, .kiz-cut-source { width: 100%; min-width: 0; }
@media (max-width: 560px) {
  .kiz-cut-row { grid-template-columns: 1fr 80px; }
  .kiz-cut-row .kiz-cut-source { grid-column: 1 / -1; }
}

/* «+ драфт» в карточке товара: выбор образца, когда их несколько (13.10.2026). */
.redraft-pick { display: flex; flex-direction: column; gap: 8px; }
.redraft-pick-item { justify-content: flex-start; text-align: left; }

/* ── ДОСЬЕ ЮНИТА В УЗКОМ МЕСТЕ ────────────────────────────────────────────
   Одна и та же разметка стоит правой колонкой «Продуктов» (там метров семь
   ширины) и боковой панелью поверх раздела (404 px). Мерится ширина САМОГО
   досье (`container-type` у `.dossier`), а не окна: на большом экране панель
   иначе получала вёрстку широкой колонки — две колонки по 170, внутри ещё две
   по 80, шесть кнопок этапов в ряд, — и текст лез за края.

   Блок стоит последним в файле нарочно: `@container` не добавляет селектору
   веса, и правила из середины файла (образцы, лента, кнопки) перебивали бы
   его при равной специфичности. */
@container dossier (max-width: 460px) {
  .dossier { padding: 14px; gap: 12px; }
  /* 24 px именем в 370 px панели съедали строку заголовка целиком, и этап с
     номером образца уезжали на третий ряд. */
  .dossier-name { font-size: 19px; }
  /* «Скрипты» прижималась вправо и в перенесённом ряду стояла одна посреди
     пустоты — в узком досье она просто идёт следующей. */
  .dossier-script { margin-left: 0; }
  /* Дата записи занимала 128 px из 340 — на текст оставалась треть строки.
     Ставим её отдельной строкой над текстом. */
  .tl-date { flex: 0 0 100%; }
  .card-timeline li { gap: 2px 11px; }
  /* Подпись образца в одну строку с многоточием прятала то, ради чего её
     читают: фабрику, цену и срок. В узком месте она переносится. */
  .card-sample-sub { white-space: normal; overflow: visible; text-overflow: clip; }
  /* Кнопка перестаёт быть «хвостом» строки и встаёт своей строкой слева, не
     отнимая ширину у подписи образца. Перенос делает сама подпись (основа
     100%), а кнопка остаётся по содержимому — во всю строку она читалась бы
     как главное действие карточки, а это не так. */
  .card-sample-main { flex: 1 1 100%; }
  .card-sample > .btn { margin-left: 0; flex: 0 0 auto; }
  .card-ready { flex-direction: column; align-items: flex-start; }
}
@container dossier (max-width: 330px) {
  /* Совсем узкое место (панель на маленьком экране): этапы по два в ряд,
     показатели — в одну колонку: две по 150 px уже врут про содержимое. */
  .stage-step { flex: 1 1 128px; }
  .stat-grid.two { grid-template-columns: minmax(0, 1fr); }
  .dossier { padding: 12px; }
}

/* ДОСЬЕ ВНУТРИ БОКОВОЙ ПАНЕЛИ — БЕЗ ВТОРОЙ РАМКИ.
   `.dossier` носит собственный фон, тень и отступ 18/20: в правой колонке
   «Продуктов» это его карточка, а в панели она ложилась внутрь такой же
   карточки — двойная рамка, двойной отступ и на 40 px меньше места под
   содержимое. И название стояло дважды: крупным в шапке панели и таким же
   крупным первой строкой досье.

   Стоит после запросов к контейнеру нарочно: они тоже правят отступ досье, и
   при равном весе селектора побеждает тот, кто ниже. */
.dossier-in-drawer {
  background: transparent; box-shadow: none; padding: 0; border-radius: 0;
}
.dossier-in-drawer > .dossier-top > .dossier-name { display: none; }

/* «Собрать для фабрики» (01.10.2026, ui/order-pack.js): карточка на товар
   заказа — что в порядке, чего не хватает и кнопка, которая это исправит.
   Проблемная карточка отбита розовой чертой слева, готовая — зелёной. */
.order-pack-progress { min-height: 18px; margin-bottom: 8px; }
.order-pack-list, .order-pack-result { display: flex; flex-direction: column; gap: var(--gap); }
.order-pack-result:not(:empty) { margin-top: 12px; }
.order-pack-card {
  border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: var(--radius-sm); padding: 10px 12px; background: var(--panel);
  display: flex; flex-direction: column; gap: 6px;
}
.order-pack-card.problem { border-left-color: var(--danger); }
.order-pack-card.done { border-left-color: var(--ok); }
.order-pack-title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 600; font-size: 14px;
}
.order-pack-problem { font-size: 13px; }
.order-pack-warnings { display: flex; flex-direction: column; gap: 2px; }
.order-pack-root { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.order-pack-uploads { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.order-pack-uploads .row-actions { margin: 0; }
/* «Папка товара» (13.11.2026, app.js `labelsPanel`): выбор этикетки и фото — одной строкой. */
.labels-form { display: flex; align-items: center; gap: 10px 18px; flex-wrap: wrap; margin: 12px 0; }
.labels-field { display: flex; align-items: center; gap: 8px; }
.labels-field select { min-width: 220px; }
.labels-check { display: flex; align-items: center; gap: 6px; }
.labels-form + .btn { margin-bottom: 12px; }

/* «+ Заказ» по шагам (02.10.2026, ui/index.html `#new-modal`, app.js `nwRender`):
   полоса шагов под шапкой, на экране один шаг, кнопки шага — в подвале окна.
   Окно шире прежнего узкого: в шаге «Архив» стоят карточки товаров сборки. */
.nw-panel { width: min(720px, calc(94vw - var(--chat-room))); }
/* Высота шага не прыгает от шага к шагу, но на низком экране уступает: иначе
   подвал с кнопками уехал бы за край окна. */
.nw-panel .modal-body { min-height: min(240px, 30vh); }
.nw-steps {
  display: flex; gap: 6px; margin: 0; padding: 10px var(--pad-lg);
  list-style: none; border-bottom: 1px solid var(--line);
}
.nw-steps li { flex: 1 1 0; min-width: 0; }
.nw-step {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: var(--radius-sm); border: 1px solid transparent;
  background: var(--panel-6); color: var(--muted);
  font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.nw-step:disabled { cursor: default; }
.nw-step:hover:not(:disabled) { border-color: var(--gossamer-green); }
.nw-step:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 2px; }
.nw-num {
  flex: none; width: 22px; height: 22px; border-radius: 999px;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700;
  background: var(--panel); border: 1px solid var(--line);
}
.nw-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nw-step.done { background: var(--tile-green-bg); color: var(--ink-green); }
.nw-step.done .nw-num { background: var(--accent); border-color: var(--accent); color: var(--on-accent-strong); }
.nw-step.now { background: var(--tile-yellow-bg); color: var(--ink-yellow); font-weight: 600; }
.nw-step.now .nw-num { border-color: var(--ink-yellow); }
/* Узкое окно (браузер ассистентки, телефон): у прочих шагов — только номер,
   название остаётся у текущего, а не обрезается у всех четырёх до «Бл…». */
@media (max-width: 560px) {
  .nw-steps li { flex: 0 0 auto; }
  .nw-steps li:has(.nw-step.now) { flex: 1 1 auto; }
  .nw-step:not(.now) .nw-name { display: none; }
}
/* То же, когда окно сузила открытая панель Гермеса (`--chat-room` 400 px). */
@media (min-width: 900px) and (max-width: 1050px) {
  body.chat-open .nw-steps li { flex: 0 0 auto; }
  body.chat-open .nw-steps li:has(.nw-step.now) { flex: 1 1 auto; }
  body.chat-open .nw-step:not(.now) .nw-name { display: none; }
}

/* Шаг «Бланк»: большая рамка с одной кнопкой — в неё же можно бросить файл.
   Файл выбран — рамка сжимается в строку «имя файла · Убрать файл». */
.nw-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 34px 16px; text-align: center;
  border: 2px dashed var(--line); border-radius: var(--radius); background: var(--panel-2);
}
.nw-drop.over { border-color: var(--accent); background: var(--accent-dim); }
/* Выбрали «без бланка» — рамка уступает место полям, но бланк выбрать по-прежнему можно. */
.nw-drop.slim { flex-direction: row; flex-wrap: wrap; justify-content: flex-start; padding: 10px 12px; text-align: left; }
.nw-drop:has(#imp-clear:not(.hidden)) {
  flex-direction: row; justify-content: flex-start; flex-wrap: wrap;
  padding: 9px 12px; border-style: solid; border-width: 1px; text-align: left;
}
.nw-drop:has(#imp-clear:not(.hidden)) #imp-pick { display: none; }
.nw-drop:has(#imp-clear:not(.hidden)) #imp-name { color: var(--text); font-weight: 600; }
.nw-drop:has(#imp-clear:not(.hidden)) ~ .nw-manual { display: none; }
.nw-manual { display: block; margin: 8px auto 0; }
.nw-pane #imp-plan:not(:empty) { margin-top: 12px; }
#nw-fields { margin-top: 12px; }
.nw-pane .ask-to-slot { margin-bottom: 8px; }
/* Бланк читается или записывается (09.10.2026, просьба владелицы: «показывать
   визуально процесс подгрузки — кружочек или шкалу»): кружок, слова и бегущая
   полоса. Сколько осталось, сервер не говорит — полоса бежит, а не заполняется. */
.nw-busy {
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 8px 10px;
  padding: 12px 14px; margin: 8px 0; border-radius: var(--radius);
  background: var(--accent-dim); border: 1px solid var(--accent);
}
.nw-busy .spinner { width: 20px; height: 20px; border-width: 3px; border-top-color: var(--ink-green); }
.nw-busy-text { color: var(--ink-green); }
.nw-busy-text { font-weight: 600; }
.nw-busy-bar {
  grid-column: 1 / -1; height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--line); position: relative;
}
.nw-busy-bar::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -40%; width: 40%;
  border-radius: 3px; background: var(--ink-green); animation: nw-busy-run 1.2s ease-in-out infinite;
}
@keyframes nw-busy-run { to { left: 100%; } }
@media (prefers-reduced-motion: reduce) { .nw-busy-bar::after { animation-duration: 3s; } }
/* Сборка файла заказа (09.10.2026, ui/order-pack.js `orderPackBusy`): та же
   плашка, но сервер знает, сколько впереди, — полоса заполняется, справа
   процент, снизу какая папка и сколько файлов и мегабайт уже в архиве. */
.order-pack-busy { grid-template-columns: auto 1fr auto; margin: 0 0 4px; }
.nw-busy-pct { color: var(--ink-green); font-weight: 700; font-variant-numeric: tabular-nums; }
.nw-busy-pct:empty { display: none; }
.nw-busy-bar.known::after { display: none; }
.nw-busy-fill {
  height: 100%; width: 0; border-radius: 3px; background: var(--ink-green);
  transition: width .5s ease;
}
.nw-busy-detail {
  grid-column: 1 / -1; color: var(--muted); font-size: 13px;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.nw-busy-detail:empty { display: none; }
/* Кружок со словами у кнопки: «Кладу «S.pdf» на Диск…», «Читаю файл…». */
.order-pack-note { display: inline-flex; align-items: center; gap: 6px; }

/* ПОЛОСА ХОДА НА НАЖАТОЙ КНОПКЕ (13.10.2026, `NadosBusy` в ui-kit.js): кнопка, после
   которой CRM работает, сама становится полосой. Слой лежит ПОД подписью (`z-index: -1`
   внутри `isolation`), поэтому ни ширина, ни текст кнопки не меняются. Заливка — мятой,
   снизу толстая черта; на мятной главной кнопке — цветом подписи, иначе её не видно. */
.busy-at { position: relative; }
.is-busy { --busy: 0; isolation: isolate; cursor: progress; }
.is-busy:disabled { opacity: 1; cursor: progress; }
.busy-bar {
  position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none;
  border-radius: inherit; box-shadow: inset 0 -4px 0 color-mix(in srgb, var(--accent) 35%, transparent);
}
.busy-fill {
  position: absolute; top: 0; bottom: 0; left: -45%; width: 45%;
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: inset 0 -4px 0 var(--accent);
  animation: busy-run 1.1s ease-in-out infinite;
}
.btn-primary > .busy-bar, .kiz-tab.on > .busy-bar {
  box-shadow: inset 0 -4px 0 color-mix(in srgb, currentColor 25%, transparent);
}
.btn-primary > .busy-bar .busy-fill, .kiz-tab.on > .busy-bar .busy-fill {
  background: color-mix(in srgb, currentColor 18%, transparent);
  box-shadow: inset 0 -4px 0 color-mix(in srgb, currentColor 75%, transparent);
}
.busy-known .busy-fill {
  left: 0; width: calc(var(--busy) * 100%); animation: none; transition: width .4s ease;
}
@keyframes busy-run { to { left: 100%; } }
@media (prefers-reduced-motion: reduce) { .busy-fill { animation-duration: 3s; } }

/* Подвал: второстепенное слева, главное справа. */
.nw-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px var(--pad-lg); border-top: 1px solid var(--line);
}
/* Кнопок у шага нет (бланк ещё не выбран) — нет и пустой полосы. */
.nw-foot:not(:has(.btn:not(.hidden))) { display: none; }
.nw-foot-side { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nw-foot-side:last-child { justify-content: flex-end; }

/* Окно бренда по шагам (27.10.2026, app.js `openBrandForm`): полоса шагов и
   подвал — от «+ Заказ». Высота окна постоянная: от шага к шагу оно не прыгает,
   длинный список листается внутри шага. */
#entity-modal[data-brand-form] .modal-panel {
  width: min(680px, calc(94vw - var(--chat-room))); height: min(620px, 88vh);
}
#entity-modal[data-brand-form] .modal-body {
  flex: 1 1 auto; min-height: 0; padding: 0; overflow: hidden;
  display: flex; flex-direction: column;
}
.bf-pane { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 18px var(--pad-lg); }
.bf-fields { gap: 16px; }
.bf-fields .form-label { font-size: 12px; }
.bf-fields input { font-size: 15px; padding: 9px 12px; }
.bf-pane .ms-brand-row { margin-top: 16px; }
/* «Размещаем заказы / Только образцы» — два слова вместо галочки со «ⓘ». */
.bf-seg {
  display: inline-flex; width: fit-content; gap: 4px; padding: 4px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel-6);
}
.bf-seg label { position: relative; }
.bf-seg input { position: absolute; opacity: 0; pointer-events: none; }
.bf-seg span {
  display: block; padding: 7px 16px; border-radius: var(--radius-sm);
  font-size: 13px; color: var(--muted); cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.bf-seg span:hover { color: var(--text); }
.bf-seg input:checked + span { background: var(--accent); color: var(--ink); font-weight: 600; }
.bf-seg input:focus-visible + span { outline: 2px solid var(--ink-green); outline-offset: 1px; }
/* Чаты и контрагенты — плитками в две колонки: длинный список читается вдвое быстрее. */
.bf-search { width: 100%; margin-bottom: 14px; }
.bf-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.bf-list > .hint { grid-column: 1 / -1; margin-top: 0; }
.bf-group {
  grid-column: 1 / -1; margin-top: 12px;
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.bf-group:first-child { margin-top: 0; }
.bf-tile {
  display: flex; align-items: center; gap: var(--gap); min-width: 0;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.bf-tile:hover { border-color: var(--gossamer-green); }
.bf-tile:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); }
.bf-tile input { flex: none; margin: 0; }
.bf-tile .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bf-nm { font-size: 14px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.bf-hint { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
/* «Функции» бренда (02.11.2026): галочка внутри другой функции (ОТК в «Заказах») — сдвинута
   под неё; держит отмеченную — «Нужно для …» и замок (галочка серая); «Включится ещё» — ниже. */
.bf-modules { margin-top: 10px; }
.bf-tile.bf-inside { margin-left: 22px; }
.bf-tile:has(input:disabled) { cursor: default; }
.bf-lock { font-size: 12px; color: var(--ink-yellow); font-weight: 600; }
.bf-lock::before { content: '🔒 '; }
.bf-modules-note {
  display: flex; flex-direction: column; gap: 2px; margin-top: 12px; padding: 10px 12px;
  border-radius: var(--radius); background: var(--c-fbf5da-s); color: var(--ink-yellow); font-size: 13px;
}
.bf-modules-note .bf-nm { color: inherit; font-size: 13px; }
/* Сколько отмечено — кружком на полосе шагов. */
.bf-count {
  margin-left: auto; flex: none; min-width: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--accent); color: var(--ink); font-size: 11px; font-weight: 700;
  line-height: 18px; text-align: center;
}
.bf-count:empty { display: none; }

/* ── «Финансы» владелицы (04.10.2026) ─────────────────────────────────────
   Кнопка в самом верху стартовой страницы и свой экран поверх неё: выше
   стартовой (30), ниже окон (40) — формы и вопросы встают поверх. */
.gate-finance {
  display: flex; align-items: center; gap: var(--gap); width: fit-content;
  margin: 0 auto 22px; padding: 10px 22px 10px 12px;
  font: inherit; font-size: 16px; font-weight: 600; color: var(--text);
  background: var(--panel); border: 1px solid var(--fin-now); border-radius: 999px;
  cursor: pointer;
}
.gate-finance:hover { background: var(--fin-track); }
.gate-finance-icon {
  display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
  background: var(--fin-now); color: var(--paper); font-weight: 700;
}

/* Открытая панель Гермеса (05.11.2026) — «Финансы» отступают от неё, а не уходят под неё. */
.fin { position: fixed; inset: 0 var(--chat-room) 0 0; z-index: 35; overflow: auto; background: var(--bg); }
.fin-inner { width: min(1080px, 100%); margin: 0 auto; padding: 18px 16px 56px; }
.fin-top { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.fin-title { margin: 0; flex: 1; font-family: var(--font-display); font-size: 26px; font-weight: 600; }
.fin-error { padding: 24px; color: var(--ink-rose); }
.fin-body { display: flex; flex-direction: column; gap: 18px; }

.fin-hero {
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 20px 22px 18px;
}
.fin-hero-label { font-size: 13px; color: var(--muted); }
.fin-hero-value {
  font-family: var(--font-display); font-size: 52px; font-weight: 600; line-height: 1.05;
  margin: 2px 0 14px; letter-spacing: -.5px;
}
.fin-parts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px 18px; }
.fin-part-label { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 4px; }
.fin-part-value { font-size: 17px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Откуда свободные деньги — во всю ширину под плитками (13.10.2026). */

.fin-goal { margin-top: 18px; }
.fin-goal-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; color: var(--text-2); margin-bottom: 6px; }
.fin-meter {
  position: relative; height: 16px; border-radius: 999px; overflow: hidden;
  background: var(--fin-track);
}
.fin-meter-now, .fin-meter-later { position: absolute; top: 0; bottom: 0; left: 0; }
.fin-meter-now { background: var(--fin-now); border-radius: 999px; }
/* Будущее — штриховкой того же тона: «ещё не наше», но по пути. */
.fin-meter-later {
  background: repeating-linear-gradient(135deg, var(--fin-later) 0 6px, var(--fin-track) 6px 10px);
  border-radius: 0 999px 999px 0;
}
.fin-meter-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 8px; font-size: 13px; }
.fin-key { display: inline-flex; align-items: center; gap: 6px; }
.fin-swatch { width: 14px; height: 10px; border-radius: 3px; display: inline-block; }
.fin-swatch.now { background: var(--fin-now); }
.fin-swatch.later {
  background: repeating-linear-gradient(135deg, var(--fin-later) 0 3px, var(--fin-track) 3px 5px);
  border: 1px solid var(--fin-later);
}
.fin-goal-note { margin-top: 6px; font-size: 13px; color: var(--muted); }

.fin-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.fin-tile { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.fin-tile-label { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 4px; }
.fin-tile-value { font-family: var(--font-display); font-size: 26px; font-weight: 600; margin: 4px 0 6px; }
.fin-tile-note { font-size: 12px; color: var(--muted); display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }

.fin-badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.fin-badge.ok { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.fin-badge.low { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }

.fin-section-title {
  display: flex; align-items: center; gap: 6px;
  margin: 6px 0 10px; font-family: var(--font-display); font-size: 19px; font-weight: 600;
}
.fin-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; }
.fin-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; min-width: 0;
}
.fin-card.fin-drop { border-color: var(--fin-now); background: var(--fin-track); }
.fin-card.fin-loading { opacity: .75; }
.fin-card-done { opacity: .6; }
.fin-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.fin-card-title { font-weight: 600; font-size: 15px; }
.fin-big { font-family: var(--font-display); font-size: 24px; font-weight: 600; margin-top: 2px; }
.fin-line { font-size: 13px; color: var(--text-2); }
.fin-muted { color: var(--muted); font-size: 12px; }
.fin-up { color: var(--ink-green); }
.fin-down { color: var(--ink-rose); }
.fin-rate { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
.fin-rate-value { font-weight: 600; font-size: 14px; }
.fin-warn { font-size: 12px; color: var(--ink-rose); }
.fin-empty { color: var(--muted); font-size: 14px; padding: 6px 0; }
.fin-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.fin-busy { font-size: 12px; color: var(--muted); }
.fin-add { margin-top: 10px; }
.fin-add-top { margin: 0 0 10px; }
.fin-folds { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.fin-fold > summary { cursor: pointer; font-size: 13px; color: var(--text-2); }
.fin-list { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 2px; }
.fin-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; align-items: center;
  padding: 6px 8px; border-radius: var(--radius-sm); background: var(--panel-2); font-size: 13px;
}
.fin-row-main { font-weight: 600; }
.fin-row-note { grid-column: 1; color: var(--muted); font-size: 12px; }
.fin-row-tools { grid-column: 2; grid-row: 1 / span 2; display: flex; gap: 4px; }
.fin-row > .fin-warn { grid-column: 1 / -1; }

.fin-table-wrap { overflow-x: auto; }
.fin-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fin-table th { text-align: left; font-weight: 500; color: var(--muted); font-size: 12px; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.fin-table td { padding: 7px 8px; border-bottom: 1px solid var(--line-4); }
.fin-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fin-table .fin-strong { font-weight: 600; }
.fin-table tr.fin-current td { background: var(--panel-2); }
.fin-positions td { padding: 4px 6px; }
.fin-check { display: flex; align-items: center; gap: 8px; font-size: 13px; grid-column: 1 / -1; }
.fin-month { display: flex; gap: 6px; }
.fin-month > * { flex: 1 1 0; min-width: 0; }
.fin-form-error { color: var(--ink-rose); font-size: 13px; min-height: 0; margin-top: 8px; }
.fin-form-error:empty { display: none; }

/* Займ частями: строка выдачи — день, сумма, убрать. */
.fin-parts-rows { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }
.fin-part-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 6px; align-items: center; }
.fin-parts-edit > .btn { justify-self: start; width: fit-content; }

/* «Почему такой процент»: строки со знаком, итог под чертой, факты списком. */
.fin-why-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.fin-why-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 13px; }
.fin-why-label { color: var(--text-2); display: inline-flex; align-items: center; gap: 4px; }
.fin-why-amount { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 600; }
.fin-why-total { border-top: 1px solid var(--line); padding-top: 6px; margin-top: 2px; font-size: 14px; }
.fin-why-total .fin-why-label { color: var(--text); font-weight: 600; }
.fin-why-facts { margin: 10px 0 0; padding-left: 18px; font-size: 13px; color: var(--text-2); display: flex; flex-direction: column; gap: 4px; }
/* Панель бумаги (14.11.2026): пояснение под строкой и пункты сразу под заголовком блока. */
.fin-why-sub { font-size: 12px; color: var(--muted); }
.fin-sp-block > .fin-why-list { margin-top: 0; }
.fin-sp-block > .fin-why-facts { margin-top: 0; }
/* «По компаниям» (14.11.2026): переключатель вида, строка компании свёрткой, её бумаги — с отступом. */
.fin-sec-view { width: fit-content; margin-bottom: 10px; }
.fin-sec-co { border-bottom: 1px solid var(--line-4); }
.fin-sec-co > summary { list-style: none; cursor: pointer; border-radius: var(--radius-sm); }
.fin-sec-co > summary::-webkit-details-marker { display: none; }
.fin-sec-co > summary:hover, .fin-sec-co > summary:focus-visible { background: var(--panel-2); }
.fin-sec-co > summary .fin-sec-title { display: flex; align-items: baseline; gap: 4px; }
.fin-sec-co[open] > summary .fin-chev { transform: rotate(90deg); }
.fin-sec-co.fin-sec-alarm > summary { box-shadow: inset 3px 0 0 var(--ink-rose); }
.fin-sec-co-body { padding-left: 16px; }
.fin-sec-co-body > .fin-verdicts { margin: 4px 0 8px; }
/* Личные и бизнес-расходы (14.11.2026): бренды галочками, окно «Куда записать?». */
.fin-brand-pick { display: flex; gap: 6px; flex-wrap: wrap; }
.fin-brand-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--line);
  border-radius: 999px; font-size: 13px; cursor: pointer; background: var(--panel);
}
.fin-brand-chip:has(input:checked) { background: var(--tile-green-bg); border-color: transparent; }
.fin-brand-chip { white-space: nowrap; }
.fin-brand-chip input { width: auto; flex: 0 0 auto; margin: 0; }
.fin-card.fin-asks-card { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; text-align: left; }
.fin-asks { display: flex; flex-direction: column; gap: 8px; }
.fin-ask { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border: 1px solid var(--line-4); border-radius: var(--radius-sm); }
.fin-ask-head { display: flex; flex-direction: column; gap: 2px; }
.fin-ask-main { font-weight: 600; }
.fin-ask-buttons { display: flex; gap: 6px; flex-wrap: wrap; }
.fin-ask-work { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
/* «Прибыль к дате» (14.11.2026): крупная кнопка в шапке и окно расчёта. */
.fin-todate-btn { font-size: 15px; padding: 9px 18px; margin-left: auto; }
.fin-td { display: flex; flex-direction: column; gap: 14px; }
.fin-td-day { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fin-td-label { font-weight: 600; }
.fin-td-day input[type="date"] { width: auto; min-width: 160px; }
.fin-td-quick { display: flex; gap: 6px; flex-wrap: wrap; }
.fin-td-total { background: var(--panel-2); border-radius: var(--radius); padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; }
.fin-td-total-value { font-family: var(--font-display); font-size: 32px; font-weight: 600; font-variant-numeric: tabular-nums; }
.fin-td-total-day { color: var(--muted); font-size: 13px; }
.fin-td-total.fin-loading { opacity: .55; }
.fin-td-list { display: flex; flex-direction: column; gap: 12px; }
.fin-td-group { display: flex; flex-direction: column; gap: 2px; }
.fin-td-group-head { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; padding: 4px 0; cursor: pointer; }
.fin-td-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center;
  padding: 6px 4px 6px 22px; border-top: 1px solid var(--line-4); cursor: pointer;
}
.fin-td-row.off .fin-td-words, .fin-td-row.off .fin-td-amount { opacity: .5; }
.fin-td-words { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fin-td-name { font-size: 14px; }
.fin-td-amount { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 600; }
/* Проверки плитками ✓ / ? / ✕ (14.11.2026): нажатие раскрывает подробности. */
.fin-verdicts { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px; align-items: start; }
.fin-verdict { background: var(--panel-2); border: 1px solid var(--line-4); border-radius: var(--radius-sm); }
.fin-verdict > summary {
  list-style: none; cursor: pointer; display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; border-radius: var(--radius-sm);
}
.fin-verdict > summary::-webkit-details-marker { display: none; }
.fin-verdict > summary:hover, .fin-verdict > summary:focus-visible { background: var(--panel-3); }
.fin-verdict-icon {
  flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; line-height: 1;
}
.fin-verdict.ok .fin-verdict-icon { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.fin-verdict.wait .fin-verdict-icon { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fin-verdict.bad .fin-verdict-icon { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.fin-verdict.bad { box-shadow: inset 3px 0 0 var(--ink-rose); }
.fin-verdict-words { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fin-verdict-title { font-size: 12px; color: var(--muted); }
.fin-verdict-text { font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.fin-verdict-detail { padding: 0 10px 10px 40px; font-size: 13px; line-height: 1.45; color: var(--text-2); }
.fin-sec-co-body > .fin-sec-item:last-child { border-bottom: 0; }

@media (max-width: 640px) {
  .fin-hero-value { font-size: 40px; }
  .fin-cards { grid-template-columns: 1fr; }
}

/* ── «Финансы» 09.10.2026: вкладки, месяц, цель, риски, расходы, графики ── */
.fin-tabs-wrap { overflow-x: auto; margin: -4px 0 16px; padding-bottom: 2px; }
.fin-tabs { flex-wrap: nowrap; }
.fin-head-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.fin-toolbar { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.fin-month-tabs { max-width: 100%; overflow-x: auto; }

/* Распределение месяца: вложено, потрачено, остаток дорожкой; между кусками —
   два пикселя фона карточки, концы полосы скруглены. */
.fin-stack { display: flex; gap: 2px; height: 14px; border-radius: 4px; overflow: hidden; margin: 10px 0 2px; }
.fin-seg { min-width: 2px; flex-basis: 0; }
.fin-seg.c1, .fin-swatch.c1, .fin-bar-fill.c1 { background: var(--fin-c1); }
.fin-seg.c2, .fin-swatch.c2, .fin-bar-fill.c2 { background: var(--fin-c2); }
.fin-seg.c3, .fin-swatch.c3, .fin-bar-fill.c3 { background: var(--fin-c3); }
.fin-seg.rest, .fin-swatch.rest { background: var(--fin-rest); }
.fin-swatch.mark { width: 2px; height: 12px; border-radius: 1px; background: var(--text); }

.fin-now .fin-card-head { align-items: flex-start; flex-wrap: wrap; }
.fin-now-figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px 16px; margin-top: 8px; }
.fin-figure-label { font-size: 12px; color: var(--muted); }
.fin-figure-value { font-size: 18px; font-weight: 600; }
.fin-figure-accent .fin-figure-value { color: var(--ink-green); }
.fin-now-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px 20px; margin-top: 12px;
  border-top: 1px solid var(--line); padding-top: 10px; }
.fin-now-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fin-now-col-title { font-size: 12px; color: var(--muted); font-weight: 600; }

.fin-badge.mid { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fin-badge.soft { background: var(--panel-3); color: var(--text-2); }
.fin-goal-card .fin-card-head { flex-wrap: wrap; }
.fin-needs { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.fin-need { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 12px; align-items: baseline;
  padding: 8px 10px; border-radius: var(--radius-sm); background: var(--panel-2); }
.fin-need-label { font-size: 13px; color: var(--text-2); display: inline-flex; align-items: center; gap: 4px; }
.fin-need-value { font-size: 16px; font-weight: 600; text-align: right; white-space: nowrap; }
.fin-need-now { grid-column: 1 / -1; font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 4px; }
/* «Откладывать в месяц» раскрывается по портфелям (14.10.2026). */
.fin-need-fold > summary { list-style: none; cursor: pointer; }
.fin-need-fold > summary::-webkit-details-marker { display: none; }
.fin-need-fold > summary:hover .fin-need, .fin-need-fold[open] > summary .fin-need { background: var(--panel-3); }
.fin-need-more { margin-left: auto; color: var(--text-2); }
.fin-need-more::after { content: ' ▸'; }
.fin-need-fold[open] .fin-need-more::after { content: ' ▾'; }
.fin-save-split { display: flex; flex-direction: column; gap: 4px; padding: 6px 10px 2px; }
.fin-save-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 12px; align-items: baseline;
  padding: 6px 0; border-bottom: 1px solid var(--line-4); }
.fin-save-name { font-size: 14px; font-weight: 600; min-width: 0; }
.fin-save-amount { font-size: 15px; font-weight: 600; text-align: right; white-space: nowrap; }
.fin-save-note { grid-column: 1 / -1; font-size: 12px; color: var(--muted); }
.fin-save-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-top: 2px; }
/* Максимум затрат месяца — цифрой крупно (14.10.2026). */
.fin-spend-max-value { font-family: var(--font-display); font-size: 34px; font-weight: 600; line-height: 1.15; margin: 2px 0; }

.fin-risks { display: flex; flex-direction: column; gap: 8px; }
.fin-risk { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px;
  display: flex; flex-direction: column; gap: 4px; }
.fin-risk-high { border-color: var(--tile-rose-line); }
.fin-risk-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fin-risk-title { font-weight: 600; font-size: 14px; }
.fin-risk-text { font-size: 13px; color: var(--text-2); }
.fin-risk-actions { margin-top: 2px; }

/* Полосы по категориям и по доходности: подпись слева, сумма у конца полосы. */
/* Одна сетка на все строки: полосы одной длины шкалы и черта цели на одной вертикали. */
.fin-bars { display: grid; grid-template-columns: minmax(90px, 180px) minmax(0, 1fr) auto; gap: 8px 10px; align-items: center; }
.fin-bar-row { display: contents; }
.fin-bar-name { font-size: 13px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-bar-track { position: relative; height: 12px; }
.fin-bar-fill { height: 100%; border-radius: 0 4px 4px 0; min-width: 2px; }
.fin-bar-mark { position: absolute; top: -3px; bottom: -3px; width: 2px; border-radius: 1px; background: var(--text); }
.fin-bar-value { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }

/* Расходы по месяцам столбцами; черта — обычные расходы. */
.fin-cols { display: flex; align-items: flex-end; gap: var(--gap); height: 170px; overflow-x: auto; padding-top: 4px; }
.fin-col { flex: 1 0 44px; max-width: 72px; height: 100%; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.fin-col-value { font-size: 11px; color: var(--text-2); white-space: nowrap; min-height: 14px; }
.fin-col-area { position: relative; flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.fin-col-bar { width: 24px; border-radius: 4px 4px 0 0; background: var(--fin-c2); min-height: 0; }
.fin-col-now .fin-col-bar { opacity: .75; }
.fin-col-label { font-size: 11px; color: var(--muted); }

/* Путь к цели: линии 2 px, сетка волосяная, цель — линией текста. */
.fin-chart { position: relative; }
.fin-svg { width: 100%; height: auto; display: block; overflow: visible; }
.fin-grid { stroke: var(--line); stroke-width: 1; }
.fin-goal-line { stroke: var(--text-2); stroke-width: 1; }
.fin-axis { fill: var(--muted); font-size: 11px; }
.fin-axis-strong { fill: var(--text-2); font-weight: 600; }
.fin-path { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.fin-path.c1 { stroke: var(--fin-c1); }
.fin-path.c2 { stroke: var(--fin-c2); }
.fin-dot.c1 { fill: var(--fin-c1); stroke: var(--panel); stroke-width: 2; }
.fin-hair { stroke: var(--muted); stroke-width: 1; }
.fin-line-key { display: inline-block; width: 14px; height: 2px; border-radius: 1px; vertical-align: middle; }
.fin-line-key.c1 { background: var(--fin-c1); }
.fin-line-key.c2 { background: var(--fin-c2); }
.fin-tip {
  position: absolute; top: 4px; width: 180px; pointer-events: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 10px;
  box-shadow: 0 4px 14px var(--c-rgba-60-50-35-08-s); font-size: 12px; display: flex; flex-direction: column; gap: 4px;
}
.fin-tip-title { font-weight: 600; }
.fin-tip-row { display: flex; align-items: center; gap: 6px; }
.fin-chart-card .fin-meter-legend { margin: 0 0 6px; }

.fin-flow td.fin-flow-bar { width: 32%; min-width: 120px; }
.fin-day { font-size: 12px; color: var(--muted); font-weight: 600; margin-top: 6px; }
.fin-op-fold > summary { cursor: pointer; list-style: none; display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 10px; align-items: center; padding: 6px 8px; border-radius: var(--radius-sm); }
.fin-op-fold > summary::-webkit-details-marker { display: none; }
.fin-op-fold > summary:hover, .fin-op-fold[open] > summary { background: var(--panel-2); }
.fin-op-fold .fin-row-main { overflow-wrap: anywhere; }
.fin-op-body { display: flex; flex-direction: column; gap: 4px; padding: 4px 8px 10px; }
.fin-op-body .fin-actions { margin-top: 4px; }
/* Категории — одной сеткой на все строки, чтобы поля стояли ровными колонками. */
.fin-cat-list { display: grid; grid-template-columns: minmax(0, 1fr) 110px auto auto; gap: 6px; align-items: center; margin-bottom: 12px; }
.fin-cat-row { display: contents; }
.fin-cat-list .btn { justify-self: start; }
.fin-cat-add { display: grid; grid-template-columns: minmax(0, 1fr) 110px auto; gap: 6px; align-items: center;
  padding-top: 10px; border-top: 1px solid var(--line); }

@media (max-width: 640px) {
  .fin-bars { grid-template-columns: minmax(70px, 110px) minmax(0, 1fr) auto; }
  .fin-cat-list { grid-template-columns: minmax(0, 1fr) 96px auto; }
  .fin-cat-row > .fin-muted { display: none; }
}

/* ── «Финансы» 10.10.2026: выписки банка, подсказки, доходность по бумагам ── */
.fin-upload { display: inline-flex; }
.fin-top { flex-wrap: wrap; }
.fin-bank-busy {
  margin: -8px 0 12px; position: sticky; top: 0; z-index: 5; display: grid; gap: 6px;
  padding: 8px 12px; border-radius: 10px; background: var(--panel); color: var(--text);
  box-shadow: 0 0 0 1px var(--line);
}
/* Полоса загрузки выписок (04.11.2026): бежит, пока доля неизвестна, и заполняется по файлам. */
.fin-bank-busy-bar {
  position: relative; display: block; height: 6px; overflow: hidden; border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}
.fin-bank-busy-fill {
  position: absolute; top: 0; bottom: 0; left: -45%; width: 45%; border-radius: 3px;
  background: var(--accent); animation: busy-run 1.1s ease-in-out infinite;
}
.fin-bank-busy.known .fin-bank-busy-fill {
  left: 0; width: max(6%, calc(var(--busy, 0) * 100%)); animation: none; transition: width .4s ease;
}
/* Окно итога загрузки: по выписке — карточка; чего нет в документе — жёлтой плашкой. */
.fin-result { display: flex; flex-direction: column; gap: 6px; padding: 10px 0; border-bottom: 1px solid var(--line-4); text-align: left; }
.fin-result:last-of-type { border-bottom: 0; }
.fin-result-title { font-weight: 600; font-size: 14px; }
.fin-result-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 3px; font-size: 13px; color: var(--text-2); }
.fin-result-missing { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); border: 1px solid var(--tile-yellow-line-2);
  border-radius: var(--radius-sm); padding: 8px 10px; }
.fin-result-missing .fin-result-list { color: var(--tile-yellow-text); }
.fin-result-missing-title { font-weight: 600; font-size: 13px; margin-bottom: 2px; }
.fin-result-note { font-size: 13px; color: var(--text-2); padding-top: 8px; text-align: left; }
/* «Разобрать»: имя и сумма слева, ответы справа; на узком — ответы под именем. */
.fin-bank-cash { font-size: 13px; color: var(--text-2); }
.fin-bank-inside { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.fin-bank-people { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
.fin-bank-person { border-top: 1px solid var(--line); padding-top: 10px; display: flex; flex-direction: column; gap: 2px; }
.fin-people-switch { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fin-hints { display: flex; flex-direction: column; gap: 6px; }
.fin-hint { font-size: 14px; line-height: 1.45; padding-left: 12px; border-left: 3px solid var(--fin-c2); }
/* Доходность по бумагам: плашки сводки, таблица с прокруткой вбок на узком. */
.fin-sec-cards { grid-template-columns: 1fr; }
.fin-sec-summary { display: flex; gap: 6px; flex-wrap: wrap; margin: 6px 0; }
.fin-sec-table td.fin-sec-name { min-width: 160px; }
.fin-sec-table .fin-badge { white-space: nowrap; }
/* «Финансы» 13.10.2026: что приносят вложения, бумаги свёрнутыми строками, прошлые месяцы. */
.fin-returns { gap: 6px; }
.fin-ret-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; align-items: baseline;
  padding: 8px 0; border-top: 1px solid var(--line-4); }
.fin-ret-label { font-size: 14px; display: flex; align-items: center; gap: 4px; }
.fin-ret-value { font-family: var(--font-display); font-size: 20px; font-weight: 600; white-space: nowrap; }
.fin-ret-note { grid-column: 1 / -1; font-size: 12px; color: var(--muted); }
/* Колонки — постоянной ширины (20.10.2026, её слова: «в твоих таблицах смещены названия
   колонки и значение»): шапка и строки — разные сетки, и у последней колонки `auto`
   ширина была своя у каждой строки — у шапки ноль, у строк ширина плашки «работает».
   Шапка уезжала вправо на ширину плашки. Теперь ширины одни и те же везде. */
.fin-sec-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 110px 110px 84px 112px 196px; gap: 4px 10px;
  align-items: center; padding: 8px 6px; font-size: 13px;
}
.fin-sec-row .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fin-sec-head { color: var(--muted); font-size: 12px; border-bottom: 1px solid var(--line); padding-top: 4px; padding-bottom: 4px; }
.fin-sec-head .num { display: inline-flex; align-items: center; justify-content: flex-end; gap: 3px; }
.fin-sec-item { border-bottom: 1px solid var(--line-4); }
/* С 17.10.2026 бумага не раскрывается на месте — нажатие открывает её боковую панель. */
.fin-sec-item > .fin-sec-row { cursor: pointer; border-radius: var(--radius-sm); }
.fin-sec-item > .fin-sec-row:hover, .fin-sec-item > .fin-sec-row:focus-visible { background: var(--panel-2); }
.fin-sec-item.fin-sec-current > .fin-sec-row { background: var(--panel-3); }
.fin-sec-name { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fin-sec-title { font-weight: 600; overflow-wrap: anywhere; }
.fin-sec-badges { display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.fin-sec-badges .fin-badge { white-space: nowrap; }
.fin-sec-alarm > .fin-sec-row { box-shadow: inset 3px 0 0 var(--ink-rose); }
.fin-sec-body { display: flex; flex-direction: column; gap: 6px; padding: 6px 8px 12px 14px; }
.fin-sec-type { font-size: 13px; color: var(--text-2); }
.fin-lots th, .fin-lots td { padding: 4px 6px; }
/* «Финансы» 17.10.2026: свёрнутые купоны и группы бумаг, боковая панель бумаги. */
.fin-chev { display: inline-block; width: 12px; color: var(--muted); transition: transform .15s; }
details[open] > summary > .fin-chev { transform: rotate(90deg); }
.fin-card-fold > summary, .fin-sec-group > summary {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; cursor: pointer; list-style: none; border-radius: var(--radius-sm);
}
.fin-card-fold > summary::-webkit-details-marker, .fin-sec-group > summary::-webkit-details-marker { display: none; }
.fin-card-fold > summary .fin-card-title { margin: 0; }
.fin-card-fold[open] > summary { margin-bottom: 6px; }
.fin-click { cursor: pointer; }
.fin-click:hover td, .fin-click:focus-visible td { background: var(--panel-2); }
.fin-sec-group { border-top: 1px solid var(--line-4); }
.fin-sec-group > summary { padding: 9px 4px; font-size: 14px; }
.fin-sec-group > summary:hover { background: var(--panel-2); }
.fin-sec-group-n { font-weight: 600; }
.fin-sec-group-sum { font-variant-numeric: tabular-nums; white-space: nowrap; }
.fin-sec-group[open] { padding-bottom: 6px; }
/* «Купоны и погашения» (20.10.2026): этот и следующий месяц, галочка — пришло, красная
   полоса — не по плану, погашение — жирной суммой. */
.fin-pay-month { border-top: 1px solid var(--line-4); }
.fin-pay-month > summary {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; cursor: pointer; list-style: none;
  padding: 9px 4px; font-size: 14px; border-radius: var(--radius-sm);
}
.fin-pay-month > summary::-webkit-details-marker { display: none; }
.fin-pay-month > summary:hover { background: var(--panel-2); }
.fin-pay-month-name { font-weight: 600; }
.fin-pay-month[open] { padding-bottom: 8px; }
.fin-pay-table { table-layout: fixed; }
.fin-pay-table th:nth-child(1), .fin-pay-table td:nth-child(1) { width: 112px; }
.fin-pay-table th:nth-child(3), .fin-pay-table td:nth-child(3) { width: 150px; }
.fin-pay-table th:nth-child(4), .fin-pay-table td:nth-child(4) { width: 300px; }
.fin-pay-name { display: flex; flex-direction: column; gap: 1px; min-width: 0; overflow-wrap: anywhere; }
.fin-pay-status { white-space: nowrap; }
.fin-pay-status .fin-badge { white-space: nowrap; }
.fin-pay-status .btn { margin-left: 6px; }
.fin-pay-principal td.num { font-weight: 600; }
.fin-pay-alarm td:first-child { box-shadow: inset 3px 0 0 var(--ink-rose); }
/* Доходы (20.10.2026): «Изменить» и «Удалить» у карточки, анкета нового дохода кнопками,
   описание для Гермеса. */
.fin-card-tools { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.fin-card-alarm { box-shadow: inset 3px 0 0 var(--ink-rose); }
.fin-income-top { margin: 0 0 14px; }
.fin-income-kinds { display: flex; flex-direction: column; gap: 8px; }
.fin-income-kind {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; cursor: pointer;
  padding: 12px 14px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel); color: var(--text);
  font: inherit;
}
.fin-income-kind:hover, .fin-income-kind:focus-visible { background: var(--panel-2); }
.fin-income-kind-title { font-weight: 600; font-size: 15px; }
.fin-choice { display: flex; flex-wrap: wrap; border-radius: var(--radius); }
.fin-hermes { margin-top: 8px; }
.fin-hermes-note { font-size: 13px; line-height: 1.45; white-space: pre-wrap; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--panel-2); margin: 6px 0; }
.fin-hermes-summary { font-size: 13px; line-height: 1.45; color: var(--text-2); margin-bottom: 6px; }
@media (max-width: 760px) {
  /* На узком экране таблица листается вбок: бумаге нужно место под имя. */
  .fin-pay-table { min-width: 600px; }
  .fin-pay-table th:nth-child(1), .fin-pay-table td:nth-child(1) { width: 80px; }
  .fin-pay-table th:nth-child(3), .fin-pay-table td:nth-child(3) { width: 110px; }
  .fin-pay-table th:nth-child(4), .fin-pay-table td:nth-child(4) { width: 220px; }
  .fin-pay-status { white-space: normal; }
  .fin-sec-head > :nth-child(6) { display: none; }
}
#entity-modal.as-drawer[data-fin-sec] .modal-panel { width: min(560px, calc(100vw - 40px)); }
.fin-sp { display: flex; flex-direction: column; gap: 14px; }
.fin-sp-status { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fin-sp-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
.fin-sp-fig { background: var(--panel-2); border-radius: var(--radius-sm); padding: 8px 10px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fin-sp-fig-label { font-size: 12px; color: var(--muted); }
.fin-sp-fig-value { font-family: var(--font-display); font-size: 18px; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.fin-sp-block { display: flex; flex-direction: column; gap: 6px; }
.fin-sp-head { font-weight: 600; font-size: 14px; }
.fin-sp-watch { font-size: 13px; line-height: 1.45; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--panel-2); }
.fin-sp-watch.good { background: var(--tile-green-bg); color: var(--tile-green-text-2); }
.fin-sp-watch.bad { background: var(--tile-rose-bg-3); color: var(--tile-rose-text-2); }
.fin-sp-table td { padding: 6px 8px; }
.fin-sp-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fin-sp-table .fin-badge { white-space: nowrap; }
.fin-sp-bad td:first-child { box-shadow: inset 3px 0 0 var(--ink-rose); }
.fin-months { display: flex; flex-direction: column; --cols: 4; }
.fin-month-fold { border-bottom: 1px solid var(--line-4); }
.fin-month-fold > summary { cursor: pointer; list-style: none; border-radius: var(--radius-sm); }
.fin-month-fold > summary::-webkit-details-marker { display: none; }
.fin-month-fold > summary:hover, .fin-month-fold[open] > summary { background: var(--panel-2); }
.fin-month-row { display: grid; grid-template-columns: minmax(130px, 1fr) repeat(var(--cols), 120px); gap: 4px 14px;
  align-items: center; padding: 9px 8px; font-size: 13px; }
.fin-month-head { padding-top: 0; padding-bottom: 6px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 12px; }
.fin-month-name { font-weight: 600; }
.fin-month-fig { display: flex; flex-direction: column; align-items: flex-end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fin-month-lbl { display: none; color: var(--muted); font-size: 12px; }
.fin-month-body { display: flex; flex-direction: column; gap: 8px; padding: 6px 8px 14px; }
@media (max-width: 760px) {
  .fin-sec-row { grid-template-columns: minmax(0, 1fr) 96px 96px; }
  .fin-sec-row > :nth-child(4), .fin-sec-row > :nth-child(5) { display: none; }
  .fin-sec-badges { grid-column: 1 / -1; justify-content: flex-start; }
  .fin-month-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fin-month-name { grid-column: 1 / -1; }
  .fin-month-fig { align-items: flex-start; }
  .fin-month-head { display: none; }
  .fin-month-lbl { display: block; }
}


/* ── боковая панель задачи (13.10.2026, `ui/task-panel.js`; вид — 18.10.2026) ──
   Щелчок по задаче — и по группе «Задача ДШ20. Работа с товаром» — открывает её
   справа, а не окном посередине. Карточки на тёплом фоне; оттенок заглавия —
   тот же, что у строки в плане недели; внизу всегда видна кнопка «Выполнить». */
#entity-modal.as-drawer[data-task-id] .modal-panel,
#entity-modal.as-drawer[data-task-group] .modal-panel { width: min(460px, calc(100vw - 40px)); }
#entity-modal.as-drawer[data-task-id] .modal-body,
#entity-modal.as-drawer[data-task-group] .modal-body { flex: 1 1 auto; background: var(--bg); padding-bottom: 0; }
.tp {
  --tp-line: var(--tw-own-line); --tp-tint: var(--panel);
  display: flex; flex-direction: column; gap: var(--gap);
}
.tp.k-subs { --tp-line: var(--tw-subs-line); --tp-tint: var(--tw-subs-bg); }
.tp.k-crm { --tp-line: var(--tw-crm-line); --tp-tint: var(--tw-crm-bg); }
.tp.k-rec { --tp-line: var(--tw-rec-line); --tp-tint: var(--tw-rec-bg); }
.tp.k-cal { --tp-line: var(--tw-cal-line); --tp-tint: var(--tw-cal-bg); }
.tp.is-done { --tp-line: var(--line); --tp-tint: var(--panel-2); }
.tp-top { display: flex; align-items: center; gap: 8px; min-height: 26px; margin-bottom: -4px; }
.tp-back {
  display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 70%;
  padding: 3px 10px 3px 6px; border: none; border-radius: 999px; background: transparent;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--accent-ink); cursor: pointer;
}
.tp-back span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-back svg { flex: none; }
.tp-back:hover { background: var(--accent-dim); }
.tp-nav { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12px; }
/* Заглавие: галочка и текст на мягком фоне вида задачи. */
.tp-hero {
  background: var(--tp-tint); border: 1px solid var(--line-4); border-left: 4px solid var(--tp-line);
  border-radius: var(--radius); padding: 14px 14px 14px 12px;
}
.tp-title { display: flex; gap: 12px; align-items: flex-start; }
.tp-check { width: 26px; height: 26px; margin-top: 1px; font-size: 14px; border-color: var(--muted); background: var(--panel); }
.tp-check.on { background: var(--ok); }
.tp-text {
  flex: 1; min-width: 0; font-size: 17px; line-height: 1.4; font-weight: 650;
  color: var(--text); overflow-wrap: anywhere;
}
.tp-text.editable { cursor: text; border-radius: 6px; padding: 2px 4px; margin: -2px -4px; }
.tp-text.editable:hover { background: var(--panel); }
.tp-title.done .tp-text { color: var(--muted); text-decoration: line-through; }
.tp-text-edit {
  flex: 1; min-width: 0; font: inherit; font-size: 17px; font-weight: 650; line-height: 1.4;
  resize: none; padding: 2px 4px; border: 1px solid var(--accent); border-radius: 6px;
  background: var(--panel); color: var(--text);
}
/* Товар: фото, имя, этап — нажатие открывает его карточку. */
.tp-unit {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 8px 12px 8px 8px; border: 1px solid var(--line-4); border-radius: var(--radius);
  background: var(--panel); color: var(--text); font: inherit; cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.tp-unit:hover { border-color: var(--accent); box-shadow: 0 2px 10px var(--c-rgba-90-74-55-08-s); }
.tp-unit-photo {
  flex: none; width: 54px; height: 54px; border-radius: var(--radius-sm); overflow: hidden;
  display: grid; place-items: center; background: var(--panel-3); color: var(--muted);
}
.tp-unit-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tp-unit-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tp-unit-name { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-unit-stage { font-size: 12px; color: var(--muted); }
.tp-unit-go { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--accent-ink); }
.tp-unit:hover .tp-unit-go { text-decoration: underline; }
/* Карточки панели: свойства и разделы. */
.tp-card, .tp-section {
  background: var(--panel); border: 1px solid var(--line-4); border-radius: var(--radius); padding: 10px 12px;
}
.tp-fields { display: flex; flex-direction: column; padding-block: 2px; }
.tp-row { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 8px; align-items: center; padding: 8px 0; }
.tp-row + .tp-row { border-top: 1px dashed var(--line); }
.tp-label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.tp-label svg { flex: none; color: var(--text-2); }
.tp-value { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-width: 0; }
.tp-chip {
  position: relative; display: inline-flex; align-items: center; gap: 4px;
  font: inherit; font-size: 13px; line-height: 26px; padding: 0 11px; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--text-2); cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.tp-chip:hover { border-color: var(--muted); color: var(--text); }
.tp-chip.on { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-ink); font-weight: 650; }
/* «Другой день»: под плашкой — родное поле даты, невидимое; нажатие открывает календарь. */
.tp-pick { overflow: hidden; }
.tp-pick .tp-date {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0;
  border: 0; opacity: 0; cursor: pointer; font-size: 16px;
}
.tp-due-note { flex-basis: 100%; font-size: 12px; color: var(--muted); }
.tp-due-note.soon { color: var(--ink-yellow); font-weight: 600; }
.tp-due-note.late { color: var(--ink-rose); font-weight: 600; }
.tp-prio { align-self: flex-start; }
.tp-prio .mode-btn { padding: 4px 12px; font-size: 13px; }
.tp-prio .mode-btn.on[data-prio="1"] { background: var(--warn); color: var(--ink-yellow); }
.tp-prio .mode-btn.on[data-prio="2"] { background: var(--danger); color: var(--ink-rose); }
.tp-select { font: inherit; font-size: 13px; height: 26px; padding: 2px 6px; }
.tp-section { display: flex; flex-direction: column; gap: 8px; }
/* Значок раздела — маской: рисует его цвет текста, в тёмной теме тоже. */
.tp-section { --tp-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 6h10M10 12h10M10 18h10'/><path d='m3.5 6 1.2 1.2L7 5M3.5 12l1.2 1.2L7 11M3.5 18l1.2 1.2L7 17'/></svg>"); }
.tp-steps { --tp-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3.5' y='3.5' width='17' height='17' rx='4'/><path d='m8 12 3 3 5-6'/></svg>"); }
.tp-notes { --tp-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 3h10l4 4v14H5Z'/><path d='M9 11h6M9 15h6'/></svg>"); }
.tp-links { --tp-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 14a4.5 4.5 0 0 0 6.4 0l3-3a4.5 4.5 0 0 0-6.4-6.4l-1 1'/><path d='M14 10a4.5 4.5 0 0 0-6.4 0l-3 3a4.5 4.5 0 0 0 6.4 6.4l1-1'/></svg>"); }
.tp-section-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.tp-section-head::before {
  content: ''; flex: none; width: 15px; height: 15px; background: var(--text-2);
  -webkit-mask: var(--tp-ico) center / contain no-repeat; mask: var(--tp-ico) center / contain no-repeat;
}
.tp-section-head .muted {
  margin-left: auto; font-size: 12px; line-height: 20px; padding: 0 8px;
  border-radius: 999px; background: var(--panel-2);
}
.tp-section-head .save-mark { margin-left: auto; }
.tp-step-list { display: flex; flex-direction: column; gap: 2px; }
.tp-step { display: flex; align-items: flex-start; gap: var(--gap); padding: 5px 4px; border-radius: var(--radius-sm); }
.tp-step:hover { background: var(--panel-2); }
.tp-step-text { flex: 1; min-width: 0; font-size: 13px; line-height: 1.35; overflow-wrap: anywhere; cursor: text; }
.tp-step.done .tp-step-text { color: var(--muted); text-decoration: line-through; }
.tp-step-del {
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 12px; padding: 0 2px; opacity: 0;
}
.tp-step:hover .tp-step-del, .tp-step-del:focus-visible { opacity: 1; }
.tp-step-del:hover { color: var(--ink-rose); }
@media (hover: none) { .tp-step-del { opacity: 1; } }
.tp-step-edit { flex: 1; min-width: 0; font: inherit; font-size: 13px; }
.tp-step-new {
  width: 100%; min-width: 0; font: inherit; font-size: 13px; padding: 7px 10px;
  border: 1px dashed var(--line); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--text);
}
.tp-step-new:focus { border-style: solid; border-color: var(--accent); background: var(--panel); }
.tp-steps-done {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px;
  border-radius: var(--radius-sm); background: var(--accent-dim); color: var(--accent-ink); font-size: 13px; font-weight: 600;
}
.tp-notes-field {
  width: 100%; min-height: 64px; font: inherit; font-size: 13px; line-height: 1.45; resize: vertical;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--text);
}
.tp-notes-field:focus { border-color: var(--accent); background: var(--panel); }
.tp .task-source {
  background: var(--panel); border: 1px solid var(--line-4); border-radius: var(--radius);
  padding: 10px 12px; font-size: 13px;
}
.tp .task-source summary { color: var(--text-2); font-weight: 600; }
/* Кто и когда — тихой лентой с точками. */
.tp-history {
  display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted);
  padding: 2px 4px 6px 18px;
}
.tp-history div { position: relative; }
.tp-history div::before {
  content: ''; position: absolute; left: -12px; top: .55em; width: 5px; height: 5px;
  border-radius: 50%; background: var(--line);
}
.tp-history:empty { display: none; }
/* Просьба ассистентки владелице (11.11.2026, `core/owner-asks.js`): что сделает CRM, почему не вышло. */
.tp-ask {
  display: flex; flex-direction: column; gap: 4px; font-size: 13px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
}
.tp-ask-error { border-left: 3px solid var(--danger); padding-left: 8px; }
/* Низ панели — всегда на виду. */
.tp-foot {
  position: sticky; bottom: 0; z-index: 3;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px;
  /* Справа — место круглой кнопке чата (44 px в 18 px от края), она стоит поверх. */
  margin: 2px calc(-1 * var(--pad-lg)) 0; padding: 10px 72px 14px var(--pad-lg);
  background: var(--panel); border-top: 1px solid var(--line);
  box-shadow: 0 -6px 14px var(--c-rgba-90-74-55-08-s);
}
.tp-foot-main, .tp-foot-more { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.tp-ibtn { display: inline-flex; align-items: center; gap: 4px; }
.tp-icon-only { padding-inline: 7px; }
.tp-done-btn { padding-inline: 16px; font-weight: 650; }
.tp-delete { color: var(--ink-rose); }
/* Задача, открытая в панели, подсвечена на доске. */
.tw-item.tp-current, .task-row.tp-current { background: var(--accent-dim); box-shadow: inset 2px 0 0 var(--accent); }
.task-row { cursor: pointer; }
/* Подзадачи товара в панели (15.10.2026): пункты чек-листа и их подзадачи — как в плане недели. */
.tp-item-list { display: flex; flex-direction: column; gap: 2px; }
.tp-item { display: flex; align-items: flex-start; gap: var(--gap); padding: 5px 4px; border-radius: var(--radius-sm); cursor: pointer; }
.tp-item:hover { background: var(--panel-2); }
.tp-item.sub { margin-left: 26px; padding-block: 3px; }
.tp-item.sub .tw-check.sm { margin-top: 2px; }
.tp-item-text { flex: 1; min-width: 0; font-size: 13px; line-height: 1.35; overflow-wrap: anywhere; }
.tp-item.sub .tp-item-text { font-size: 13px; color: var(--text-2); }
.tp-item.done .tp-item-text { color: var(--muted); text-decoration: line-through; }
/* Панель группы «Задача ДШ20. Работа с товаром» (18.10.2026). */
.tpg { padding-bottom: var(--pad-lg); }
.tpg-hero { display: flex; flex-direction: column; gap: 8px; }
.tpg-progress { display: flex; align-items: baseline; gap: 6px; font-size: 13px; }
.tpg-progress strong { font-family: var(--font-display); font-size: 21px; }
.tpg-list { display: flex; flex-direction: column; gap: 6px; }
.tpg .tw-group-row {
  position: relative; padding: 9px 10px; border-radius: var(--radius-sm);
  border-color: var(--line-4); background: var(--panel-2);
}
.tpg .tw-group-row:hover { border-color: var(--tw-subs-line); background: var(--panel); }
.tpg .tw-group-row-main { gap: var(--gap); padding-right: 30px; }
.tpg .tw-group-row .tw-text { font-size: 13px; line-height: 1.35; }
.tpg .tw-group-row .tw-check { width: 18px; height: 18px; line-height: 15px; }
.tpg .tw-group-row .tw-subs { margin-left: 27px; gap: 4px; }
.tpg .tw-group-row .tw-subs-text { font-size: 13px; }
.tpg .tw-give { top: 7px; right: 7px; }
.tpg .tw-group-row:hover .tw-give { opacity: 1; }
.tpg-who { font-size: 12px; color: var(--muted); }
.tpg-tasks { --tp-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 8 12 3 3 8v8l9 5 9-5Z'/><path d='m3 8 9 5 9-5M12 13v8'/></svg>"); }

/* «ТОВАРЫ» В ДОСЬЕ ФАБРИКИ (20.10.2026, ui/factory-products.js): плитка на товар — фото,
   имя, цена, что сейчас. Сетка подстраивается сама: в узкой панели справа две плитки
   в ряд, в широком досье — сколько влезет. */
.fprod { margin-top: 4px; }
.fprod-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: var(--gap); margin: 8px 0 4px;
}
.fprod-tile {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
  cursor: default;
}
.fprod-tile[role="button"] { cursor: pointer; }
.fprod-tile[role="button"]:hover { border-color: var(--accent); background: var(--hover); }
.fprod-tile[role="button"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.fprod-tile.past .fprod-photo img { opacity: .82; }
.fprod-photo {
  position: relative; aspect-ratio: 1 / 1; min-height: 0; overflow: hidden;
  background: var(--panel-2); border-bottom: 1px solid var(--line);
}
/* Снимок лежит поверх квадрата, а не в потоке: иначе высокий портрет растягивал
   плитку, и в одном ряду они стояли разной высоты. */
.fprod-photo img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
}
.fprod-count {
  position: absolute; right: 6px; bottom: 6px; min-width: 20px; padding: 1px 6px;
  border-radius: 999px; background: var(--panel); color: var(--text);
  font-size: 11px; line-height: 16px; text-align: center; border: 1px solid var(--line);
}
.fprod-body { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px 10px; min-width: 0; }
.fprod-name { font-weight: 600; font-size: 14px; overflow-wrap: anywhere; }
.fprod-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; }
.fprod-price b { font-size: 16px; }
.fprod-from { font-size: 12px; color: var(--muted); }
.fprod-noprice { font-size: 13px; color: var(--muted); }
.fprod-state { display: flex; flex-wrap: wrap; gap: 4px; }
.fprod-meta { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.fprod-why { font-style: italic; }
.fprod-past > summary { cursor: pointer; color: var(--muted); font-size: 13px; margin: 6px 0 2px; }
/* Свёрткой досье (20.10.2026): отступы даёт сама свёртка. */
.ctr-folds > .fprod { margin-top: 0; }
.ctr-folds > .fprod[open] { padding-bottom: 8px; }

/* ── Анкета фабрики: загрузка и итог (20.10.2026, `openAnketaUpload`) ─────
   Рамка, в которую бросают файл; итог — карточкой со значком: обновила
   (зелёная), новая (зелёная), похожа на фабрику библиотеки (жёлтая). */
.anketa-imp-drop {
  display: flex; flex-direction: column; align-items: center; gap: var(--gap);
  padding: 30px 16px 22px; text-align: center;
  border: 2px dashed var(--line); border-radius: var(--radius); background: var(--panel-2);
  transition: border-color .15s, background .15s;
}
.anketa-imp-drop.over { border-color: var(--accent); background: var(--accent-dim); }
.anketa-imp-drop.busy { opacity: .55; pointer-events: none; }
.anketa-imp-drop-icon {
  display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%;
  background: var(--accent-dim); color: var(--ink-green);
}
.anketa-imp-drop-title { font-family: var(--font-display); font-size: 18px; color: var(--text); }
.anketa-imp-drop-hint { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: var(--muted); }
.anketa-imp-busy {
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 8px 10px;
  padding: 12px 14px; margin-top: 10px; border-radius: var(--radius);
  background: var(--accent-dim); border: 1px solid var(--accent);
}
.anketa-imp-busy .spinner { width: 18px; height: 18px; border-width: 3px; border-top-color: var(--ink-green); }
.anketa-imp-busy-text { color: var(--ink-green); font-weight: 600; overflow-wrap: anywhere; }
.anketa-imp-busy-bar {
  grid-column: 1 / -1; height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--line); position: relative;
}
.anketa-imp-busy-bar::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -40%; width: 40%;
  border-radius: 3px; background: var(--ink-green); animation: nw-busy-run 1.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .anketa-imp-busy-bar::after { animation-duration: 3s; } }
.anketa-imp-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 16px; }
.anketa-imp-spacer { flex: 1 1 auto; }

.anketa-imp-top { display: flex; flex-direction: column; gap: 8px; }
.anketa-imp-head {
  display: flex; gap: 12px; align-items: flex-start; padding: 14px;
  border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel-2);
}
.anketa-imp-badge {
  flex: 0 0 auto; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: var(--panel); color: var(--text);
}
.anketa-imp-head.ok, .anketa-imp-head.plus { background: var(--accent-dim); border-color: var(--accent); }
.anketa-imp-head.ok .anketa-imp-badge, .anketa-imp-head.plus .anketa-imp-badge { background: var(--panel); color: var(--ink-green); }
.anketa-imp-head.look { background: var(--warn); border-color: var(--warn); }
.anketa-imp-head.look .anketa-imp-title, .anketa-imp-head.look .anketa-imp-text { color: var(--ink-yellow); }
.anketa-imp-head.look .anketa-imp-badge { background: var(--panel); color: var(--ink-yellow); }
.anketa-imp-words { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.anketa-imp-title { font-size: 15px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.anketa-imp-text { font-size: 13px; color: var(--text-2); overflow-wrap: anywhere; }
.anketa-imp-signals { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.anketa-imp-signals-label { font-size: 13px; color: var(--muted); }
.anketa-imp-chip {
  padding: 2px 9px; border-radius: 999px; font-size: 12px;
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.anketa-imp-match { display: grid; gap: 8px; margin-top: 10px; }
.anketa-imp-cand {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 12px 14px;
  border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel);
}
.anketa-imp-cand-name { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.anketa-imp-cand-note { font-size: 13px; color: var(--ink-rose); }
.anketa-imp-match-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; font-size: 13px; }
.anketa-imp-fold { margin-top: 10px; }
.anketa-imp-fold > summary { cursor: pointer; font-size: 13px; color: var(--muted); }
.anketa-imp-fold .row-actions { margin-top: 8px; }
.anketa-imp-changes { display: grid; gap: 4px; margin-top: 8px; font-size: 13px; }
.anketa-imp-change { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px; overflow-wrap: anywhere; }
.anketa-imp-change-mark { flex: 0 0 16px; text-align: center; color: var(--muted); }
.anketa-imp-change.add .anketa-imp-change-mark { color: var(--ink-green); font-weight: 700; }
.anketa-imp-was { color: var(--muted); text-decoration: line-through; }

/* ── «+ Фабрика» (21.10.2026, `openFactoryAdd`): две крупные кнопки выбора —
   анкета или WeChat — и строка «90 Factory» для названия чата крупно, с
   «Копировать». */
.factory-add-choice { display: grid; gap: var(--gap); }
.factory-add-btn {
  display: flex; align-items: center; gap: 14px; width: 100%; min-height: 72px;
  padding: 14px 16px; border-radius: var(--radius); text-align: left;
  border: 2px solid var(--accent); background: var(--panel); color: var(--text);
  font: inherit; cursor: pointer; transition: background .15s ease, transform .15s ease;
}
.factory-add-btn:hover { background: var(--accent-dim); transform: translateY(-1px); }
.factory-add-btn:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 2px; }
.factory-add-btn-icon {
  flex: none; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%;
  background: var(--accent-dim); color: var(--ink-green);
}
.factory-add-btn-words { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.factory-add-btn-title { font-size: 16px; font-weight: 700; }
.factory-add-btn-text { font-size: 13px; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .factory-add-btn { transition: none; } }
.factory-add-step { margin-top: 14px; font-size: 13px; color: var(--text-2); }
.factory-add-copy {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin-top: 8px; padding: 12px 14px;
  border-radius: var(--radius); border: 2px dashed var(--accent); background: var(--accent-dim);
}
.factory-add-copy-text {
  flex: 1 1 160px; min-width: 0; font-family: var(--mono); font-size: 22px; font-weight: 700;
  color: var(--ink-green); background: none; user-select: all; overflow-wrap: anywhere;
}
.factory-add-note { margin-top: 10px; font-size: 13px; color: var(--muted); }
/* «Отправить анкету для заполнения» (21.10.2026): кнопка под письмом и под
   анкетой, рядом — имя файла «90 Factory.xlsx». */
.factory-add-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin-top: 8px; }
.factory-add-file { font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--ink-green); }
.anketa-imp-now { font-weight: 600; }
.anketa-imp-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; font-size: 13px; }
.anketa-imp-block { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.anketa-imp-block .anketa-imp-line { margin-top: 6px; }
.anketa-imp-label { margin-bottom: 6px; font-size: 13px; color: var(--muted); }
.anketa-imp-brands { display: flex; flex-wrap: wrap; gap: 8px; }
.anketa-imp-brand {
  padding: 8px 14px; border-radius: var(--radius-sm); font: inherit; font-size: 14px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
}
.anketa-imp-brand:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-dim); }
.anketa-imp-brand.ghost { background: transparent; color: var(--muted); }
.anketa-imp-brand:disabled { opacity: .6; cursor: default; }

/* ── «Контрагенты» — вид 20.10.2026 ──────────────────────────────────────────
   Её слово: «оформить раздел более красиво, лишнюю информацию свернуть». Одна
   полоса управления над списком, список прилипает, досье — карточками на фоне
   раздела: шапка, плитки «Аналитики», адрес, дальше свёртки-строки. Досье —
   контейнер `ctrdossier`: в панели 460px раскладка считается от его ширины. */
.ctr-bar { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; margin: 0 0 14px; }
.ctr-bar .product-tabs, .ctr-bar .spec-filter { margin: 0; }
.ctr-bar .section-head-box { margin-left: auto; }
.ctr-bar .section-head { margin: 0; }
.ctr-tab-n { margin-left: 6px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ctr-split .split-list {
  position: sticky; top: 8px; max-height: calc(100vh - 140px); overflow-y: auto; padding: 2px;
}
.ctr-split .split-row.on {
  background: var(--accent-dim); box-shadow: inset 3px 0 0 var(--accent), 0 0 0 1px var(--accent);
}
.ctr-split .split-detail { background: transparent; box-shadow: none; padding: 0; }
.ctr-split .split-detail, #entity-modal.as-drawer[data-supplier-panel] .modal-body {
  container: ctrdossier / inline-size;
}
#entity-modal.as-drawer[data-supplier-panel] .modal-panel { width: min(460px, calc(100vw - 40px)); }
#entity-modal.as-drawer[data-supplier-panel] .modal-body { background: var(--bg); }
.ctr-hero {
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; margin: 0 0 12px;
}
.ctr-hero-top, .ctr-hero-bottom { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; }
.ctr-hero-top:empty { display: none; }
.ctr-hero .detail-rating, .ctr-hero-actions { margin-left: auto; }
.ctr-hero-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.ctr-spec-chip { background: var(--panel-2); color: var(--text-2); }
.ctr-spec-edit {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; margin: 0 0 12px;
}
.ctr-spec-edit[hidden] { display: none; }
.ctr-spec-edit .section-subhead { margin-top: 0; }
.ctr-spec-edit .spec-edit { margin-bottom: 0; }
/* В окне карандаша досье (11.11.2026) — без своей рамки: оно и так окно. */
#entity-body .ctr-spec-edit { background: none; border: 0; padding: 0; margin: 14px 0; }
#entity-body .ctr-edit-actions { margin: 0 0 6px; }
.ctr-tiles { margin: 0 0 12px; }
/* Плитки досье фабрики (20.10.2026): «12,9 дня» целиком крупным не влезало и наезжало
   на соседнюю плитку. Число крупно, единица мельче рядом (`ctrTileValue`), плитка шире,
   а узко — единица уходит под число, но за плитку не вылезает ничего. */
.ctr-tiles { grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr)); }
.ctr-tiles .analytics-tile { overflow: hidden; }
.ctr-tiles .analytics-tile-top { max-width: 100%; min-width: 0; }
.ctr-tiles .analytics-tile-value {
  display: inline-flex; align-items: baseline; flex-wrap: wrap; min-width: 0; max-width: 100%;
}
.analytics-tile-unit {
  font-size: .6em; font-weight: 500; color: var(--text-2); margin-left: .25em; white-space: nowrap;
}
.analytics-tile-unit.joined { margin-left: 1px; }
/* Пять-шесть плиток — по три в ряд (21.10.2026): пять в строке оставляли шестую внизу одну.
   В широком досье все встают одной строкой. */
.ctr-tiles:has(> :nth-child(5)) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@container ctrdossier (min-width: 960px) {
  .ctr-tiles:has(> :nth-child(5)) { grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr)); }
}
/* Свёртка без цифры — стрелка всё равно у правого края, как у соседних (21.10.2026). */
.ctr-fold .analytics-block-title + .analytics-chevron { margin-left: auto; }
.ctr-split .split-detail > .section-subhead, #entity-modal[data-supplier-panel] .modal-body > .section-subhead {
  margin: 4px 0 6px;
}
.factory-contact .copy-menu .btn { background: var(--accent-dim); border-color: var(--accent); font-weight: 600; }
.ctr-folds { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.ctr-fold { scroll-margin-top: 16px; }
.ctr-fold summary .section-subhead {
  margin: 0; font-size: 14px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--text);
}
.ctr-fold .metric-list.two { margin-top: 0; }
.ctr-fold .metric-row.metric-empty { background: transparent; border-style: dashed; padding: 5px 11px; }
.ctr-fold .metric-note[hidden] { display: none; }
.ctr-fold .stat-grid { margin-top: 6px; }
.ctr-subfold { margin-top: 8px; }
.ctr-subfold > summary {
  cursor: pointer; list-style: none; color: var(--muted); font-size: 13px;
  display: flex; gap: 6px; align-items: center; min-width: 0;
}
.ctr-subfold > summary::-webkit-details-marker { display: none; }
.ctr-subfold > summary:hover { color: var(--text); }
.ctr-subfold-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctr-subfold-figure { color: var(--text-2); font-variant-numeric: tabular-nums; }
.ctr-subfold > :not(summary) { margin-top: 6px; }
.ctr-note .hint.pre { margin: 0; }
.ctr-parties { align-items: start; }
#entity-modal.as-drawer .hint.pre.party-address {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px 12px; color: var(--text);
}
.party-drawer-actions { margin-top: 18px; }
@container ctrdossier (max-width: 520px) {
  .ctr-hero .detail-rating, .ctr-hero-actions { margin-left: 0; }
  .ctr-tiles .analytics-tile { padding: 10px 12px; }
  .ctr-tiles .analytics-tile-value { font-size: 22px; }
  .ctr-fold .analytics-block-figure { white-space: normal; text-align: right; }
  .fact-row { grid-template-columns: minmax(0, 1fr) auto; }
  .fact-row .fact-label { grid-column: 1 / -1; }
}

/* «Юнит экономика» (27.10.2026, `ui/unit-economics.js`): её таблица «Юнитка» —
   показатели слева сверху, ориентир литража справа, просчёты строками. Серым —
   её вопросы к товару, как серые столбцы таблицы; маржа и ROI — зелёным и
   розовым относительно проходных. */
.unit-pick { display: flex; flex-direction: column; gap: 12px; align-items: center; }
.unit-pick-brands { display: flex; gap: var(--gap); flex-wrap: wrap; justify-content: center; }
.unit-top { display: grid; grid-template-columns: minmax(0, 760px) minmax(220px, 300px); gap: 16px; margin: 4px 0 18px; align-items: start; }
/* Показатели — двумя колонками: таблица просчётов не должна уезжать за экран. */
.unit-params { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }
.unit-params > .unit-card-title { grid-column: 1 / -1; }
/* Группы показателей: общие, логистика, FBO, FBS (05.11.2026). */
.unit-param-group { grid-column: 1 / -1; margin: 14px 0 2px; font-size: 12px; font-weight: 600; color: var(--muted); }
.unit-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.unit-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.unit-card-title { margin: 0 0 8px; font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.unit-card-head .unit-card-title { margin: 0; }
.unit-param { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.unit-param:last-child { border-bottom: 0; }
.unit-param-label { color: var(--text); display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 6px; min-width: 0; }
.unit-param-value { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.unit-param-note { color: var(--muted); font-size: 11px; }
.unit-param-rub { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Поле, знак и галочка «сохранено» — постоянной ширины в каждой строке: поля
   стоят ровным столбцом, что бы ни было рядом (27.10.2026). */
.unit-param-edit { display: flex; align-items: center; gap: 4px; }
.unit-param-input { width: 68px; text-align: right; padding: 3px 6px; font-size: 13px; }
.unit-param-suffix { color: var(--muted); font-size: 12px; width: 16px; white-space: nowrap; }
.unit-param-edit .save-mark { width: 12px; font-size: 12px; font-weight: 700; text-align: center; }
/* Шрифты таблицы — одной шкалой с прочими таблицами CRM: строки 13 px, шапка и
   пояснения 12 и 11 px, все подписи шапки одного цвета; серым фоном — её вопросы. */
.unit-table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
.unit-table { border-collapse: separate; border-spacing: 0; font-size: 13px; line-height: 1.4; min-width: 100%; }
.unit-table th, .unit-table td { padding: 7px 10px; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.unit-table th { position: sticky; top: 0; z-index: 1; background: var(--panel); color: var(--muted); font-size: 12px; font-weight: 500; vertical-align: bottom; white-space: normal; min-width: 84px; line-height: 1.3; }
.unit-table th.unit-ask, .unit-table td.unit-ask { background: var(--panel-2); }
.unit-th-note { display: block; font-size: 11px; font-weight: 400; color: var(--muted); }
.unit-table .unit-sticky { position: sticky; left: 0; z-index: 2; background: var(--panel); text-align: left; border-right: 1px solid var(--line); }
.unit-table th.unit-sticky { z-index: 3; }
.unit-row { cursor: pointer; }
.unit-row:hover td { background: var(--hover); }
.unit-table td.unit-product { white-space: normal; vertical-align: top; }
.unit-product-box { display: flex; gap: var(--gap); align-items: flex-start; width: 290px; }
.unit-thumb { width: 64px; height: 80px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); flex: 0 0 auto; cursor: zoom-in; background: var(--panel-2); }
.unit-thumb-empty { display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--muted); cursor: pointer; }
.unit-product-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.unit-product-title { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.unit-product-comment {
  color: var(--text-2); font-size: 12px; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
}
.unit-product-date { color: var(--muted); font-size: 11px; }
.unit-table td.unit-strong { font-weight: 600; }
.unit-table td.unit-ok { background: var(--tile-green-bg); color: var(--tile-green-text); font-weight: 600; }
.unit-table td.unit-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); font-weight: 600; }
.unit-links { text-align: left; }
.unit-links a { display: block; color: var(--accent-ink); }
.unit-liters-edit { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.unit-liters-row { display: grid; grid-template-columns: 1fr 80px auto; gap: 8px; align-items: center; }
.unit-form-top { display: flex; gap: 16px; align-items: stretch; margin-bottom: 8px; flex-wrap: wrap; }
.unit-photo { position: relative; width: 150px; height: 190px; flex: 0 0 auto; border-radius: var(--radius); overflow: hidden; }
.unit-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border: 1px solid var(--line); border-radius: var(--radius); }
.unit-photo.has-photo .photo-remove { opacity: 1; top: 6px; right: 6px; }
.unit-photo .unit-photo-drop { width: 100%; height: 100%; font-size: 12px; gap: 4px; }
.unit-photo.over .unit-photo-drop { border-color: var(--accent); background: var(--accent-dim); }
.unit-photo-hint { font-size: 11px; color: var(--muted); }
.unit-live { flex: 1 1 260px; display: grid; grid-template-columns: repeat(2, minmax(110px, 1fr)); gap: 8px; align-content: start; }
.unit-live-tile { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--panel-2); border: 1px solid var(--line); }
.unit-live-tile.unit-ok { background: var(--tile-green-bg); color: var(--tile-green-text); }
.unit-live-tile.unit-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.unit-batch { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.unit-batch-title { margin: 0; font-size: 15px; }
.unit-batch-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.unit-batch-table th, .unit-batch-table td { padding: 4px 6px; text-align: left; border-bottom: 1px solid var(--line); }
.unit-batch-table th { font-weight: 500; color: var(--muted); }
.unit-batch-table td input { width: 100%; min-width: 0; }
.unit-batch-out td.unit-ok { color: var(--tile-green-text); font-weight: 600; }
.unit-batch-out td.unit-bad { color: var(--tile-rose-text); font-weight: 600; }
/* FBS / FBO (03.11.2026): переключатель схемы в шапке и сравнение в окне просчёта. */
.unit-scheme { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.unit-scheme-btn { border: 0; background: transparent; color: var(--muted); padding: 4px 12px; font: inherit; font-size: 13px; cursor: pointer; }
.unit-scheme-btn.on { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.unit-schemes-box { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 8px; }
.unit-schemes-table td.unit-ok { color: var(--tile-green-text); font-weight: 600; }
.unit-schemes-table td.unit-bad { color: var(--tile-rose-text); font-weight: 600; }
.unit-schemes-table tr.unit-strong th, .unit-schemes-table tr.unit-strong td { font-weight: 600; }
.unit-live-label { font-size: 12px; opacity: .85; }
.unit-live-value { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.unit-live-note { font-size: 11px; opacity: .8; }
.unit-live-rates { margin: 0 0 10px; }
/* Цепочка цены в окне «Юнит экономики» (28.10.2026): после её скидки → на сайте, откуда СПП. */
.unit-live-price { margin: 10px 0 2px; font-size: 13px; color: var(--text-2); }
.unit-live-price:empty { display: none; }
.unit-form-grid .unit-ask-field input, .unit-form-grid .unit-ask-field select { background: var(--panel-2); }
.unit-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.unit-chip { border: 1px solid var(--line); background: var(--panel); color: var(--text-2); border-radius: 999px; padding: 2px 8px; font-size: 11px; cursor: pointer; }
.unit-chip:hover { background: var(--accent-dim); color: var(--text); }
/* Не подключено (MPStats, Google) — слова и кнопка в «Подключения» (аудит 13.11.2026). */
.unit-connect { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; width: 100%; }
/* Показатели под шестерёнкой закрыты — карточка литража своей ширины, а не во всю колонку 760px (проверка 28.10.2026). */
@media (min-width: 1101px) {
  .unit-top:has(> .unit-params.hidden) { grid-template-columns: minmax(220px, 300px); }
}
@media (max-width: 1100px) {
  .unit-top { grid-template-columns: 1fr; }
  .unit-liters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }
  .unit-liters > .unit-card-head { grid-column: 1 / -1; }
}
@media (max-width: 620px) {
  .unit-params { grid-template-columns: 1fr; }
}


/* «Финансовый отчёт» — подраздел «Аналитики» (27.10.2026, `ui/wb-finance.js`). Таблица —
   та же, что у «Юнит экономики» (`.unit-table`): убыток розовым, прибыль зелёным. */
.wbfin-nav { display: inline-flex; align-items: center; gap: 4px; }
.wbfin-period { min-width: 150px; text-align: center; font-weight: 600; font-variant-numeric: tabular-nums; }
.wbfin-tile { cursor: default; }
.wbfin-tile:hover { transform: none; border-color: var(--line); }
.wbfin-tile-profit { border-color: var(--an-ink); background: var(--an-bg); }
.wbfin-tile-profit .analytics-tile-value { color: var(--an-ink); }
.wbfin-demo, .wbfin-alert {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; padding: 10px 14px;
  border-radius: var(--radius); background: var(--tile-yellow-bg); color: var(--tile-yellow-text); font-size: 13px;
}
.wbfin-scroll { margin-bottom: 16px; }
/* Окно о новой неделе (28.10.2026): строки «название — сумма справа», имя в одну строку. */
.wbfin-pop-profit { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 12px; padding: 12px 14px; margin-bottom: 14px; border-radius: var(--radius-sm); background: var(--panel-2); font-size: 14px; }
.wbfin-pop-profit b { font-size: 17px; font-variant-numeric: tabular-nums; }
.wbfin-pop-profit .wbfin-pop-note { flex-basis: 100%; }
.wbfin-pop-block { margin-bottom: 14px; }
.wbfin-pop-block:last-child { margin-bottom: 0; }
.wbfin-pop-head { display: flex; justify-content: space-between; gap: 12px; padding-bottom: 6px; border-bottom: 1px solid var(--line); font-weight: 600; font-size: 13px; }
.wbfin-pop-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.wbfin-pop-row:last-child { border-bottom: 0; }
.wbfin-pop-left { min-width: 0; flex: 1 1 auto; }
.wbfin-pop-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wbfin-pop-note { color: var(--muted); font-size: 12px; margin-top: 1px; }
.wbfin-pop-sum { flex: 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--tile-rose-text); }
.wbfin-pop-head .wbfin-pop-sum { font-weight: 600; }
.wbfin-pop-neg { color: var(--tile-rose-text); }
.wbfin-pop-more { padding-top: 7px; color: var(--muted); font-size: 13px; }
.wbfin-table td.wbfin-name { min-width: 180px; }
.wbfin-name-box { display: flex; align-items: center; gap: 8px; }
.wbfin-chevron { width: 10px; color: var(--muted); flex: 0 0 auto; }
.wbfin-photo { width: 44px; height: 58px; object-fit: cover; border-radius: 4px; flex: 0 0 auto; }
.wbfin-name-text { min-width: 0; }
.wbfin-article { font-weight: 600; }
.wbfin-subject { color: var(--muted); font-size: 12px; }
.wbfin-open-able { cursor: pointer; }
.wbfin-open-able:hover td { background: var(--hover); }
.wbfin-size td { background: var(--panel-2); color: var(--muted); }
.wbfin-size td.unit-sticky { background: var(--panel-2); padding-left: 34px; }
.wbfin-sortable { cursor: pointer; }
.wbfin-sortable:hover { color: var(--text); }
.wbfin-sort-mark { color: var(--text); }
.wbfin-cost-src { color: var(--muted); font-size: 11px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; }
.wbfin-cost-edit { cursor: pointer; }
.wbfin-cost-edit:hover { background: var(--hover); }
.wbfin-cost-none { color: var(--muted); }
.wbfin-general-list { display: flex; flex-direction: column; }
.wbfin-general-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.wbfin-general-row:last-child { border-bottom: 0; }
.wbfin-general-sum { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Часть общей строки разложена по товарам (03.11.2026) — мелко под суммой. */
.wbfin-general-row:has(.wbfin-general-note) { flex-wrap: wrap; row-gap: 0; }
.wbfin-general-note { flex-basis: 100%; text-align: right; color: var(--muted); font-size: 12px; }
/* Какие товары показывать (27.10.2026): строка над таблицей, «Скрыть» в строке, окно выбора. */
.wbfin-pickbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.wbfin-pickbar .btn { margin-left: auto; }
.wbfin-hide { margin-left: auto; padding: 2px 8px; opacity: 0; transition: opacity .15s; }
.wbfin-row:hover .wbfin-hide, .wbfin-hide:focus-visible { opacity: 1; }
@media (hover: none) { .wbfin-hide { opacity: 1; } }
.wbfin-name-box .wbfin-name-text { flex: 1 1 auto; }
.wbfin-pick-bulk { display: flex; align-items: center; gap: 6px; margin: 10px 0 6px; }
.wbfin-pick-count { margin-left: auto; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.wbfin-pick-list { display: flex; flex-direction: column; max-height: 55vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.wbfin-pick-row { display: flex; align-items: center; gap: var(--gap); padding: 8px 10px; border-bottom: 1px solid var(--line); cursor: pointer; }
.wbfin-pick-row:last-child { border-bottom: 0; }
.wbfin-pick-row:hover { background: var(--hover); }
.wbfin-pick-row input { flex: 0 0 auto; }
.wbfin-pick-filter { display: flex; gap: 8px; flex-wrap: wrap; }
.wbfin-pick-filter > * { flex: 1 1 200px; min-width: 0; }
.wbfin-pick-nosales { margin-left: auto; color: var(--muted); font-size: 12px; white-space: nowrap; }
@media (max-width: 620px) {
  .wbfin-period { min-width: 0; }
}
/* «Финансовый отчёт» подробнее (27.10.2026): прибыль столбиками, «кто приносит деньги»,
   разворот товара. Прибыль — зелёным, убыток — розовым, как в плитках и таблице. */
.wbfin-trend { padding: 12px 14px; margin-bottom: 12px; }
.wbfin-trend-title { font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.wbfin-chart { display: block; width: 100%; max-width: 640px; height: auto; overflow: visible; }
.wbfin-chart-mini { width: 240px; max-width: 100%; }
.wbfin-bar-hit { fill: var(--text); fill-opacity: 0; }
.wbfin-bar-up { fill: var(--tile-green-text); }
.wbfin-bar-down { fill: var(--tile-rose-text); }
.wbfin-bar path { opacity: .45; transition: opacity .12s; }
.wbfin-bar.on path, .wbfin-bar:hover path { opacity: 1; }
.wbfin-bar.pick { cursor: pointer; }
.wbfin-zero { stroke: var(--line); stroke-width: 1; }
.wbfin-axis { fill: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.wbfin-bar.on .wbfin-axis { fill: var(--text); font-weight: 600; }
.wbfin-chart-value { fill: var(--text); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
.wbfin-orders-line { margin: -4px 0 12px; }
.wbfin-since { display: inline-flex; align-items: center; }
.wbfin-hidden-count { color: var(--muted); font-size: 13px; }
/* Фильтр отчёта (29.10.2026): категории галочками, товары под стрелкой, скрытые — счётчиком. */
.wbfin-filter { margin-bottom: 12px; }
.wbfin-filter-bar { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.wbfin-filter-panel { margin-top: 8px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); max-width: 720px; }
.wbfin-filter-list { max-height: 60vh; }
.wbfin-filter-group { border-bottom: 1px solid var(--line); }
.wbfin-filter-group:last-child { border-bottom: 0; }
.wbfin-filter-group .wbfin-pick-row { border-bottom: 0; }
.wbfin-filter-cat { cursor: default; font-weight: 600; }
.wbfin-filter-cat-name { display: flex; align-items: center; gap: 8px; cursor: pointer; flex: 1 1 auto; min-width: 0; }
.wbfin-filter-cat-count { color: var(--muted); font-weight: 400; font-size: 13px; font-variant-numeric: tabular-nums; }
.wbfin-filter-chevron { border: 0; background: none; color: var(--muted); cursor: pointer; width: 18px; padding: 0; font-size: 13px; }
.wbfin-filter-hidden-link { border: 0; background: none; color: var(--accent); cursor: pointer; font-size: 13px; padding: 0 4px; white-space: nowrap; }
.wbfin-filter-hidden-link:hover { text-decoration: underline; }
.wbfin-filter-items { padding-left: 28px; }
.wbfin-filter-item { padding-top: 6px; padding-bottom: 6px; }
.wbfin-filter-hidden { background: var(--panel-2); }
.wbfin-filter-note { color: var(--muted); font-size: 12px; padding: 6px 10px 2px; }
.wbfin-filter-panel .row-actions { margin-top: 10px; }
.wbfin-filter-empty-head { display: block; width: 100%; text-align: left; border: 0; border-top: 1px solid var(--line); background: none; color: var(--muted); cursor: pointer; padding: 8px 10px; font-size: 13px; }
.wbfin-filter-empty { padding-left: 0; }
.wbfin-signals { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.wbfin-signal { display: flex; align-items: baseline; gap: var(--gap); flex-wrap: wrap; padding: 8px 12px; border-radius: var(--radius); font-size: 13px; }
.wbfin-signal-ok { background: var(--tile-green-bg); color: var(--tile-green-text); }
.wbfin-signal-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.wbfin-signal-warn { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.wbfin-signal-title { font-weight: 600; }
.wbfin-signal-list { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.wbfin-signal-chip {
  border: 1px solid currentColor; border-radius: 999px; background: none; color: inherit; font: inherit;
  font-size: 12px; padding: 1px 9px; cursor: pointer; font-variant-numeric: tabular-nums;
}
.wbfin-signal-chip:hover { background: var(--panel); }
.wbfin-signal-text { font-size: 13px; }
.wbfin-chip { display: inline-block; margin-top: 3px; padding: 0 7px; border-radius: 999px; font-size: 11px; white-space: nowrap; }
.wbfin-chip-ok { background: var(--tile-green-bg); color: var(--tile-green-text); }
.wbfin-chip-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.wbfin-chip-warn { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.wbfin-chip-none { background: var(--panel-2); color: var(--muted); }
/* Товары без себестоимости — своим блоком внизу таблицы, красным (аудит 31.10.2026): в прибыль не вошли. */
.wbfin-chip-nocost { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.wbfin-row-nocost > td, .wbfin-row-nocost .wbfin-article { color: var(--tile-rose-text); }
.wbfin-group-row > td { background: var(--tile-rose-bg); color: var(--tile-rose-text); font-weight: 600; font-size: 13px; text-align: left; }
.wbfin-group-row > td > span { position: sticky; left: 12px; }
.wbfin-trust {
  display: inline-block; max-width: 100%; margin-top: 6px; border: 0; font: inherit; font-size: 11px; line-height: 1.35;
  white-space: normal; text-align: left; cursor: pointer;
}
.wbfin-trust:hover { filter: brightness(0.96); }
.wbfin-checks { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 10px; }
.wbfin-check { display: flex; gap: 8px; align-items: baseline; font-size: 13px; }
.wbfin-check-mark { flex: 0 0 14px; font-weight: 600; }
.wbfin-check-ok .wbfin-check-mark { color: var(--tile-green-text); }
.wbfin-check-warn .wbfin-check-mark { color: var(--tile-yellow-text); }
.wbfin-check-bad { color: var(--tile-rose-text); }
.wbfin-batch { padding: 6px 0; border-top: 1px solid var(--line); }
.wbfin-batch:first-of-type { border-top: 0; }
.wbfin-batch-head { font-size: 13px; font-weight: 500; }
.wbfin-batch-line { font-size: 13px; font-variant-numeric: tabular-nums; }
.wbfin-card select { width: 100%; margin-top: 6px; }
.wbfin-detail-row > td { background: var(--panel-2); padding: 10px 12px; }
.wbfin-detail { position: sticky; left: 12px; display: flex; flex-wrap: wrap; gap: var(--gap); text-align: left; white-space: normal; }
.wbfin-card { flex: 0 1 260px; min-width: 220px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
.wbfin-card-title { font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.wbfin-card-row { display: flex; justify-content: space-between; gap: var(--gap); font-size: 13px; padding: 2px 0; }
.wbfin-card-val { font-variant-numeric: tabular-nums; white-space: nowrap; }
.wbfin-card-big { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
.wbfin-card-note { color: var(--muted); font-size: 12px; margin-top: 4px; }
.wbfin-card .btn { margin-top: 8px; }
.wbfin-bad-text, .wbfin-card-note.wbfin-bad-text { color: var(--tile-rose-text); }
.wbfin-plan { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.wbfin-plan th { color: var(--muted); font-weight: 500; text-align: right; padding: 2px 0 4px 8px; }
.wbfin-plan td { padding: 2px 0 2px 8px; text-align: right; white-space: nowrap; }
.wbfin-plan td:first-child { text-align: left; padding-left: 0; }
.wbfin-export { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
/* Окно «Вы изменили фабрики в таблице» (28.10.2026): строка на правку с галочкой. */
.factory-edits { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; max-height: 50vh; overflow-y: auto; }
.factory-edit { display: flex; gap: 8px; align-items: flex-start; font-size: 13px; line-height: 1.35; cursor: pointer; }
.factory-edit input { margin-top: 2px; flex: none; }
.factory-edit + .factory-edit { border-top: 1px solid var(--line); padding-top: 6px; }


/* ── Окно «На сегодня» при входе в «Задачи» (28.10.2026, `ui/today.js`) ──────── */
.today-modal { z-index: 45; }
/* Вопрос из строки окна («Утвердить образец?», «Что исправить», 10.11.2026) — над ним, а не под ним. */
body:has(> .today-modal) #ask-modal { z-index: 46; }
/* «Настройки», открытые поверх другого окна (13.11.2026, `openManage` → `.over-modal`): над ним, вопрос — над ними. */
#manage-modal.over-modal { z-index: 41; }
body:has(> #manage-modal.over-modal:not(.hidden)) #ask-modal { z-index: 42; }
.today-panel { width: min(980px, calc(96vw - var(--chat-room))); max-height: 90vh; }
.today-head {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 22px 14px; border-bottom: 1px solid var(--line);
  background: var(--accent-dim);
}
.today-title { flex: 1; min-width: 0; }
.today-title h2 { margin: 0; font-family: var(--font-display); font-size: 24px; color: var(--accent-ink); }
.today-date { color: var(--muted); font-size: 13px; margin-top: 2px; }
.today-left {
  font-weight: 650; font-size: 13px; color: var(--accent-ink);
  background: var(--panel); border-radius: 999px; padding: 4px 12px;
}
.today-left:empty { display: none; }
.today-made {
  font-weight: 650; font-size: 13px; color: var(--ink-green); white-space: nowrap;
  background: var(--panel); border-radius: 999px; padding: 4px 12px;
}
.today-made:empty { display: none; }
/* Сделанное (02.11.2026): строка «✓ … Сделано · Вернуть» на месте задачи. */
.today-marking { opacity: .55; pointer-events: none; transition: opacity .15s; }
.today-done-line {
  display: flex; align-items: center; gap: var(--gap); padding: 8px 10px 8px 14px; margin-bottom: 10px;
  border: 1px dashed var(--line); border-radius: var(--radius); background: var(--accent-dim); font-size: 13px;
}
.today-done-mark { color: var(--ok); font-weight: 700; }
.today-done-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); }
.today-done-word { color: var(--ink-green); font-weight: 650; font-size: 13px; }
.today-made-group .today-group-count { display: none; }
.today-x { font-size: 20px; line-height: 1; }
.today-body { padding: 16px 22px 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 22px; }
.today-group-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 10px; }
.today-group-head h3 { margin: 0; font-size: 15px; font-weight: 700; }
.today-group-count {
  font-size: 12px; font-weight: 700; min-width: 22px; text-align: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; padding: 1px 7px;
}
.today-group-hint { color: var(--muted); font-size: 13px; }
.today-list { display: flex; flex-direction: column; gap: var(--gap); }
.today-item {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 1px 3px var(--shadow-soft);
}
.today-script { padding: 12px 14px; display: flex; flex-direction: column; gap: var(--gap); }
.today-script.copied { border-color: var(--accent); }
.today-item-head { display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.today-item-title { display: flex; align-items: baseline; gap: 8px; flex: 1; min-width: 0; flex-wrap: wrap; }
.today-item-title strong { font-size: 14px; }
.today-what { color: var(--text-2); font-size: 13px; overflow-wrap: anywhere; }
.today-kind {
  font-size: 12px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
  border-radius: 6px; padding: 3px 8px; white-space: nowrap;
  background: var(--tile-green-bg); color: var(--tile-green-text-2);
}
.today-kind.kind-size { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.today-kind.kind-stall { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.today-kind.kind-overdue { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.today-kind.kind-silent { background: var(--panel-2); color: var(--muted); }
/* 31.10.2026: тишина фабрики 10+ дней — тревога, срок готовности, образец без дня отправки. */
.today-kind.kind-quiet { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.today-kind.kind-dates { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.today-kind.kind-sample { background: var(--tile-blush-bg); color: var(--tile-blush-text); }
/* 08.11.2026: фабрика обещала отправить образец сегодня. */
.today-kind.kind-ship { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
/* 09.11.2026: заказ готов к отгрузке три дня и больше, а не отгружен. */
.today-kind.kind-unshipped { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.today-wait {
  font-size: 12px; font-weight: 600; border-radius: 999px; padding: 1px 9px;
  background: var(--panel-2); color: var(--text-2);
}
.today-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.today-meta .task-due { font-size: 12px; line-height: 20px; }
.today-to { font-size: 13px; font-weight: 600; color: var(--text-2); }
.today-asked { font-size: 13px; color: var(--muted); }
.today-who {
  font-size: 12px; font-weight: 650; border-radius: 999px; padding: 1px 9px;
  background: var(--tile-violet-bg); color: var(--tile-violet-text);
}
.today-who::before { content: 'Поручено · '; font-weight: 500; }
.today-text { min-height: 60px; font-size: 15px; }
.today-photos { display: flex; flex-direction: column; gap: 4px; }
.today-photo-hint { font-size: 13px; font-weight: 650; color: var(--warn-ink); }
.today-photos .price-ask-photo-tile { width: 64px; height: 64px; }
.today-actions { display: flex; gap: 8px; justify-content: flex-end; }
.today-actions .btn { min-width: 116px; }
/* «Уже отправили?» — образцы письма строками и день отправки (13.11.2026). */
.today-actions .today-sent-open { margin-right: auto; }
.today-sent {
  display: flex; flex-direction: column; gap: 8px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
}
.today-sent-title { font-size: 13px; font-weight: 650; color: var(--text-2); }
.today-sent-row { display: flex; align-items: center; gap: 12px; }
.today-sent-name { flex: 1; min-width: 0; font-size: 14px; overflow-wrap: anywhere; }
.today-sent-date { width: 160px; }
.today-sent-actions { display: flex; gap: 8px; justify-content: flex-end; }
.today-row { display: flex; flex-direction: column; gap: var(--gap); padding: 10px 14px; }
.today-row-line { display: flex; align-items: center; gap: 12px; }
.today-row-body.clickable { cursor: pointer; }
.today-row.open { border-color: var(--accent); }
.today-expand::after { content: ' ▾'; }
.today-row.open .today-expand::after { content: ' ▴'; }
.today-more { display: flex; flex-direction: column; gap: var(--gap); padding-top: 10px; border-top: 1px solid var(--line); }
.today-note { font-size: 13px; color: var(--text-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.today-checks { display: flex; flex-direction: column; gap: 6px; }
.today-check { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.today-check.nested { padding-left: 26px; }
.today-check.done .today-check-text { color: var(--muted); text-decoration: line-through; }
.today-check-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.today-sub-script {
  display: flex; flex-direction: column; gap: 8px; margin-left: 26px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
}
.today-sub-script.copied { border-color: var(--accent); }
.today-reply { display: flex; flex-direction: column; gap: 6px; }
.today-reply-label { font-size: 13px; font-weight: 650; color: var(--text-2); }
.today-reply-ru { width: 100%; font: inherit; font-size: 14px; resize: vertical; }
.today-more-foot { justify-content: flex-start; }
.today-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.today-row-text { font-size: 14px; overflow-wrap: anywhere; }
.today-quote {
  font-size: 13px; color: var(--text-2); border-left: 3px solid var(--line);
  padding-left: 8px; overflow-wrap: anywhere;
}
.today-empty { text-align: center; padding: 28px 0; font-size: 16px; color: var(--accent-ink); font-weight: 650; }
.today-verdict { justify-content: flex-start; flex-wrap: wrap; }
.today-verdict .btn { min-width: 0; }
.today-verdict .today-done { margin-left: auto; }
.today-fitting-open { cursor: pointer; border-radius: 8px; }
.today-fitting-open:hover .today-row-text { color: var(--accent-ink); text-decoration: underline; }
.today-fitting-note {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.today-foot { display: flex; justify-content: flex-end; padding: 10px 22px 14px; border-top: 1px solid var(--line); }
@media (max-width: 640px) {
  .today-head, .today-body, .today-foot { padding-left: 14px; padding-right: 14px; }
  .today-row-line { flex-direction: column; align-items: stretch; }
  .today-actions .btn { flex: 1; min-width: 0; }
}


/* ── «Аналитика»: общий вид подразделов (28.10.2026, её слово: «сделай красивее интерфейс всех
   подразделов аналитики и удобнее»). Кадр подраздела помечен `.an-page` (`analyticsTabs` в app.js):
   вкладки подразделов сверху, кнопки — одной панелью, плитки — на всю ширину ряда. Общие
   `.analytics-*` вне кадра («Завершено», «КИЗы», досье фабрики) не тронуты. */
.an-tabs {
  display: flex; gap: 4px; width: fit-content; max-width: 100%; margin-bottom: 12px; padding: 4px;
  background: var(--c-f4f1e8-s); border-radius: var(--radius); overflow-x: auto; scrollbar-width: none;
}
.an-tabs::-webkit-scrollbar { display: none; }
.an-tab {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; padding: 7px 14px;
  border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--muted);
  font: inherit; font-size: 13px; white-space: nowrap; cursor: pointer; transition: background .15s, color .15s;
}
.an-tab svg { flex: 0 0 auto; }
.an-tab:hover { color: var(--text); background: var(--hover); }
.an-tab.on {
  background: var(--paper); color: var(--text); font-weight: 650; cursor: default;
  box-shadow: 0 1px 3px var(--c-rgba-60-50-35-08-s);
}
.an-tab.on svg { color: var(--ink-green); }
.an-tab:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.an-page > .section-head {
  margin-bottom: 14px; padding: 8px 10px; gap: var(--gap);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
}
.an-page > .section-head > .section-actions { flex: 1 1 auto; }
.an-page .analytics-since { margin: -4px 0 12px; }
.an-page .analytics-tiles { grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); gap: 12px; }
.an-page .analytics-tile { padding: 14px 16px; gap: 6px; box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s); }
.an-page .analytics-tile-label { font-size: 13px; }
.an-tile-static { cursor: default; }
.an-tile-static:hover:not(:disabled) { transform: none; border-color: var(--line); }
.an-page .analytics-findings { box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s); }
.an-page .analytics-f-row { padding: 12px 16px; }
.an-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; }
/* «Юнит экономика»: курс — у правого края панели, ориентир литража — плашками в строку. */
.an-page .unit-rates-line { margin: 0 4px 0 auto; font-size: 12px; }
.unit-sheet-pair { display: inline-flex; align-items: center; gap: 2px; }
.an-page .unit-top { margin: 0 0 14px; }
.an-page .unit-top:has(> .unit-params.hidden) { grid-template-columns: minmax(0, 1fr); }
.an-page .unit-liters { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; padding: 10px 14px; }
.an-page .unit-liters > .unit-card-head { margin: 0; justify-content: flex-start; gap: 4px; }
.unit-liters-list { display: flex; flex-wrap: wrap; gap: 6px; }
.unit-liter {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 10px; font-size: 13px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
}
.unit-liter-name { color: var(--text-2); }
.unit-liter-value { font-weight: 600; font-variant-numeric: tabular-nums; }
.an-page .unit-tiles { margin-bottom: 14px; }
.an-page .unit-table-scroll { box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s); }
/* «Финансовый отчёт»: график и «кто приносит деньги» рядом; график — во всю свою колонку. */
.wbfin-overview {
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(260px, 1fr); gap: 12px;
  align-items: start; margin-bottom: 14px;
}
.wbfin-overview > .wbfin-trend, .wbfin-overview > .wbfin-signals { margin-bottom: 0; }
/* «Куда ушли деньги» и свои расходы (29.10.2026): лесенка от продаж до прибыли, цвет — хорошо / на грани / плохо. */
.wbfin-money-one { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
.wbfin-ladder, .wbfin-expenses { padding: 14px 16px; }
.wbfin-ladder > *, .wbfin-expenses > * { margin: 0; }
.wbfin-block-title { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 14px; margin-bottom: 10px; }
.wbfin-ladder-row {
  display: grid; grid-template-columns: minmax(120px, 34%) minmax(40px, 1fr) auto 56px; gap: var(--gap); align-items: center;
  padding: 5px 0; font-size: 13px;
}
.wbfin-ladder-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wbfin-ladder-minus .wbfin-ladder-label, .wbfin-ladder-plus .wbfin-ladder-label { padding-left: 12px; color: var(--text-2); }
.wbfin-ladder-total { border-top: 1px solid var(--line); margin-top: 3px; padding-top: 8px; font-weight: 600; }
.wbfin-ladder-bar { height: 8px; border-radius: 999px; background: var(--panel-2); overflow: hidden; }
.wbfin-ladder-fill { display: block; height: 100%; border-radius: 999px; }
.wbfin-ladder-fill-base { background: var(--line); }
.wbfin-ladder-fill-cost { background: var(--tile-rose-bg); box-shadow: inset 0 0 0 1px var(--tile-rose-text); opacity: .7; }
.wbfin-ladder-fill-good { background: var(--tile-green-text); opacity: .55; }
.wbfin-ladder-fill-bad { background: var(--tile-rose-text); opacity: .65; }
.wbfin-ladder-sum { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.wbfin-ladder-share { text-align: right; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.wbfin-tone-text-good { color: var(--tile-green-text); }
.wbfin-tone-text-bad { color: var(--tile-rose-text); }
.wbfin-expenses-head .btn { margin-left: auto; }
.wbfin-expenses-sum { color: var(--tile-rose-text); font-variant-numeric: tabular-nums; }
.wbfin-expense-row { display: flex; align-items: center; gap: var(--gap); padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.wbfin-expense-row:last-child { border-bottom: 0; }
.wbfin-expense-text { flex: 1 1 auto; min-width: 0; }
.wbfin-expense-note { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wbfin-expense-sum { white-space: nowrap; font-variant-numeric: tabular-nums; font-weight: 600; }
.wbfin-expense-del { padding: 0 8px; }
.unit-table td.wbfin-tone-good, .wbfin-legend-dot.wbfin-tone-good { background: var(--tile-green-bg); color: var(--tile-green-text); font-weight: 600; }
.unit-table td.wbfin-tone-warn, .wbfin-legend-dot.wbfin-tone-warn { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); font-weight: 600; }
.unit-table td.wbfin-tone-bad, .wbfin-legend-dot.wbfin-tone-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); font-weight: 600; }
/* Выкуп WB по нескольким заказам — серым, не красным (14.11.2026). */
.unit-table td.wbfin-tone-muted { color: var(--muted); }
.wbfin-legend { display: flex; align-items: center; gap: 14px; margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.wbfin-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.wbfin-legend-dot { width: 12px; height: 12px; border-radius: 3px; box-shadow: inset 0 0 0 1px var(--line); }
@media (max-width: 1000px) { .wbfin-money-one { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) {
  .wbfin-ladder-row { grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
  .wbfin-ladder-bar, .wbfin-ladder-share { display: none; }
  .wbfin-ladder-label { white-space: normal; overflow: visible; }
}
.an-page .wbfin-trend { padding: 14px 16px; }
.an-page .wbfin-trend-title { font-size: 14px; margin-bottom: 10px; }
.an-page .wbfin-chart { max-width: none; }
.an-page .wbfin-signal { padding: 10px 14px; }
@media (max-width: 1000px) {
  .wbfin-overview { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .an-tab { padding: 7px 10px; font-size: 13px; }
  .an-page .unit-rates-line { margin-left: 0; flex-basis: 100%; }
  .an-page .analytics-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .an-page .analytics-tile { padding: 10px 12px; }
  .an-page .analytics-tile-top { min-width: 0; max-width: 100%; }
  .an-page .analytics-tile-value { font-size: 19px; }
  .an-page .wbfin-tile-profit { grid-column: 1 / -1; }
  .an-page .wbfin-trend { overflow-x: auto; }
  .an-page .wbfin-chart { min-width: 520px; }
  /* Листается вбок — открывается на выбранной (последней) неделе, а не на самой старой (аудит 13.11.2026, 375 px). */
  .an-page .wbfin-trend { direction: rtl; }
  .an-page .wbfin-trend > * { direction: ltr; }
}

/* ── «+ Заказ»: две двери и окно «Создать заказ» (29.10.2026, ui/order-create.js) ── */
.new-order-menu {
  position: fixed; z-index: 60; width: 290px; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 18px 50px var(--shadow-soft);
  display: flex; flex-direction: column; gap: 4px;
}
.new-order-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 10px 12px; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--text); text-align: left; cursor: pointer; font: inherit;
}
.new-order-item:hover, .new-order-item:focus-visible { background: var(--hover); outline: none; }
.new-order-item .muted { font-size: 12px; }
/* Пункт выбора, которого сейчас нет (03.11.2026, «+ Драфт» без образца в работе). */
.new-order-item:disabled { opacity: .5; cursor: default; background: none; }
.oc-head { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.oc-goods { margin-top: var(--pad-lg); display: flex; flex-direction: column; gap: 8px; position: relative; }
.oc-search { display: flex; gap: 8px; align-items: center; }
.oc-search input { flex: 1; min-width: 0; }
.oc-pick {
  max-height: 300px; overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px;
}
.oc-pick-row {
  display: flex; align-items: center; gap: var(--gap); width: 100%; padding: 6px 8px;
  border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.oc-pick-row:hover { background: var(--hover); }
.oc-pick-row .muted { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oc-pick-price { font-variant-numeric: tabular-nums; }
.oc-pick-empty { padding: 10px; }
.oc-photo {
  flex: none; width: 40px; height: 40px; border-radius: var(--radius-sm); overflow: hidden;
  background: var(--panel-2); display: inline-flex;
}
.oc-photo img { width: 100%; height: 100%; object-fit: cover; }
.oc-rows { display: flex; flex-direction: column; gap: var(--gap); }
.oc-row { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; display: flex; flex-direction: column; gap: var(--gap); }
.oc-row-head { display: flex; align-items: center; gap: var(--gap); }
.oc-row-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.oc-row-name .muted { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oc-price-box { display: inline-flex; align-items: center; gap: 6px; }
.oc-price { width: 86px; }
.oc-sizes { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.oc-size {
  display: flex; flex-direction: column; gap: 4px; width: 108px; padding: 6px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel-2);
}
.oc-size.on { border-color: var(--accent); background: var(--accent-dim); }
.oc-size-name { font-size: 12px; font-weight: 600; white-space: nowrap; }
.oc-size-name .muted { font-weight: 400; }
.oc-size input { width: 100%; }
.oc-size-new { width: 140px; }
.oc-foot { margin-top: var(--pad-lg); justify-content: flex-end; gap: 12px; }
.oc-total { margin-right: auto; margin-left: 8px; font-variant-numeric: tabular-nums; }
.osp-head { grid-template-columns: minmax(150px, 1fr) minmax(200px, 1.4fr) auto; align-items: end; }
.osp-find { display: flex; align-items: flex-end; }
.osp-body { margin-top: var(--pad-lg); display: flex; flex-direction: column; gap: 12px; }
.osp-blocks { display: flex; flex-direction: column; gap: 8px; }
.osp-block {
  display: flex; flex-direction: column; gap: 6px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
}
.osp-block:has(> .osp-photo) { flex-direction: row; align-items: flex-start; gap: 12px; }
.osp-photo {
  flex: none; width: 64px; height: 64px; border-radius: var(--radius-sm); overflow: hidden; background: var(--panel-2);
}
.osp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.osp-block-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.osp-deleted {
  padding: 8px 12px; border-radius: var(--radius-sm); font-size: 13px;
  background: var(--tile-yellow-bg); color: var(--tile-yellow-text);
}
.osp-sizes { display: flex; flex-wrap: wrap; gap: 6px; }
.osp-size {
  display: inline-flex; gap: 6px; align-items: baseline; padding: 2px 8px;
  border: 1px solid var(--line); border-radius: 999px; font-size: 12px; font-variant-numeric: tabular-nums;
}
.osp-block-no .osp-size { border-color: currentColor; }
.osp-block-head { display: flex; align-items: baseline; gap: var(--gap); min-width: 0; }
.osp-block-head .muted { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.osp-block-head input[type="checkbox"] { align-self: center; }
.osp-block-no-num { white-space: nowrap; }
.osp-block-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.osp-block-line > :last-child:not(span):not(b) { margin-left: auto; min-width: 200px; }
.osp-sum { min-width: 80px; }
.osp-price { width: 86px; }
.osp-hint { font-size: 12px; }
.osp-block-off { opacity: .5; }
.osp-block-done { opacity: .65; }
.osp-block-no { background: var(--tile-rose-bg); border-color: transparent; color: var(--tile-rose-text); }
.osp-block-no .muted { color: inherit; opacity: .8; }
.osp-block-ok { background: var(--tile-green-bg); border-color: transparent; color: var(--tile-green-text); }
.osp-error {
  display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: var(--radius-sm);
}
.osp-error { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
@media (max-width: 640px) {
  .osp-head { grid-template-columns: 1fr; }
  .osp-block-line > :last-child:not(span):not(b) { margin-left: 0; width: 100%; }
}
@media (max-width: 640px) {
  .oc-row-head { flex-wrap: wrap; }
  .oc-size { width: calc(33% - 6px); }
}

/* ── АУДИТ ИНТЕРФЕЙСА 29.10.2026 (просьба владелицы: «причеши, где что съехало,
   кнопочки покрасивее, всё ли читается, не съезжают ли буквы») ─────────────
   Замер каждого раздела на копии базы (1440 и 1100 px, светлая и тёмная тема):
   высоты в ряду, текст за краем коробки, наложения. Правки собраны здесь, чтобы
   их было видно одним куском и не спорить с соседними правилами по порядку. */

/* Шапка: всё в ряд одной высоты — 36 px. Было 32/30/38/36: стрелки, часы и тема
   ниже кнопок, поиск выше, ряд читался ступенькой. */
.topbar .icon-btn { width: 36px; height: 36px; }
.topbar .topbar-clock { height: 36px; }
.topbar .filters input { padding-top: 7px; padding-bottom: 7px; }

/* Кнопка внутри заголовка набиралась шрифтом заголовка (Literata): «Все скрипты»
   в «Задачах», «+» у «Повторяющихся задач». Кнопка всегда пишет шрифтом CRM. */
.btn, .icon-btn, .info-dot {
  font-family: Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

/* Свёрнутое меню: у «Лога» метка «BETA» стояла в ряд со значком и сдвигала его
   на 18 px влево от остальных. Теперь значок на своём месте, метка — мелко под ним. */
.shell.nav-collapsed .side-item-beta .beta-mark {
  position: absolute; left: 50%; bottom: -5px; transform: translateX(-50%);
  margin: 0; padding: 0 3px; font-size: 8px; line-height: 11px; letter-spacing: .06em;
  background: var(--panel); border-radius: 3px;
}
.shell.nav-collapsed .side-item-beta { margin-bottom: 4px; }

/* Плитки «Завершено» и «Сокращения расходов» стояли узкими в левой половине
   ряда (сетка на восемь мест при четырёх плитках), и крупная сумма вылезала из
   плитки под «i». Теперь плитки делят ряд поровну. */
.analytics-tiles.closed-tiles {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
}
.analytics-tiles.savings-an-tiles {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.analytics-tile-top { max-width: 100%; }
.analytics-tile-value { min-width: 0; overflow-wrap: anywhere; }

/* Мелочь, которую трудно прочесть: подписи часов «ЮАР · Москва · Пекин» были
   9 px, «причина не найдена» на карточке заказа — 9.5 px, а число у скрепки на
   карточке — светлее нормы контраста (3 : 1 при нужных 4.5). */
.tc-label { font-size: 10px; }
.card-reason-label { font-size: 10px; }
.card-links { color: var(--muted); }

/* Доска: «Запросить причины» в шапке колонки была сдвинута на 11 px вправо от
   карточек под ней и тоньше их кнопок (22 px). Теперь по краям карточек и
   ростом с кнопку «Отправить на ОТК». */
.col-head:has(> .col-action) { padding-left: 8px; padding-right: 8px; }
.col-head > .col-action { margin-left: 0; min-height: 26px; }

/* Флажки и переключатели — цветом CRM, а не системным синим: в чек-листе
   «Продуктов» ярко-синие галочки стояли на зелёной плашке. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--ink-green); }

/* Чек-лист товара: у пункта справа невидимая до наведения кнопка «изменить»,
   у подпункта её нет — и даты подпунктов стояли на 31 px правее дат пунктов,
   столбик дат шёл зубцами. Подпункт держит то же место справа. */
.checklist-sub:not(:has(.checklist-edit)) { padding-right: 37px; }
/* Счёт «7 из 7» стоял посреди шапки чек-листа (раскладка «по краям» на три
   части) — теперь справа, рядом с кнопкой «Пункты». */
.checklist-head > .checklist-count { margin-left: auto; }
/* Календарь задач: «Я / Викусик» и «Отпуска» висели посреди ряда с дырами по
   200 px. Они — рядом с годом, как в плане недели; «+ Задача» — справа. */
.cal-bar { justify-content: flex-start; }
.cal-bar > .btn-primary:last-child { margin-left: auto; }
/* «Настройки» (Бренды · Производства · Доступ): окно стояло по центру и при
   смене вкладки прыгало вверх-вниз на 50 px — у вкладок разная высота. Окно
   держится от верха, вкладки меняются под той же шапкой. */
#manage-modal { align-items: start; }
#manage-modal > .modal-panel { margin-top: 6vh; }
/* «Контрагенты»: карточки одного ряда были разной высоты, и кнопки «Скопировать
   адрес · Редактировать» стояли ступеньками. Ряд — одной высоты, кнопки — внизу. */
.card-grid.ctr-parties { align-items: stretch; }
.ctr-parties > .party-card > .entity-card-actions { margin-top: auto; }
/* Разделы-ленты докручиваются выше круглой кнопки чата: у нижней строки
   («Ответили» у последней просьбы фабрики в «Задачах») кнопка лежала прямо на
   ней. Разделы из двух колонок во всю высоту («Продукты», «Таблицы», «Ревью»)
   не трогаем — у них снизу встала бы пустая полоса. */
#section-view:is([data-section="tasks"], [data-section="closed"], [data-section="savings"],
  [data-section="kiz"], [data-section="trace"], [data-section="trends"],
  [data-section="analytics"], [data-section="unit"], [data-section="wb_finance"],
  [data-section="factories"]) { padding-bottom: 80px; }
/* «Просьбы фабрик»: «Выбрать производство» стояла в 57 px от правого края блока. */
.task-board-head > .task-pick { display: flex; justify-content: flex-end; }
/* «Работа фабрик», раскрытый блок: у каждой строки полоска своей длины —
   подпись справа («10 заказов · в ср. 12 дней» против «7 заказов…») съедала
   разное место, и полоски нельзя было сравнить глазом. Подпись — в столбике
   одной ширины, полоски одной длины. */
.analytics-bar-row { grid-template-columns: minmax(90px, 32%) minmax(0, 1fr) minmax(12.5em, auto); }
.analytics-bar-value { text-align: right; }
/* «Работа фабрик» на телефоне (аудит 13.11.2026): подпись, полоса и «15 заказов · в ср. 11 дней» в одну строку
   не влезали — полоса сжималась в ноль, число обрезалось краем («в ср. 11 дне»), подпись — в «Бирки, этик…».
   Узко — подпись своей строкой во всю ширину, под ней полоса и число. */
/* Плитка списком — «1 драфт — 13 моделей» строками (её ответ 14.11.2026). */
.analytics-tile-list { white-space: pre-line; }
@media (max-width: 640px) {
  .analytics-bar-row { grid-template-columns: minmax(0, 1fr) auto; }
  .analytics-bar-label { grid-column: 1 / -1; white-space: normal; }
}

/* «Лог»: у строки без стрелки время стояло на 3 px правее, чем у строки со
   стрелкой, — столбик времени шёл зубцами. */
.jr-leaf .jr-head { padding-left: 27px; }

/* Обычная выпадашка (<select>) — со стрелкой той же, что у выпадашки с поиском
   (`.combo-input`): на одном экране стояли две разные стрелки («Папка» и
   «Размер» в «КИЗах», «Статус» и «Производство» в карточке заказа). Свойства
   стрелки — с `!important`: правила разделов задают `background` целиком и
   иначе стёрли бы её вместе с фоном. */
select:not([multiple]):not([size]) {
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%237a7268' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 10px center !important;
  background-size: 10px 6px !important;
  padding-right: 28px !important;
  cursor: pointer;
  text-overflow: ellipsis;
}
select:not([multiple]):not([size]):disabled { cursor: default; }

/* Заголовок свёрнутого блока — от левого края, а не по центру кнопки: длинный
   («Сообщения-основания (5, переведено 4)» рядом с «Перевести») ломался на две
   строки и вставал посередине. Название целиком, подпись в скобках — сколько
   влезет. */
.fold-toggle { text-align: left; }
#order-modal .fold-head > .fold-toggle { flex: 0 1 auto; white-space: nowrap; }
#order-modal .fold-head > .fold-toggle > .muted {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
#order-modal .fold-head > .btn { flex: 0 0 auto; }

/* Круглая кнопка чата висит в правом нижнем углу поверх боковых панелей: у
   нижнего блока панели («Заметки» в заказе) она закрывала край. Запас снизу —
   чтобы последний блок докручивался выше кнопки. */
#order-modal .modal-body,
#entity-modal.as-drawer .modal-body { padding-bottom: 76px; }

/* Карточка образца: кнопка следующего шага («Отправлен на примерку») стояла
   вплотную под выпадашкой статуса, подписи под ней — вплотную к кнопке. */
/* У панели задачи внизу ряд «Выполнить · Копия · Удалить» — кнопка чата
   садилась прямо на него. Пока такая панель открыта, кнопка чата — над рядом. */
body:has(#entity-modal.as-drawer:not(.hidden) .tp-foot) .chat-toggle { bottom: 80px; }

/* Шапка разговора с Гермесом: «Очистить» и крестик стояли на 12 px ниже
   названия (общий отступ `.row-actions` над рядом кнопок). */
.chat-head > .row-actions { margin-top: 0; }

/* «Создать заказ»: кнопки «Свернуть каталог» и «Завести новый товар» стояли
   на 6 px ниже поиска рядом с ними. Та же мера, что у `.row-actions` с полем. */
.oc-search > .btn { min-height: 36px; }

/* «Продукты»: переключатель «По юнитам / По фабрикам» в ряду кнопок раздела
   сидел на 2.5 px выше «Скриптов» (свои поля сверху и снизу) и был на пиксель
   ниже кнопок. В ряду — без полей и одной с кнопками высоты. */
.section-actions > .product-tabs { margin: 0; align-items: center; }
.section-actions > .product-tabs > .product-tab { min-height: 30px; align-items: center; }
/* Одна кнопка «Скрипты» «Продуктов» — в том же ряду, у правого края (11.11.2026). */
.section-actions:has(> .products-scripts) { flex: 1 1 auto; }
.section-actions > .products-scripts { margin-left: auto; }

/* Узкое окно (телефон ассистентки, половина экрана).
   — Доска: «Выбрать производство», «Скрипты» и шестерёнка забирали всю ширину,
     и полоса производств сжималась в ноль — вкладок не было видно вовсе.
     Полоса уходит второй строкой во всю ширину.
   — «Задачи»: ряд брендов переносился в две строки и становился кривым овалом.
     Ряд остаётся одной строкой и листается пальцем. */
@media (max-width: 760px) {
  #tabs { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 2px 8px; }
  #tabs > .tabs-scroll { order: 5; grid-column: 1 / -1; }
  #tabs > .tab-pick { min-width: 0; }
  #tabs > .tab-pick .tab-pick-btn { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  .task-person-switch { flex-wrap: nowrap; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .task-person-switch::-webkit-scrollbar { display: none; }
  .task-brand-btn { padding: 7px 14px; font-size: 14px; }
}

.sample-state > .btn { margin-top: 8px; }
.sample-state > .hint { margin-top: 6px; }

/* «Фото» — съёмка товара в стиле референса (29.10.2026, `ui/photo-studio.js`).
   Фото — вертикальные 3:4, как и рисует OpenAI по её правилу. */
.photos-shoots { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px; }
.photos-shoot {
  display: flex; flex-direction: column; gap: 4px; padding: 8px; text-align: left; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); color: var(--ink);
}
.photos-shoot:hover { border-color: var(--accent); }
.photos-shoot-cover, .photos-card-cover {
  aspect-ratio: 3 / 4; border-radius: var(--radius-sm); overflow: hidden; background: var(--panel);
}
.photos-shoot-cover img, .photos-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photos-shoot-cover { position: relative; }
.photos-shoot-delete {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card); color: var(--ink-rose); font-size: 16px; line-height: 1;
  cursor: pointer; opacity: 0; transition: opacity .15s;
}
.photos-shoot:hover .photos-shoot-delete, .photos-shoot:focus-within .photos-shoot-delete { opacity: 1; }
.photos-shoot-delete:hover { background: var(--danger); border-color: var(--danger); color: var(--on-accent); }
@media (hover: none) { .photos-shoot-delete { opacity: 1; } }
.photos-shoot-title { font-weight: 600; }
.photos-shoot-sub, .photos-card-stage { color: var(--muted); font-size: 12px; }
.photos-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--gap); margin-top: 10px; }
.photos-card {
  display: flex; flex-direction: column; gap: 3px; padding: 6px; text-align: left; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--ink);
}
.photos-card:hover { border-color: var(--accent); }
.photos-card-name { font-weight: 600; font-size: 13px; overflow-wrap: anywhere; }
.photos-card-pick { display: flex; flex-direction: column; gap: var(--gap); align-items: flex-start; }
.photos-pick-title { margin: 0; }
.photos-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.photos-pick {
  position: relative;
  width: 96px; aspect-ratio: 3 / 4; padding: 0; overflow: hidden; cursor: pointer;
  border: 2px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
}
.photos-pick.is-on { border: 3px solid var(--accent); }
/* Галочка в углу: пустой кружок — не выбрано, закрашенный с ✓ — выбрано (30.10.2026). */
.photos-pick-check {
  position: absolute; top: 5px; right: 5px; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700;
  border: 2px solid var(--on-accent); background: color-mix(in srgb, var(--text) 25%, transparent); color: transparent;
}
.photos-pick.is-on .photos-pick-check { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.photos-pick-count { font-size: 13px; font-weight: 600; }
.photos-cards-head { font-weight: 600; margin-top: 10px; }
.photos-cards-rest { margin-top: 14px; }
.photos-cards-rest > summary { cursor: pointer; color: var(--muted); font-weight: 600; }
.photos-pick img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photos-top { display: flex; justify-content: space-between; align-items: center; gap: var(--gap); flex-wrap: wrap; }
.photos-top-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.photos-title { margin: 10px 0 14px; }
.photos-block {
  display: flex; flex-direction: column; gap: 12px; padding: 16px; margin-bottom: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
}
.photos-block-title { margin: 0; display: flex; align-items: center; gap: 6px; }
.photos-field, .photos-words { display: flex; flex-direction: column; gap: 6px; }
.photos-words-label { font-weight: 600; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.photos-words textarea, .photos-poses, .photos-fix textarea { width: 100%; box-sizing: border-box; }
.photos-inputs {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-height: 40px;
  padding: 6px; border: 1px dashed var(--line); border-radius: var(--radius-sm);
}
.photos-inputs.is-drop { border-color: var(--accent); background: var(--panel); }
.photos-field.is-missing .photos-inputs { border: 2px solid var(--ink-rose); background: color-mix(in srgb, var(--danger) 18%, transparent); }
.photos-field.is-missing > .photos-words-label, .photos-field.is-missing .photos-give-head { color: var(--ink-rose); }
.photos-words.is-missing textarea { border-color: var(--ink-rose); }
.photos-words.is-missing .photos-words-label { color: var(--ink-rose); }
.photos-missing { color: var(--ink-rose); font-size: 13px; font-weight: 600; }
.photos-input { position: relative; width: 104px; display: flex; flex-direction: column; gap: 4px; }
.photos-rules-list { margin: 6px 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }
.photos-rule { font-size: 13px; }
.photos-rule-x {
  margin-left: 8px; width: 20px; height: 20px; padding: 0; line-height: 18px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card); color: var(--ink); cursor: pointer;
}
.photos-rules-add { display: flex; gap: 8px; align-items: center; }
.photos-rules-add input { flex: 1; min-width: 0; }
.photos-face-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.photos-input-img {
  width: 100%; aspect-ratio: 3 / 4; padding: 0; overflow: hidden; cursor: zoom-in;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
}
.photos-input-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photos-input-x {
  position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; padding: 0; line-height: 20px;
  border: 1px solid var(--line); border-radius: 50%; background: var(--card); color: var(--ink); cursor: pointer;
}
.photos-draw { align-self: flex-start; }
/* «Что даём» (10.11.2026): референс и фото товара — две карточки рядом, фото слева, слово к ним — справа
   маленьким полем за чертой. На узком окне карточки встают одна под другой. */
.photos-give-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(440px, 100%), 1fr)); gap: 12px; }
.photos-give {
  display: grid; grid-template-columns: minmax(0, 1fr) 215px; gap: 8px 14px; align-items: center;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
}
.photos-give-main { display: flex; flex-direction: column; gap: 8px; min-width: 0; align-self: start; }
.photos-give .photos-inputs { border-color: transparent; padding: 0; min-height: 0; }
.photos-give .photos-inputs.is-drop { border-color: var(--accent); }
.photos-give-side { padding-left: 14px; border-left: 1px solid var(--line); gap: 4px; }
.photos-give-side .photos-words-label { font-weight: 500; color: var(--muted); }
.photos-give-side textarea { min-height: 34px; resize: vertical; background: var(--card); }
.photos-give > .photos-missing { grid-column: 1 / -1; }
@media (max-width: 560px) {
  .photos-give { grid-template-columns: minmax(0, 1fr); }
  .photos-give-side { padding-left: 0; border-left: 0; }
}
/* Новое правило для всех фото — одной строкой; список и скрипт — окно под шестерёнкой (10.11.2026). */
.photos-rule-new { display: flex; align-items: center; gap: 6px 12px; flex-wrap: wrap; }
.photos-rule-new .photos-rules-add { flex: 1; min-width: 240px; }
.photos-settings { display: flex; flex-direction: column; gap: 18px; }
.photos-settings-part { display: flex; flex-direction: column; gap: 8px; }
.photos-settings-title { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 14px; }
.photos-settings .photos-rules-list { margin: 0; }
.photos-script-tabs { gap: 6px; margin: 0; }
.photos-script-tabs .kiz-tab {
  flex: 0 0 auto; min-height: 0; padding: 6px 14px; border-width: 1px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600;
}
.photos-script-tabs .kiz-tab:hover { transform: none; }
.photos-script-tabs .kiz-tab.on { box-shadow: none; }
.photos-script {
  display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; max-height: 46vh; overflow: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel);
  font-size: 13px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; user-select: text;
}
.photos-script-line.is-rules {
  padding: 6px 8px; border-radius: var(--radius-sm); font-weight: 600;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
/* «Сохранить» и «Скачать» крупно под отобранными кадрами (04.11.2026). */
.photos-chosen-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 14px; }
.photos-chosen-actions .btn.photos-big { flex: 1 1 220px; }
/* «Куда сохранять фото» (12.11.2026) — маленькой шестерёнкой рядом с крупными кнопками. */
.photos-chosen-actions .btn-gear { flex: 0 0 auto; }
.photos-chosen-actions[hidden] { display: none; }
.btn.photos-big {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 64px; padding: 12px 18px; border-radius: var(--radius);
}
.photos-big-word { font-size: 18px; font-weight: 700; }
.photos-big-sub { font-size: 12px; font-weight: 400; opacity: .8; }
/* Идёт рисование: плитка с процентами на месте будущего фото (30.10.2026). */
.photos-pending {
  display: flex; flex-direction: column; justify-content: center; gap: 8px; min-height: 160px; padding: 14px;
  border: 2px dashed var(--accent); border-radius: var(--radius-sm); background: var(--panel);
}
.photos-pending-title { font-weight: 600; }
/* Не нарисовано — плитка с причиной на месте фото (04.11.2026). */
.photos-result.photos-failed {
  position: relative; display: flex; flex-direction: column; justify-content: center; gap: 8px; min-height: 160px;
  padding: 14px; border: 2px dashed var(--ink-rose); border-radius: var(--radius-sm); background: var(--panel);
}
.photos-failed-what { font-weight: 600; color: var(--ink-rose); }
.photos-failed-reason { font-size: 13px; color: var(--ink); }
.photos-pending-text { font-size: 13px; color: var(--muted); }
.photos-pending-bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.photos-pending-fill { height: 100%; width: calc(var(--busy, 0) * 100%); background: var(--accent); transition: width .9s linear; }
.photos-limit { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.photos-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.photos-result {
  display: flex; flex-direction: column; gap: 6px; padding: 6px;
  border: 2px solid var(--line); border-radius: var(--radius); background: var(--card);
}
.photos-result.is-chosen { border-color: var(--accent); }
/* Кружок отметки в правом верхнем углу фото (12.11.2026): отмеченные — разом панелью внизу. */
.photos-result { position: relative; }
.photos-mark {
  position: absolute; top: 12px; right: 12px; z-index: 1; width: 24px; height: 24px; padding: 0;
  border: 2px solid var(--card); border-radius: 50%; background: var(--crop-shade); cursor: pointer;
  box-shadow: 0 1px 4px var(--shadow-soft); display: grid; place-items: center; color: var(--on-accent); font-size: 14px; line-height: 1;
}
.photos-mark:hover { background: var(--accent-dim); }
.photos-mark[aria-pressed="true"] { background: var(--ink-green); border-color: var(--card); color: var(--card); }
.photos-mark[aria-pressed="true"]::after { content: '✓'; font-weight: 700; }
.photos-result.is-picked { outline: 3px solid var(--ink-green); outline-offset: 2px; }
.photos-markbar {
  position: sticky; bottom: 12px; z-index: 3; margin-top: 14px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); box-shadow: 0 4px 16px var(--shadow-soft);
}
.photos-markbar[hidden], .photos-markbar-fix[hidden] { display: none; }
.photos-markbar-row > [hidden] { display: none; }
.photos-markbar-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.photos-markbar-count { font-weight: 600; margin-right: 4px; }
.photos-markbar-fix { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.photos-markbar-fix textarea { align-self: stretch; }
.photos-result-img {
  aspect-ratio: 3 / 4; padding: 0; overflow: hidden; cursor: zoom-in;
  border: 0; border-radius: var(--radius-sm); background: var(--panel);
}
.photos-result-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Обрезанное свободно — целиком, как сохранится, а не срезанным под плитку 3:4. */
.photos-result-img.is-cropped img { object-fit: contain; }
.photos-result-note { color: var(--muted); font-size: 12px; }
/* Кадр после «Сделай без наготы» (аудит 09.11.2026, F2-02) — заметно, но не тревогой. */
.photos-result-note.photos-safe-retry { background: var(--warn); color: var(--warn-ink); border-radius: 6px; padding: 2px 6px; }
.photos-result-history-title { font-size: 12px; font-weight: 600; }
.photos-result-history { margin: 0; padding-left: 18px; font-size: 13px; display: flex; flex-direction: column; gap: 2px; }
.photos-pending-note { font-size: 13px; overflow-wrap: anywhere; }
.photos-result-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.photos-fix { display: flex; flex-direction: column; gap: 6px; }
/* Как «Удалить» у задач: розовым текстом, заливка — под курсором. */
.btn.photos-delete { color: var(--ink-rose); }
/* Окно обрезки фото (04.11.2026): нарисованный кадр, поверх — рамка с уголками; вне рамки — тень. */
.photos-crop { display: flex; flex-direction: column; gap: 12px; align-items: center; }
.photos-crop-top { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; width: 100%; }
.photos-crop-size { color: var(--muted); font-size: 13px; }
.photos-crop-size.is-up { color: var(--text); }
.photos-crop-stage {
  position: relative; display: inline-block; max-width: 100%; overflow: hidden;
  border-radius: var(--radius-sm); touch-action: none; user-select: none; background: var(--panel);
}
.photos-crop-stage img {
  display: block; max-width: 100%; max-height: min(calc(88vh - 210px), 900px); width: auto; height: auto;
  pointer-events: none; -webkit-user-drag: none;
}
.photos-crop-box {
  position: absolute; cursor: move;
  /* Тень на 2000 px: шире Хром не рисует вовсе (проверено 04.11.2026), а фото в окне не выше 900. */
  box-shadow: inset 0 0 0 1px var(--crop-line), 0 0 0 2000px var(--crop-shade);
}
.photos-crop-box::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to right, transparent calc(33.33% - .5px), var(--crop-grid) 0, var(--crop-grid) calc(33.33% + .5px), transparent 0,
      transparent calc(66.67% - .5px), var(--crop-grid) 0, var(--crop-grid) calc(66.67% + .5px), transparent 0),
    linear-gradient(to bottom, transparent calc(33.33% - .5px), var(--crop-grid) 0, var(--crop-grid) calc(33.33% + .5px), transparent 0,
      transparent calc(66.67% - .5px), var(--crop-grid) 0, var(--crop-grid) calc(66.67% + .5px), transparent 0);
}
/* Ручки — внутри рамки: у края фото они не срезаются. Уголки — скобками, стороны — чёрточкой. */
.photos-crop-h { position: absolute; width: 26px; height: 26px; }
.photos-crop-h::after { content: ''; position: absolute; width: 18px; height: 18px; border: 0 solid var(--crop-line); }
.photos-crop-h[data-dir="nw"] { left: 0; top: 0; cursor: nwse-resize; }
.photos-crop-h[data-dir="nw"]::after { left: 0; top: 0; border-width: 4px 0 0 4px; }
.photos-crop-h[data-dir="ne"] { right: 0; top: 0; cursor: nesw-resize; }
.photos-crop-h[data-dir="ne"]::after { right: 0; top: 0; border-width: 4px 4px 0 0; }
.photos-crop-h[data-dir="sw"] { left: 0; bottom: 0; cursor: nesw-resize; }
.photos-crop-h[data-dir="sw"]::after { left: 0; bottom: 0; border-width: 0 0 4px 4px; }
.photos-crop-h[data-dir="se"] { right: 0; bottom: 0; cursor: nwse-resize; }
.photos-crop-h[data-dir="se"]::after { right: 0; bottom: 0; border-width: 0 4px 4px 0; }
.photos-crop-h[data-dir="n"], .photos-crop-h[data-dir="s"] { left: 50%; width: 40px; margin-left: -20px; cursor: ns-resize; }
.photos-crop-h[data-dir="n"] { top: 0; }
.photos-crop-h[data-dir="s"] { bottom: 0; }
.photos-crop-h[data-dir="w"], .photos-crop-h[data-dir="e"] { top: 50%; height: 40px; margin-top: -20px; cursor: ew-resize; }
.photos-crop-h[data-dir="w"] { left: 0; }
.photos-crop-h[data-dir="e"] { right: 0; }
.photos-crop-h[data-dir="n"]::after { left: 11px; top: 0; height: 0; border-top-width: 4px; }
.photos-crop-h[data-dir="s"]::after { left: 11px; bottom: 0; height: 0; border-bottom-width: 4px; }
.photos-crop-h[data-dir="w"]::after { top: 11px; left: 0; width: 0; border-left-width: 4px; }
.photos-crop-h[data-dir="e"]::after { top: 11px; right: 0; width: 0; border-right-width: 4px; }
/* 3:4 тянут за уголки: у сторон пропорция бы ломалась. */
.photos-crop.is-ratio .photos-crop-h[data-dir="n"], .photos-crop.is-ratio .photos-crop-h[data-dir="s"],
.photos-crop.is-ratio .photos-crop-h[data-dir="w"], .photos-crop.is-ratio .photos-crop-h[data-dir="e"] { display: none; }
.photos-crop-actions { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; justify-content: flex-end; }
.btn.photos-delete:hover { background: var(--danger); border-color: var(--danger); }

/* «Проверка данных» в «Логе» (31.10.2026, `traceDataChecks`) */
.data-checks { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.data-check-refused { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border-radius: var(--radius-sm); background: var(--panel-2); border: 1px solid var(--line); }
.data-check { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); padding: 8px 12px; }
.data-check-head { display: flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600; }
.data-check-count { margin-left: auto; min-width: 24px; text-align: center; padding: 0 8px; border-radius: 999px; background: var(--tile-rose-bg); color: var(--tile-rose-text); font-size: 12px; line-height: 20px; }
.data-check-tag { font-size: 12px; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px; line-height: 18px; }
.data-check-soft .data-check-count { background: var(--panel-2); color: var(--muted); }
.data-check-rows { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.data-check-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; font-size: 13px; }

/* «Сравнить фабрики» товара (31.10.2026, `cardCompareOpen`) */
/* Кнопка не касается рамки первого образца (12.11.2026, её слово: «сделай чуть выше»). */
.card-samples-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.card-compare-wrap { overflow-x: auto; }
.card-compare { width: 100%; border-collapse: collapse; font-size: 13px; }
.card-compare th, .card-compare td { padding: 6px 8px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
.card-compare th { font-weight: 500; color: var(--muted); white-space: nowrap; }
.card-compare-name { font-weight: 600; min-width: 110px; }
.card-compare-pro { color: var(--tile-green-text); }
.card-compare-con { color: var(--tile-rose-text); }
.card-compare-approved td:first-child { box-shadow: inset 3px 0 0 var(--tile-green-text); }

/* АУДИТ 31.10.2026 — БЫСТРЫЕ ПУТИ: ⌘K «Перейти» (`ui/jump.js`), «Заказы» в досье товара,
   фабрика ссылкой и «→ следующий этап» в карточке заказа, плашки рисков над доской. */
.jump-modal { align-items: start; }
.jump-modal .jump-panel {
  width: min(560px, calc(100vw - 32px - var(--chat-room)));
  margin-top: 12vh; max-height: 70vh;
}
.jump-input {
  width: 100%; border: none; border-bottom: 1px solid var(--line); border-radius: 0;
  padding: 14px 16px; font: inherit; font-size: 16px; background: transparent; color: var(--text);
}
.jump-input:focus { outline: none; box-shadow: none; }
.jump-list { overflow-y: auto; padding: 4px 0; }
.jump-list:empty { display: none; }
.jump-row {
  display: flex; align-items: baseline; gap: var(--gap); padding: 8px 16px; cursor: pointer; min-width: 0;
}
.jump-row.on { background: var(--hover); }
.jump-kind {
  flex: 0 0 64px; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em;
}
.jump-text { font-weight: 650; white-space: nowrap; }
.jump-note {
  min-width: 0; flex: 1 1 auto; color: var(--muted); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.jump-empty { padding: 12px 16px; color: var(--muted); font-size: 13px; }

.card-orders { margin-top: 14px; }
.card-orders-list { display: flex; flex-direction: column; gap: 6px; }
.card-order-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); min-width: 0;
}
.card-order-code { font-weight: 650; }
.card-order-qty { font-variant-numeric: tabular-nums; }
.card-order-when { font-size: 12px; margin-left: auto; }


.status-row > .btn-next {
  border-color: var(--accent); background: var(--accent-dim); color: var(--accent-ink); font-weight: 600;
}
/* На заливке акцента — тёмный текст и в тёмной теме: светло-зелёный `--accent-ink` на ней не читался. */
.status-row > .btn-next:hover { background: var(--accent); color: var(--on-accent-strong); }
.card-decide-btn.next:hover { border-color: var(--accent); background: var(--accent-dim); color: var(--accent-ink); }

.orders-mode { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.board-risks { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
/* «Фильтр» доски заказов и надпись включённого отбора (11.11.2026): отбор — не счётчик, его видно сразу. */
.board-filter-btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.board-filter-btn::after { content: '▾'; color: var(--muted); font-size: 11px; }
.board-filter-btn:hover { border-color: var(--accent); }
.board-filter-btn:focus-visible, .board-filter-off:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.board-filter-on {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 12px;
  border-radius: 999px; background: var(--accent); color: var(--on-accent-strong);
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.board-filter-off {
  width: 22px; height: 22px; border: 0; border-radius: 50%; background: transparent;
  color: inherit; font: inherit; font-size: 12px; cursor: pointer; line-height: 1;
}
.board-filter-off:hover { background: var(--shadow-soft); }
.board-filter-menu .new-order-item.on { background: var(--accent-dim); color: var(--accent-ink); }

/* Какая фабрика заполнила анкету (02.11.2026) */
.anketa-pick { display: flex; flex-direction: column; gap: var(--gap); }
.anketa-pick.busy { opacity: .55; pointer-events: none; }
.anketa-pick-search { width: 100%; }
.anketa-pick-list { display: grid; gap: 6px; }
.anketa-pick-all { max-height: 320px; overflow-y: auto; }
.anketa-pick-row {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; width: 100%; text-align: left;
  padding: 9px 12px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel);
  color: var(--text); cursor: pointer;
}
.anketa-pick-row:hover { border-color: var(--accent); background: var(--accent-dim); }
.anketa-pick-name { font-size: 14px; font-weight: 600; }
.anketa-pick-hint { font-size: 13px; color: var(--muted); overflow-wrap: anywhere; min-width: 0; }

/* «Размерная сетка» в «Фото» (02.11.2026, `ui/size-chart.js`). */
.photos-modes { margin-top: 0; }
.sizechart-title-row { display: flex; gap: 8px; flex-wrap: wrap; }
.sizechart-title-row select, .sizechart-title-row input { min-width: 0; max-width: 320px; flex: 1 1 200px; }
.sizechart-table-wrap { display: flex; flex-direction: column; gap: 8px; overflow-x: auto; }
.sizechart-table { border-collapse: collapse; font-size: 13px; }
.sizechart-table th, .sizechart-table td { padding: 4px 6px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
.sizechart-table th { color: var(--muted); font-weight: 600; white-space: nowrap; }
.sizechart-table input { width: 100%; box-sizing: border-box; }
.sizechart-name { min-width: 200px; }
.sizechart-value { width: 72px; }
.sizechart-value input, .sizechart-size-input { width: 64px; text-align: center; }
.sizechart-size { white-space: nowrap; }
.sizechart-how { color: var(--muted); font-size: 12px; margin-top: 2px; }
.sizechart-letter {
  display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border-radius: 50%; background: var(--text); color: var(--bg); font-weight: 700; font-size: 12px;
}
.sizechart-table-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.sizechart-badge { font-size: 13px; font-weight: 600; color: var(--accent); }
.sizechart-value.is-guess input { background: var(--accent-dim); }

/* «Юнит экономика» → «В Excel» (04.11.2026): товары галочками. */
.unit-xlsx-bulk { display: flex; align-items: center; gap: 6px; margin: 10px 0 6px; }
.unit-xlsx-count { margin-left: auto; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.unit-xlsx-list { display: flex; flex-direction: column; max-height: 55vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.unit-xlsx-row { display: flex; align-items: center; gap: var(--gap); padding: 8px 10px; border-bottom: 1px solid var(--line); cursor: pointer; }
.unit-xlsx-row:last-child { border-bottom: 0; }
.unit-xlsx-row:hover { background: var(--hover); }
.unit-xlsx-row input { flex: 0 0 auto; }
.unit-xlsx-thumb { width: 36px; height: 45px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); flex: 0 0 auto; font-size: 9px; }
.unit-xlsx-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.unit-xlsx-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unit-xlsx-date { color: var(--muted); font-size: 12px; }
.unit-xlsx-num { white-space: nowrap; font-variant-numeric: tabular-nums; font-size: 13px; padding: 2px 6px; border-radius: 6px; }
.unit-xlsx-num.unit-ok { background: var(--tile-green-bg); color: var(--tile-green-text); }
.unit-xlsx-num.unit-bad { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
/* «Тренды WB» → «Отчёт по категории в PDF» (04.11.2026). */
.trends-report-line { display: flex; justify-content: flex-end; margin: 8px 0 4px; }
/* «Тренды WB» → «Спрос по запросу» (04.11.2026): строка над категориями, ответ на месте списка. */
.trends-word { display: flex; gap: 8px; align-items: center; margin: 0 0 12px; }
.trends-word-input { flex: 1; min-width: 0; }
.trends-word-place { display: flex; flex-direction: column; gap: 12px; }
.trends-word-months { flex-wrap: wrap; align-self: flex-start; max-width: 100%; }
.trends-word-lines { display: flex; flex-direction: column; gap: 4px; max-width: 860px; }
.trends-word-chart { max-width: 860px; }
.trends-word-row { grid-template-columns: minmax(0, 1fr) minmax(60px, 160px) 64px minmax(0, 120px) auto; }
.trends-word-actions { justify-content: flex-start; flex-wrap: wrap; gap: 8px; }
@media (max-width: 640px) {
  .trends-word-row { grid-template-columns: minmax(0, 1fr) 60px auto; }
  .trends-word-row > .trends-query-bar, .trends-word-row > .trends-crowd { display: none; }
  .trends-word-place .trends-cat-head { grid-template-columns: auto minmax(0, 1fr); }
  .trends-word-place .trends-cat-head > .analytics-f-nums { grid-column: 1 / -1; align-items: flex-start; }
  .trends-word-place .trends-cat-title { font-size: 20px; }
}

/* ── АУДИТ ИНТЕРФЕЙСА 03.11.2026, P1 (её ответы 04.11.2026) ────────────────── */
/* Разговор с Гермесом не закрывает боковые панели и шапку: карточка заказа, панели
   товара, фабрики и задачи встают левее разговора, кнопки шапки — тоже. */
#order-modal .modal-panel,
#entity-modal.as-drawer .modal-panel { right: var(--chat-room); }
body.order-open .board { padding-right: calc(var(--order-drawer) + var(--chat-room) + 16px); }
body.chat-open .topbar { padding-right: calc(var(--chat-room) + 16px); }
/* Зелёный текст на светлом фоне и подпись на зелёной кнопке — тёмным зелёным. */
.sizechart-badge,
.wbfin-filter-hidden-link { color: var(--accent-ink); }
.unit-scheme-btn.on,
.photos-pick.is-on .photos-pick-check { color: var(--on-accent-strong); }
/* Будущие этапы в карточке заказа — читаемым серым и 11 px: это кнопки перевода. */
.path-step { color: var(--muted); }
.path-name { font-size: 11px; opacity: 1; white-space: normal; overflow-wrap: anywhere; line-height: 1.15; }
.stage-name { font-size: 11px; }
/* Галочка и стрелка плана недели: вид прежний, мишень нажатия шире на 6 px с каждой
   стороны — как у «ⓘ». */
.tw-check, .tw-group-toggle { position: relative; }
.tw-check::after, .tw-group-toggle::after { content: ''; position: absolute; inset: -6px; }

/* ── АУДИТ 03.11.2026, P2 (её ответы 04.11.2026) ────────────────────────────── */
/* Журнал выдач КИЗов (11.11.2026, «красивее и аккуратнее»; «кто, кому, когда, почему, из
   какого файла»): рамка, строки по дням, причина плашкой, второстепенное — мелкой строкой. */
.kiz-ledger-wrap {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  margin: 4px 0 18px;
}
.kiz-table.kiz-ledger { margin: 0; min-width: 900px; }
.kiz-ledger th { padding: 10px 12px; background: var(--panel-2); }
.kiz-ledger thead th:first-child { border-top-left-radius: var(--radius); }
.kiz-ledger thead th:last-child { border-top-right-radius: var(--radius); }
.kiz-ledger td { padding: 10px 12px; vertical-align: top; }
.kiz-ledger tbody:last-child tr:last-child td { border-bottom: 0; }
.kiz-ledger tbody tr:not(.kiz-ledger-dayhead):hover td { background: var(--panel-2); }
.kiz-ledger-dayhead td {
  padding: 14px 12px 6px; border-bottom: 1px solid var(--line); background: transparent;
}
.kiz-ledger-daytitle { font-weight: 600; font-size: 13px; color: var(--text); }
.kiz-ledger-daysum {
  margin-left: 10px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.kiz-ledger .kiz-when { white-space: nowrap; color: var(--muted); font-variant-numeric: tabular-nums; width: 1%; }
.kiz-ledger .kiz-who { white-space: nowrap; font-weight: 500; }
.kiz-ledger .kiz-to { white-space: nowrap; }
.kiz-ledger .kiz-reason { white-space: nowrap; }
.kiz-reason-chip {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 12px; font-weight: 500; line-height: 18px;
}
.kiz-reason-violet { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.kiz-reason-yellow { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.kiz-reason-plain { background: var(--panel-2); color: var(--text-2); }
.kiz-reason-green { background: var(--tile-green-bg); color: var(--tile-green-text); }
/* Фильтр журнала (11.11.2026): «Все · Нарезанные КИЗы · Заказанные КИЗы». */
.kiz-ledger-filter { display: flex; gap: 6px; flex-wrap: wrap; margin: 14px 0 12px; }
.kiz-ledger-chip {
  padding: 6px 14px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text-2); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
}
.kiz-ledger-chip:hover { background: var(--panel-2); }
.kiz-ledger-chip.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent-strong); }
.kiz-ledger .kiz-article { white-space: nowrap; font-weight: 600; width: 1%; }
.kiz-ledger .kiz-size-cell { width: 1%; white-space: nowrap; }
.kiz-ledger .kiz-folder { white-space: nowrap; }
.kiz-ledger .kiz-comment { min-width: 220px; }
.kiz-ledger .kiz-comment .kiz-note { margin: 0; }
.kiz-ledger .kiz-reason .kiz-sub { white-space: normal; max-width: 200px; }
.kiz-ledger .kiz-what { min-width: 180px; }
.kiz-what-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.kiz-what-name { font-weight: 500; }
.kiz-size {
  display: inline-block; min-width: 22px; padding: 0 6px; border: 1px solid var(--line);
  border-radius: 6px; font-size: 11px; font-weight: 600; line-height: 18px; text-align: center;
  color: var(--text-2);
}
.kiz-sub { margin-top: 2px; font-size: 12px; color: var(--muted); }
.kiz-note { margin-top: 4px; font-size: 12px; color: var(--text-2); max-width: 340px; }
.kiz-ledger .kiz-range { white-space: nowrap; width: 1%; padding-left: 24px; }
.kiz-ledger .kiz-who, .kiz-ledger .kiz-to, .kiz-ledger .kiz-reason { width: 1%; }
.kiz-range-codes { font-weight: 600; font-variant-numeric: tabular-nums; }
.kiz-ledger .kiz-range .kiz-mark { margin: 4px 0 0; }
.kiz-ledger .kiz-src { width: 28%; }
.kiz-src-file { font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; }
.kiz-ledger .kiz-src .kiz-sub { overflow-wrap: anywhere; }
/* Строка не из выдачи (выданы раньше, из таблицы) — тише, но читаемо. */
.kiz-ledger .kiz-row-past td { color: var(--muted); font-style: normal; }
.kiz-ledger .kiz-row-past .kiz-what-name, .kiz-ledger .kiz-row-past .kiz-range-codes { font-weight: 400; }

/* Полоса этапов карточки товара (Р-В-06) — у самого правила `.stage-path` выше:
   её `@container` должен стоять раньше обнуления рамки досье в панели. */

/* Окна (Р-С-11): три ширины — узкое, обычное, широкое (`.modal-wide`); универсальное
   окно без своей ширины остаётся 860 px (в нём настройки и таблицы). Все уступают
   место разговору с Гермесом. */
:root { --modal-w-narrow: 480px; --modal-w-normal: 720px; }
.modal-narrow,
.price-diff-panel, .kiz-ask-panel, .kiz-gtin-panel, .undo-conflict-panel {
  width: min(var(--modal-w-narrow), calc(94vw - var(--chat-room)));
}
.album-pick-panel, .parse-news-panel, .nw-panel,
#entity-modal[data-brand-form] .modal-panel {
  width: min(var(--modal-w-normal), calc(94vw - var(--chat-room)));
}
/* Кнопки внизу окна (Р-С-12): главная — справа, рядом слева — остальные,
   удаляющая — у левого края. Только ряд-подвал окна, не боковые панели. */
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) {
  justify-content: flex-end;
}
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) > .btn-ghost { order: 1; }
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) > .btn:not(.btn-ghost):not(.btn-primary):not(.btn-danger):not(.btn-danger-solid) { order: 2; }
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) > .btn-primary { order: 3; }
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) > .btn.btn-danger,
.modal:not(#order-modal):not(.as-drawer) .modal-body > .row-actions:last-child:has(> .btn-primary, > .btn-danger, > [data-close]):not(:has(> input, > select, > textarea, > .combo)) > .btn.btn-danger-solid {
  order: 0; margin-right: auto;
}
/* Крестик «Закрыть» (Р-С-08): у окна — малая кнопка 30 px с «✕», у плашки — 22 px. */
.today-x { font-size: 13px; line-height: inherit; }
.icon-btn.guide-close, .icon-btn.guide-tip-close {
  width: 30px; height: 30px; border-radius: 999px; font-size: 13px;
}
.lightbox-close { width: 30px; height: 30px; font-size: 13px; }
.done-bar-x, .offline-banner .offline-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; border-radius: 6px; font-size: 13px;
}
.done-bar-x:hover { background: var(--panel-2); color: var(--text); }

/* Кнопки (Р-С-06, Р-С-07): крупные кнопки скруглены одинаково; «маленькая» кнопка
   действия — того же роста, что `.btn-sm` (30 px). Мелкой остаётся только правка
   внутри строки, появляющаяся при наведении. */
.btn-lg, .btn.price-diff-choice { border-radius: var(--radius); }
.btn-xs { padding: 4px 9px; font-size: 13px; line-height: inherit; min-height: 30px; }
.btn-xs.fact-edit, .quote-edit .btn-xs, .item-edit .btn-xs, .btn-xs.checklist-edit {
  padding: 2px 6px; font-size: 11px; line-height: 1.3; min-height: 0;
}
/* Мелкие значки-кнопки (Р-С-09): вид прежний, мишень нажатия шире. */
.nsm-qty-btn, .photos-rule-x, .chat-chip-x, .spec-chip-x, .tp-step-del,
.wbfin-filter-chevron, .done-bar-x, .offline-banner .offline-close, .toast-close,
.nsm-new-drop, .dev-stage-remove, .star { position: relative; }
.nsm-qty-btn::after, .photos-rule-x::after, .photos-input-x::after,
.wbfin-filter-chevron::after, .done-bar-x::after, .offline-banner .offline-close::after,
.toast-close::after, .tp-step-del::after, .dev-stage-remove::after {
  content: ''; position: absolute; inset: -6px;
}
.chat-chip-x::after, .spec-chip-x::after, .nsm-new-drop::after { content: ''; position: absolute; inset: -4px; }
.star::after { content: ''; position: absolute; inset: -6px 0; }

/* Переключатели «одно из нескольких» (Р-С-10) — видом `.mode-switch`: пилюля на
   бежевой подложке, выбранное — бумагой с тенью. */
.unit-scheme {
  gap: 2px; padding: 2px; border: 0; border-radius: 999px;
  background: var(--c-f4f1e8-s); overflow: visible;
}
.unit-scheme-btn { padding: 5px 16px; border-radius: 999px; }
.unit-scheme-btn.on {
  background: var(--paper); color: var(--text); font-weight: 650;
  box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s);
}
.an-tabs { gap: 2px; padding: 2px; border-radius: 999px; }
.an-tab { padding: 5px 14px; border-radius: 999px; font-size: 13px; }
.an-tab.on { box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s); }
.product-tab { border-radius: 999px; font-size: 13px; padding: 5px 14px; }

/* Мелкий шрифт там, где текст читают (Р-С-16): не меньше 11 px. Счётчики в кружках,
   «BETA» и буквы-метки остаются мелкими. */
.form-hint, .field-source, .conflict-label, .fact-note, .unit-photo-hint, .tl-src,
.review-row-top .muted, .quote-table th, .card-reason, .card-reason-label,
.tw-late, .tw-sub, .tw-meta .task-due, .tw-subs-toggle, .chat-msg-at,
.card-repl, .card-draft, .card-parked, .kind, .savings-src, .tc-label,
.review-why-label, .dev-block-label, .card-links, .log-actor, .log-common,
.jr-eff-sec, .card-sample-lead, .task-person-vac, .assign-pick-vac,
.yc-wd, .cal-weekday, .photo-drop, .price-ask-photo-copy { font-size: 11px; }
#order-modal .card-section h3 { font-size: 11px; }
.card-thumb.empty { font-size: 10px; }
/* Звёзды оценки и «нет образца» (Р-С-17): читаемым цветом в светлой теме. */
.star.on, .stars-view .on { color: var(--c-a8742f-t); }
.stars-view .off { color: var(--star-off); }
/* Дробная звезда (4,8 — пятая на 80 %): серая звезда, поверх — закрашенная часть. */
.stars-view .part { position: relative; display: inline-block; letter-spacing: 0; margin-right: 2px; color: var(--star-off); }
.stars-view .part::before {
  content: '★'; position: absolute; left: 0; top: 0; width: var(--fill, 0%);
  overflow: hidden; white-space: nowrap; color: var(--c-a8742f-t);
}
.stars.readonly .star:not(.on) { opacity: 1; }
.sample-card-gap { color: var(--muted); }

/* Плашка фоновой работы (Р-С-18) не ложится на кнопки открытого окна: пока окно
   по центру открыто, она уходит под его затемнение и возвращается, когда окно
   закрыли. Боковые панели (карточка заказа, панели справа) это не трогает. */
body:has(.modal:not(.hidden):not(#order-modal):not(.as-drawer)) .job { z-index: 39; }

/* Крупная сумма в плитке (Р-С-15) переносится, а не обрезается. */
.analytics-tile-value { white-space: normal; }

/* ── АУДИТ 03.11.2026, P3 ──────────────────────────────────────────────────── */
/* Шапка на ноутбуке 1280 px — одной строкой (Р-В-07): поиск уступает место
   кнопкам, промежутки и часы плотнее. На широком окне всё как было. */
@media (max-width: 1440px) {
  .topbar { gap: 8px; padding-left: 14px; padding-right: 14px; }
  .topbar .filters { flex: 1 1 64px; }
  .topbar .undo-group { gap: 6px; }
  .topbar-title { gap: 6px; }
  .topbar .actions { gap: 6px; }
  .topbar .actions > .btn { padding-left: 10px; padding-right: 10px; }
  .topbar .topbar-clock { gap: 6px; padding: 0 8px; }
}
/* 1280 px с открытым меню и «Выполнено: N» — ещё плотнее: черта перед часами
   уходит, промежутки по 6 px. */
@media (max-width: 1320px) {
  .topbar { gap: 6px; }
  .topbar .actions > .topbar-split { display: none; }
  .topbar .topbar-clock { gap: 4px; }
}
/* Кнопка разговора с Гермесом — под затемнением открытого окна (Р-В-08), как
   плашка фоновой работы. Боковые панели её не прячут. */
body:has(.modal:not(.hidden):not(#order-modal):not(.as-drawer)) .chat-toggle { z-index: 39; }
/* Окно бренда на шаге «Бренд» — по своему содержимому, без пустоты под двумя
   полями (Р-В-09). Остальные шаги — прежней высоты, список листается внутри. */
#entity-modal[data-brand-form] .modal-panel:has(.modal-body > .bf-pane:first-of-type:not(.hidden)) {
  height: auto; max-height: min(620px, 88vh);
}
/* Подпись столбца «Гермес читает» — только над строками (Р-В-10). */
.sup-group:not(:has(.sup-row)) .sup-group-col { display: none; }
/* «На связи» — той же высоты, что кнопки шапки (Р-В-12). */
.topbar .conn-chip { height: 36px; }
/* Точки шагов обучения — украшение, не кнопки (Р-В-14). */
.guide-dot { cursor: default; }
/* Стартовый экран (Р-В-15): «+ Бренд» — обычная кнопка за чертой от входов
   «Все бренды / Без бренда». */
.gate-extra { align-items: center; }
.gate-extra-split { width: 1px; height: 24px; margin: 0 6px; background: var(--line); }
/* Подсказки внутри цветных плашек и выбранных строк (Р-С-19): серый на цвете
   не дотягивал до нормы — там они темнее. */
:is(.otable tr.sel, .review-album-tile.on, .review-compare-option.on, .review-compare-option.guess,
  .assign-menu-item.on, .price-ask-sample.is-active, .card-row.on, .task-mx-row.on,
  .tw-group-row.tp-current, .tw-item.tp-current, .task-row.tp-current, .bf-tile:has(input:checked),
  .oc-size.on, .chip.danger, .kiz-request-failed) :is(.hint, .muted, .bf-hint) { color: var(--text-2); }
/* Выпадающий список — над любым окном (Р-С-20): между выбором вкладки (60) и календарём (70). */
.combo-menu { z-index: 65; }
/* Поле и кнопка в одном ряду — одной высоты (Р-С-21): ряд с выпадашкой, как ряд с полем. */
.row-actions:has(> select) > .btn,
.row-inline:has(> select) > .btn { min-height: 36px; }
/* Маленькие выпадашки строк — ровно с малую кнопку, 30 px. */
.srow select, .crow select, .sup-edit select, .dev-head select { padding-top: 4px; padding-bottom: 4px; }
/* Отступы рядов, которые стояли прямо в разметке (Р-С-27). */
#all-advanced > .row-actions { margin-top: 0; }
#all-pick > .row-actions { margin-top: 6px; }
#pane-brands > .row-actions:first-child { margin-bottom: 12px; }

/* МЕТКА «ФАЙЛ СТИЛЕЙ ДОШЁЛ ЦЕЛИКОМ» — ВСЕГДА ПОСЛЕДНЕЙ СТРОКОЙ (01.10.2026).
   Её проверяет страница (первый скрипт `index.html`): оборвись файл посреди —
   метки нет, и страница открывается заново сама, а не стоит голым текстом.
   Новые правила — ВЫШЕ этого комментария (Р-С-30). */
/* «Чей этот товар?» — новые товары кабинета WB без доли (04.11.2026, доход Inno Led в «Финансах»). */
.fin-share-brand { display: grid; gap: 8px; margin-bottom: 16px; }
.fin-share-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fin-share-head b { margin-right: auto; }
.fin-share-row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  padding: 8px; border-radius: 10px; background: var(--panel-2);
}
.fin-share-pic { width: 44px; height: 56px; border-radius: 6px; overflow: hidden; background: var(--line); }
.fin-share-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fin-share-text { display: grid; gap: 2px; min-width: 0; }
.fin-share-text b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fin-share-btns { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

/* Портфель плитками (04.11.2026, её слово: «много текста друг на друге, очень много читать»). */
.fin-minis { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin: 12px 0 4px; }
.fin-mini { padding: 10px 12px; border-radius: 10px; background: var(--panel-2); min-width: 0; }
.fin-mini-label { font-size: 12px; color: var(--muted); }
.fin-mini-value { margin-top: 2px; font-size: 17px; font-weight: 600; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.fin-mini-value.fin-muted { font-size: 14px; font-weight: 400; }
.fin-mini-sub { font-size: 12px; font-weight: 400; }
.fin-more-list { display: grid; gap: 2px; padding-top: 6px; }
.fin-ret-todate select { font: inherit; margin: 0 4px; padding: 2px 6px; border-radius: 8px; }
.fin-ret-value.fin-loading { opacity: .45; }

/* Карточка заказа (05.11.2026): «Стоит» строкой вместо полей, шестерёнка заказа,
   «История» — ход заказа по дням, как в комментарии «Моего склада». */
.order-stall {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
  margin: 0 0 14px; padding: 8px 11px; border-radius: var(--radius-sm);
  background: var(--panel-3); color: var(--text-2); font-size: 13px; line-height: 1.45;
}
.order-stall-label {
  font-size: 10px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; opacity: .8;
}
.order-gear { margin-bottom: 6px; }
.btn.btn-gear.active { background: var(--gossamer-green); color: var(--ink); }
.order-story { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.story-day { display: grid; grid-template-columns: 44px 1fr; gap: 10px; font-size: 13px; line-height: 1.45; }
.story-date { color: var(--muted); font-variant-numeric: tabular-nums; }
.story-text { display: grid; gap: 2px; }
.order-stall .order-stall-go { margin-left: auto; }



/* «Задачи» — её финальный драфт (09.11.2026, после пяти вариантов): слева узкая полоса — вид
   словами, ниже за чертой бренды квадратными плитками одна под другой, внизу «💬 Просьбы фабрик».
   Над планом — шапка и ряд кнопок на виду («•••» нет), сегодня — широкой колонкой, прошедшие
   дни — полосками, рабочая суббота — жёлтой колонкой в конце недели. Меню CRM в «Задачах»
   свёрнуто само (`applyNavMode` в app.js). */
.tasks-shell { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 16px; align-items: start; }
.tasks-main { min-width: 0; }
.tasks-side {
  position: sticky; top: 8px; display: flex; flex-direction: column; align-items: stretch;
  padding: 8px 6px; border-radius: var(--radius); background: var(--panel-2);
}
.tasks-side-group { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tasks-side-group[hidden] { display: none; }
.tasks-side-group + .tasks-side-group { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.tasks-side-list, .tasks-side-slot { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.tasks-side-item {
  display: flex; align-items: center; gap: 6px; width: 100%; min-height: 32px;
  padding: 6px 8px; border: 0; border-radius: 8px; background: transparent;
  color: var(--text-2); font: inherit; font-size: 13.5px; font-weight: 500; text-align: left;
  cursor: pointer; white-space: normal; box-shadow: none;
}
.tasks-side-item:hover { background: var(--panel-3); color: var(--text); }
.tasks-side-item.on {
  background: var(--paper); color: var(--text); font-weight: 650;
  box-shadow: 0 1px 2px var(--c-rgba-60-50-35-08-s);
}
.tasks-side-item:focus-visible { outline: 2px solid var(--ink-green); outline-offset: 1px; }
.tasks-side-label { flex: 1 1 auto; min-width: 0; }
.tasks-side-req { font-size: 12.5px; line-height: 1.3; align-items: flex-start; }
.tasks-side-count {
  flex: none; min-width: 20px; padding: 0 6px; border-radius: 999px; text-align: center;
  background: var(--panel-3); color: var(--text-2); font-size: 11px; line-height: 18px;
}
.tasks-side-req.has .tasks-side-count { background: var(--accent); color: var(--paper); font-weight: 600; }
/* Бренды — квадратными плитками одна под другой, полным названием, по левому краю. */
.tasks-side .tasks-side-brands {
  display: flex; flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: 6px;
  padding: 0 0 0 2px; border-radius: 0; background: transparent; max-width: none;
}
.tasks-side .tasks-side-brands .task-brand-btn {
  width: 66px; height: 66px; padding: 3px; margin: 0; border: 1px solid var(--line); border-radius: 12px;
  background: var(--paper); color: var(--text-2); font-size: 11px; line-height: 1.2; font-weight: 600;
  letter-spacing: -.01em; white-space: normal; word-break: keep-all; overflow-wrap: normal;
  display: flex; align-items: center; justify-content: center; text-align: center; box-shadow: none;
}
.tasks-side .tasks-side-brands .task-brand-btn:hover { border-color: var(--line-3); color: var(--text); }
.tasks-side .tasks-side-brands .task-brand-btn.on { background: var(--ink-green); border-color: var(--ink-green); color: var(--paper); }
.tasks-side .tasks-side-brands .task-person-personal::before { display: none; }

/* Шапка плана: заголовок, неделя, «Сегодня», прогресс с процентом. */
.tasks-main .tw-head { gap: 8px 10px; }
.tasks-main .tw-title { flex: 0 1 auto; margin-right: 6px; }
.tasks-main .tw-h { font-size: 24px; }
.tasks-main .tw-nav { gap: 2px; padding: 1px 2px; }
.tasks-main .tw-nav-btn { min-width: 28px; padding-left: 6px; padding-right: 6px; font-size: 17px; line-height: 1; }
.tasks-main .tw-week { min-width: 150px; font-size: 14px; }
.tasks-main .tw-today-btn.on { color: var(--muted); }
.tasks-main .tw-progress {
  flex: 0 1 300px; min-width: 200px; margin-left: auto; display: flex; align-items: center; gap: 8px;
  padding: 0; border: 0; background: transparent; font-size: 12.5px; color: var(--text-2);
}
.tasks-main .tw-progress-label { display: inline-flex; gap: 6px; white-space: nowrap; }
.tasks-main .tw-progress .tw-bar { flex: 1 1 auto; min-width: 60px; }
.tasks-main .tw-progress-count { margin: 0; white-space: nowrap; }

/* Ряд кнопок: всё на виду, справа — повторяющиеся и приоритеты. */
.tasks-main .tw-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tasks-main .tw-tools > .btn { flex: none; width: auto; }
.tasks-main .tw-tools .task-person-switch { padding: 3px; }
.tasks-main .tw-tools .task-person-btn { font-size: 13.5px; padding: 3px 12px 3px 3px; }
.tasks-main .tw-tools .task-person-btn .assign-avatar,
.tasks-main .tw-tools .task-person-icon { width: 24px; height: 24px; font-size: 11px; }
.tasks-main .tw-tools .tw-panels.two { margin-left: auto; display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; }
.tasks-main .tw-tools .tw-panels.two > .tw-panel { flex: 0 1 auto; padding: 3px 6px 3px 12px; }
.tasks-main .tw-tools .tw-panels.two > .tw-panel .tw-panel-head { margin-bottom: 0; }
.tasks-main .tw-tools .tw-panels.two > .tw-panel-empty { flex: 0 0 auto; padding: 3px 4px 3px 12px; border-style: dashed; background: transparent; }
.tasks-main .tw-panel-empty .tw-panel-head { font-size: 13px; color: var(--text-2); }
.tw-strip-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.tw-strip-row > .tw-vac-strip { flex: 1 1 320px; }

/* Дни: сегодня широкой колонкой, прошедшие — полосками, остальные — поровну, суббота в конце. */
.tw-week-days { --tw-grow: 1; display: flex; gap: 8px; align-items: stretch; min-width: 0; }
.tw-week-days .tw-day { min-height: 220px; }
/* Сегодня забирает свободное место недели (13.11.2026, её слово: «справа много пустого места —
   какой бы ни был день, красиво распределялось по всему экрану»): растёт вдвое против
   одного оставшегося дня (`--tw-grow` у остальных = их число), задачи — колонками по ширине. */
.tw-week-days > .tw-day.big { flex: 2 1 340px; min-width: 260px; padding: 12px; }
.tw-day.big > .tw-items, .tw-day.big > .tw-done > .tw-done-list { display: block; columns: 280px; column-gap: 10px; }
.tw-day.big > .tw-items { flex: 0 0 auto; }
.tw-day.big > .tw-items > *, .tw-day.big > .tw-done > .tw-done-list > * { break-inside: avoid; margin-bottom: 4px; }
.tw-day.big > .tw-done { align-self: stretch; }
.tw-day.big .tw-today-open { max-width: 460px; }
.tw-day.big > .tw-add, .tw-day.big > .tw-today-req { max-width: 560px; }
.tw-week-days > .tw-day.past { flex: 0 0 190px; }
.tw-day.big .tw-day-name strong { font-size: 19px; }
.tw-day-name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.tw-day.big .tw-day-sub { align-items: center; gap: 8px; }
.tw-day.big .tw-today-open {
  width: 100%; margin: 4px 0 2px; min-height: 40px; font-size: 15px; font-weight: 700;
  background: var(--ink-green); border-color: var(--ink-green); color: var(--paper);
}
.tw-day.big .tw-today-open:hover { background: var(--ink-green); border-color: var(--ink-green); color: var(--paper); filter: brightness(1.15); }
.tw-day-head .tw-sat-off { align-self: flex-start; margin-top: 4px; color: var(--tw-vac-ink); border: 1px solid var(--tw-vac-line); background: var(--paper); }
.tw-day-head .tw-past-fold { align-self: flex-end; margin-top: -2px; }
.tw-rest {
  flex: var(--tw-grow) 1 0; min-width: 0; display: grid; gap: 8px; align-items: stretch;
  grid-template-columns: repeat(var(--tw-cols, 5), minmax(120px, 1fr));
}
.tw-rest.with-sat { grid-template-columns: repeat(var(--tw-cols, 5), minmax(120px, 1fr)) 96px; }
.tw-rest.with-sat.empty { flex: 0 0 120px; grid-template-columns: 120px; }
.tw-week-days .tw-add > .tw-add-btn { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tw-past-strip {
  flex: 0 0 44px; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 10px 0;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel-2);
  color: var(--muted); font: inherit; font-size: 11.5px; cursor: pointer;
}
.tw-past-strip:hover { background: var(--panel-3); color: var(--text-2); }
.tw-past-strip.vac { background: var(--tw-vac-bg); border-style: dashed; border-color: var(--tw-vac-line); }
.tw-past-name {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-family: var(--font-display); font-size: 14px; font-weight: 600; color: var(--text-2);
}
.tw-past-dot { color: var(--accent); font-size: 9px; }
.tw-sat-col {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 220px;
  padding: 8px; border: 1.5px dashed var(--tw-sat-line); border-radius: var(--radius);
  background: var(--tw-sat-bg); color: var(--tw-sat-ink); font: inherit; font-size: 13px; font-weight: 600;
  text-align: center; cursor: pointer;
}
.tw-sat-col:hover { border-style: solid; }
.tw-sat-plus { font-size: 20px; line-height: 1; }
.tw-sat-note { font-size: 11px; font-weight: 400; }
/* Просьбы фабрик коротко — в колонке «Сегодня». */
.tw-today-req { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.tw-today-req-title { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.tw-today-req-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--paper);
}
.tw-today-req-text {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; padding: 0;
  border: 0; background: transparent; font: inherit; font-size: 12.5px; color: var(--text); text-align: left; cursor: pointer;
}
.tw-today-req-text strong { font-size: 12.5px; }
.tw-today-req-text span { color: var(--text-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tw-today-req > .btn { align-self: flex-start; }

@media (max-width: 900px) {
  .tasks-shell { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .tasks-side { position: static; flex-direction: row; flex-wrap: wrap; gap: 8px 16px; }
  .tasks-side-group + .tasks-side-group { margin-top: 0; padding-top: 0; border-top: 0; }
  .tasks-side .tasks-side-brands { flex-direction: row; }
  .tasks-main .tw-progress { margin-left: 0; }
  .tw-week-days { flex-wrap: wrap; }
  .tw-week-days > .tw-day.big { flex-basis: 100%; }
  .tw-rest, .tw-rest.with-sat { flex-basis: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}



/* «Поиск производства» — вкладка «Контрагентов» (11.11.2026): как лист книги «Фабрики». */
.fsearch { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.fs-form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px 22px;
  padding: var(--pad-lg); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
}
.fs-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.fs-label { font-size: 12px; color: var(--muted); }
.fs-input {
  width: 300px; max-width: 100%; padding: 8px 12px; font: inherit; font-size: 15px; font-weight: 600;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--tile-yellow-bg); color: var(--text);
}
.fs-input:focus { outline: none; border-color: var(--accent); }
.fs-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.fs-cat {
  padding: 5px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.fs-cat:hover { border-color: var(--accent); }
.fs-cat.on { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.fs-found { display: flex; flex-direction: column; gap: 6px; margin-left: auto; text-align: right; }
.fs-found b { font-size: 22px; line-height: 1; color: var(--accent-ink); }
.fs-table-wrap {
  overflow-x: auto; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
}
.fs-table-wrap > .hint, .fs-table-wrap > .muted { padding: var(--pad-lg); }
.fs-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fs-table th {
  position: sticky; top: 0; padding: 9px 10px; text-align: left; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--muted); background: var(--panel-2); border-bottom: 1px solid var(--line);
}
.fs-table td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.fs-table tbody tr:last-child td { border-bottom: 0; }
.fs-table tbody tr:nth-child(even) td { background: var(--panel-2); }
.fs-row { cursor: pointer; }
.fs-table tbody tr.fs-row:hover td { background: var(--hover); }
.fs-row-off td { color: var(--muted); }
.fs-table .num { text-align: center; white-space: nowrap; }
.fs-name { font-weight: 600; white-space: nowrap; }
.fs-city { min-width: 110px; max-width: 180px; }
.fs-what { min-width: 240px; max-width: 420px; }
.fs-what-text { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.fs-contact { white-space: nowrap; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.fs-none { color: var(--muted); }
.fs-stage, .fs-grade {
  display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap;
}
.fs-stage-0 { background: var(--accent); color: var(--on-accent-strong); }
.fs-stage-1 { background: var(--tile-green-bg); color: var(--tile-green-text); }
.fs-stage-2 { background: var(--tile-violet-bg); color: var(--tile-violet-text); }
.fs-stage-3 { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fs-stage-4 { background: var(--panel-2); color: var(--muted); }
.fs-stage-5 { background: var(--tile-blush-bg); color: var(--tile-blush-text); }
.fs-stage-6 { background: var(--tile-rose-bg); color: var(--tile-rose-text); }
.fs-grade-hi { background: var(--tile-green-bg); color: var(--tile-green-text); }
.fs-grade-mid { background: var(--tile-yellow-bg); color: var(--tile-yellow-text); }
.fs-grade-lo { background: var(--tile-rose-bg); color: var(--tile-rose-text); }

/* «Все фабрики» в шапке «Контрагентов» (11.11.2026): открыта — подсвечена, как вкладка. */
.all-factories-btn.on { background: var(--accent-dim); border-color: var(--accent); color: var(--text); font-weight: 600; }


/* «Настройки → Подключения» (12.11.2026, `ui/integrations.js`): слева список подключений с точкой
   состояния, справа — одно выбранное. Каждое отдельно, не одной простынёй (её слово). */
.int-wrap { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 18px; align-items: start; min-height: 360px; }
.int-nav { display: flex; flex-direction: column; gap: 2px; border-right: 1px solid var(--line); padding-right: 12px; }
.int-nav-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 9px 10px; text-align: left;
  background: none; border: 0; border-radius: var(--radius-sm); color: var(--text); cursor: pointer; font: inherit;
}
.int-nav-item:hover { background: var(--hover); }
.int-nav-item.active { background: var(--accent-dim); }
.int-nav-item .int-dot { margin-top: 5px; }
.int-nav-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.int-nav-title { font-weight: 600; }
.int-nav-what { font-size: 12px; color: var(--muted); }
.int-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--line); box-shadow: inset 0 0 0 1px var(--muted); }
.int-dot.is-ok { background: var(--ok); box-shadow: inset 0 0 0 1px var(--ink-green); }
.int-dot.is-warn { background: var(--warn); box-shadow: inset 0 0 0 1px var(--ink-yellow); }
.int-dot.is-bad { background: var(--ink-rose); box-shadow: none; }
.int-pane { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.int-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.int-title { margin: 0; font-family: var(--font-display); font-size: 20px; font-weight: 600; }
.int-what { color: var(--muted); font-size: 13px; }
.int-state { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.int-problem {
  padding: 8px 12px; font-size: 13px; border-radius: var(--radius-sm);
  background: var(--tile-rose-bg); color: var(--tile-rose-text);
}
.int-body { display: flex; flex-direction: column; gap: 10px; }
.int-body > .trends-connect { padding: 0; border: 0; background: none; max-width: none; }
.int-body > .row-actions { margin: 0; }
.int-body > .section-subhead { margin: 6px 0 0; }
.int-brands { display: flex; flex-wrap: wrap; gap: 6px; }
.int-brands:empty { display: none; }
.int-brand {
  display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px; font: inherit; font-size: 13px;
  background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
}
.int-brand:hover { background: var(--hover); }
.int-brand.active { background: var(--accent-dim); border-color: var(--accent); font-weight: 600; }
.int-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.int-row:last-child { border-bottom: 0; }
.int-row-name { font-weight: 600; }
.int-row-words { flex: 1 1 auto; color: var(--muted); font-size: 13px; min-width: 0; }
/* Что-то в подключениях не работает — красная точка у «Настроек» внизу меню и у вкладки. */
#btn-settings.has-problem, .subtab.has-problem { position: relative; }
#btn-settings.has-problem::after, .subtab.has-problem::after {
  content: ''; position: absolute; top: 6px; left: 22px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink-rose); box-shadow: 0 0 0 2px var(--panel);
}
.subtab.has-problem::after { left: auto; right: 2px; top: 4px; }
@media (max-width: 700px) {
  .int-wrap { grid-template-columns: minmax(0, 1fr); }
  .int-nav { border-right: 0; border-bottom: 1px solid var(--line); padding: 0 0 10px; }
}

/* «Фабрики на доске» — шестерёнка полосы фабрик «Заказов» и её окно (11.11.2026). */
.tab.tab-gear { display: inline-flex; align-items: center; justify-content: center; flex: none; padding-left: 8px; padding-right: 8px; }
.tab.tab-gear svg { width: 16px; height: 16px; }
.board-factories-list { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; max-height: 60vh; overflow-y: auto; }
.board-factories-row { display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-radius: 6px; cursor: pointer; }
.board-factories-row:hover { background: var(--accent-dim); }
.board-factories-row input:disabled + span { opacity: 0.7; }

html { --styles-complete: 1; }
