/* Свой слой поверх Bootstrap (появился на этапе редизайна, срез 1 «Каркас»).
   Здесь только то, чего нет в Bootstrap: акцентный цвет, нижняя навигация
   для телефона и отступ под неё. Правило: сперва ищем готовый класс Bootstrap,
   своё пишем только когда его нет. */

:root {
  /* Акцент «расплавленный чугун» — ОДИН бренд-цвет на обе темы. Был #e8873f, но владелец
     05.07: на OLED-айфоне цвет приятный, а на IPS-мониторе компа читается «токсично»
     (насыщенный оранжевый на широком экране «вибрирует»). Приглушён ~на 20% насыщенности
     (спека §2 «десатурируем ~20»), оттенок и яркость сохранены — та же «расплав»-тёплость,
     но спокойнее. Один тон на обе темы; на белом мелкие ссылки чуть слабее по контрасту,
     но рабочая тема тёмная (дефолт), там читается уверенно. Крутить дальше — эти три строки. */
  --lp-accent: #d98a52;
  --lp-accent-hi: #e8a066;       /* hover/active заливки — на ступень светлее */
  --lp-accent-contrast: #1a1206; /* тёмный текст на акцентной заливке */
  --lp-accent-ink: var(--lp-accent);  /* текстовый акцент — тот же бренд-оранжевый */
  --lp-mono: ui-monospace, "Cascadia Code", Consolas, "SFMono-Regular", Menlo, monospace;
}

/* Палитра тёмной темы — «железо» из макета: фон темнее и теплее bootstrap-дефолта,
   карточки чуть приподняты, поля ввода утоплены (наследуют --bs-body-bg). */
[data-bs-theme="dark"] {
  --bs-body-bg: #17181b;
  --bs-body-color: #e8e6e1;
  --bs-secondary-color: rgba(232, 230, 225, .62);   /* ≈ #a6a49e */
  --bs-tertiary-color: rgba(232, 230, 225, .44);    /* ≈ #6d6b66 */
  --bs-secondary-bg: #25292f;
  --bs-tertiary-bg: #1b1d21;                        /* шапка (bg-body-tertiary) */
  --bs-border-color: #33373e;
  --bs-border-color-translucent: rgba(255, 255, 255, .09);
}
[data-bs-theme="dark"] .card { --bs-card-bg: #212429; }

/* Один акцент на всё приложение: синий bootstrap-primary уступает «расплаву».
   Ссылки — ЕДИНЫЙ бренд-оранжевый в обеих темах (не по теме, владелец 04.07). */
:root, [data-bs-theme="dark"], [data-bs-theme="light"] {
  --bs-link-color: var(--lp-accent);
  --bs-link-hover-color: var(--lp-accent-hi);
  --bs-link-color-rgb: 217, 138, 82;
  --bs-link-hover-color-rgb: 232, 160, 102;
}

/* Главные кнопки: акцентная заливка с тёмным текстом (как .btn.primary макета). */
.btn-primary {
  --bs-btn-bg: var(--lp-accent);
  --bs-btn-border-color: var(--lp-accent);
  --bs-btn-color: var(--lp-accent-contrast);
  --bs-btn-hover-bg: var(--lp-accent-hi);
  --bs-btn-hover-border-color: var(--lp-accent-hi);
  --bs-btn-hover-color: var(--lp-accent-contrast);
  --bs-btn-active-bg: var(--lp-accent-hi);
  --bs-btn-active-border-color: var(--lp-accent-hi);
  --bs-btn-active-color: var(--lp-accent-contrast);
  /* отключённая — ПРИГЛУШЁННО-СЕРОЙ, не оранжевой (владелец 07.07: «показать серой»;
     UX-практика: disabled должна ВЫГЛЯДЕТЬ disabled, иначе жмут в пустоту) */
  --bs-btn-disabled-bg: var(--bs-secondary-bg);
  --bs-btn-disabled-border-color: var(--bs-border-color);
  --bs-btn-disabled-color: var(--bs-secondary-color);
  --bs-btn-focus-shadow-rgb: 217, 138, 82;
}
.btn-outline-primary {
  --bs-btn-color: var(--lp-accent-ink);
  --bs-btn-border-color: var(--lp-accent-ink);
  --bs-btn-hover-bg: var(--lp-accent);
  --bs-btn-hover-border-color: var(--lp-accent);
  --bs-btn-hover-color: var(--lp-accent-contrast);
  --bs-btn-active-bg: var(--lp-accent);
  --bs-btn-active-border-color: var(--lp-accent);
  --bs-btn-active-color: var(--lp-accent-contrast);
  --bs-btn-focus-shadow-rgb: 217, 138, 82;
}

/* Фокус и выбор в формах — тем же акцентом (рамка + мягкое кольцо). */
.form-control:focus, .form-select:focus, .form-check-input:focus {
  border-color: var(--lp-accent);
  box-shadow: 0 0 0 .25rem rgba(217, 138, 82, .25);
}
.form-check-input:checked {
  background-color: var(--lp-accent);
  border-color: var(--lp-accent);
}
.nav-pills {
  --bs-nav-pills-link-active-bg: var(--lp-accent);
  --bs-nav-pills-link-active-color: var(--lp-accent-contrast);
}
/* Маркер «наш ответ» («Вы» в ленте) — тоже акцентом; бейджи СТАДИЙ (text-bg-*)
   не трогаем: у стадии свой смысл-цвет, это не действие. */
.text-primary { color: var(--lp-accent-ink) !important; }
.spinner-border { color: var(--lp-accent); }
/* Шеврон аккордеона («Заказчик»/«Условия») — у Bootstrap это SVG в data-URI со своим
   синим; перекрашиваем единым бренд-оранжевым (--lp-accent, обе темы — владелец 04.07). */
.accordion-button::after {
  --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23d98a52'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
  --bs-accordion-btn-active-icon: var(--bs-accordion-btn-icon);
}

/* iOS-грабли веб-приложений разом (прогон владельца на iPhone 04.07):
   - text-size-adjust: iOS сам раздувает шрифт в некоторых случаях — фиксируем 100%;
   - tap-highlight: серая вспышка-прямоугольник при тапе по ссылке/кнопке — убираем
     (у нас свои состояния :active/:focus);
   - overscroll-behavior: «резина» прокрутки за край цепляла страницу и она
     «прыгала пока не остановится» у нижней кромки — гасим цепочку overscroll. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overscroll-behavior-y: none;
}
* { -webkit-tap-highlight-color: transparent; }

/* Плотность макета: контролы и подписи компактнее bootstrap-дефолта.
   На грубом указателе (палец) тач-цель кнопок остаётся ≥44px. */
body { font-size: .925rem; }
h1, .h1 { font-size: 1.45rem; }
h2, .h2 { font-size: 1.25rem; }
h3, .h3 { font-size: 1.1rem; }
.btn {
  --bs-btn-padding-y: .42rem;
  --bs-btn-padding-x: .8rem;
  --bs-btn-font-size: .875rem;
  border-radius: 9px;   /* как .btn макета (line 92); было 6px бутстрапа — «менее круглые» */
}
.form-control { font-size: .875rem; padding: .42rem .65rem; }
/* У select справа остаётся место под стрелку — иначе она наезжает на текст */
.form-select { font-size: .875rem; padding: .42rem 2.25rem .42rem .65rem; }
.form-label { margin-bottom: .25rem; font-size: .82rem; }
.table > :not(caption) > * > * { padding: .45rem .5rem; }
@media (pointer: coarse) {
  /* inline-flex + центрирование: min-height растягивал кнопку, а иконка (⚙, ↻)
     оставалась прижатой кверху — «значок кривой» (владелец, iPhone 04.07) */
  .btn:not(.lp-icon-btn) {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .35rem;   /* flex глотает пробел между <i> и текстом — «⚙Это клиент» слипалось */
  }
  .form-control, .form-select { min-height: 44px; }
  textarea.form-control { min-height: unset; }
}
/* iPhone сам ПРИБЛИЖАЕТ страницу при фокусе поля, если шрифт поля < 16px, и не
   отдаляет обратно (владелец 04.07: «зачем-то приближает», «курсор в другом
   месте» — это скачок экрана в момент зума). На телефоне поля — ровно 16px.
   input.lp-field (0,1,1) специфичнее .lp-field (0,1,0) ниже в файле — иначе
   определение поля .875rem перебивало это правило и поиск оставался 14px = зум. */
@media (max-width: 991.98px) {
  .form-control, .form-select, input.lp-field, textarea.lp-field { font-size: 1rem; }
}

/* Цифры денег/дат — моноширинные табличные, как .num макета: суммы выравниваются
   и «прыгают» меньше. Вешается точечно в шаблонах на суммы и счётчики;
   суммы сметы и «Итого» на карточке заказа — сразу здесь, по своим классам. */
.lp-num, .lp-item-sum, .lp-total-val {
  font-family: var(--lp-mono);
  font-variant-numeric: tabular-nums;
}

/* ── Каркас прототипа: боковое меню + узкая колонка (компьютер, ≥lg) ─────────
   Верхняя панель на всю ширину растягивала контент по монитору — лента
   распадалась «в таблицу» (владелец 04.07). Слева узкое меню, контент — колонка. */
@media (min-width: 992px) {
  .lp-shell { display: grid; grid-template-columns: 195px minmax(0, 1fr); min-height: 100vh; }
  .lp-main { min-width: 0; padding-top: 1.25rem; }
  /* Колонка как в прототипе (узкая!): строки держатся вместе, не разлетаясь
     по монитору — на 1920px именно ширина превращала ленту «в таблицу» */
  .lp-content { max-width: 880px; }
}
.lp-side {
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  background: var(--bs-tertiary-bg);
  border-right: 1px solid var(--bs-border-color);
  position: sticky;
  top: 0;
  height: 100vh;
}
.lp-side-logo {
  font-family: var(--lp-mono);
  font-size: .85rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--lp-accent);
  text-decoration: none;
  padding: 6px 12px 14px;
}
.lp-side-logo:hover, .lp-side-logo:focus { color: var(--lp-accent-hi); }
.lp-side-link {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: .9rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.lp-side-link:hover, .lp-side-link:focus { color: var(--bs-body-color); background: var(--bs-secondary-bg); }
.lp-side-link.active { color: var(--lp-accent-ink); background: var(--bs-secondary-bg); font-weight: 600; }
/* «Выйти» — кнопка в POST-форме, но в ряду меню выглядит как ссылка (сброс родных
   стилей кнопки, как у button.lp-gal-item). */
button.lp-side-link { border: 0; background: none; font: inherit; cursor: pointer; text-align: left; }
.lp-side-sp { flex: 1; }

/* ── Компоненты ПРОТОТИПА, значения 1-в-1 (docs/litplit-proto.html) ──────────
   Урок 04.07: «похожие» bootstrap-детали (холодный серый, склеенный поиск) читались
   владельцем как «не то». Здесь — точные hex/размеры прототипа; светлая тема
   получает нейтральные аналоги через переменные. */

/* Чипы-фильтры (.chips .c прототипа): тихие пилюли, активная — светло-серая заливка */
.lp-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.lp-chip {
  flex: 0 0 auto;
  font-size: .7rem;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg);
  text-decoration: none;
  white-space: nowrap;
}
.lp-chip:hover, .lp-chip:focus { color: var(--bs-body-color); }
/* Разрыв ряда чипов: на телефоне сегменты и каналы — два РОВНЫХ ряда */
.lp-chip-break { flex-basis: 100%; height: 0; }
.lp-chip.on, .lp-chip.active { color: var(--bs-body-bg); background: var(--bs-secondary-color);
  border-color: var(--bs-secondary-color); font-weight: 600; }
/* Канал со сбоем приёма — статус по ИСКЛЮЧЕНИЮ: здоровый тих, сломанный красный
   (владелец 04.07: «✓ у каждого — шум, показывай лучше»). Подробность — строкой ниже. */
.lp-chip-err { color: var(--bs-danger); border-color: var(--bs-danger); }
[data-bs-theme="dark"] .lp-chip-err { color: #f2837f; border-color: #813; }
[data-bs-theme="dark"] .lp-chip { border-color: #33373e; color: #a6a49e; background: #212429; }
[data-bs-theme="dark"] .lp-chip:hover, [data-bs-theme="dark"] .lp-chip:focus { color: #e8e6e1; }
[data-bs-theme="dark"] .lp-chip.on, [data-bs-theme="dark"] .lp-chip.active { color: #17181b; background: #a6a49e; border-color: #a6a49e; }
/* Счётчик в чипе (.cn прототипа): сколько сейчас в корзине — моно, приглушённо */
.lp-chip-n { font-family: var(--lp-mono); opacity: .6; margin-left: 4px; }

/* Поле (.field прототипа): простой утопленный инпут, без приклеенных иконок */
.lp-field {
  display: block;
  width: 100%;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 9px;
  padding: 8px 10px;
  color: var(--bs-body-color);
  font-size: .875rem;
}
.lp-field::placeholder { color: var(--bs-tertiary-color); }
.lp-field:focus { outline: none; border-color: var(--lp-accent); box-shadow: 0 0 0 .25rem rgba(217, 138, 82, .25); }
[data-bs-theme="dark"] .lp-field { background: #17181b; border-color: #33373e; color: #e8e6e1; }
[data-bs-theme="dark"] .lp-field::placeholder { color: #6d6b66; }

/* Пилюля статуса (.pill прототипа): точка + слово, полупрозрачная заливка */
.lp-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: .66rem;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.lp-pill .lp-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.lp-pill-new { color: #818b97; background: #818b9718; border-color: #818b9740; }
.lp-pill-hidden { color: #6d6b66; background: #6d6b6618; border-color: #6d6b6640; }
/* Стадии заказа и оплата — пилюлями со смысл-цветом прототипа (точка + слово + ▾).
   Ключи совпадают со стадиями воронки (services/orders.ORDER_STAGES). */
.lp-pill-zayavka      { color: #818b97; background: #818b9718; border-color: #818b9740; }
.lp-pill-raschet      { color: #7fb0d4; background: #5e8bad1e; border-color: #5e8bad45; }
.lp-pill-soglasovanie { color: #63b8aa; background: #4f9b8e1c; border-color: #4f9b8e45; }
.lp-pill-proizvodstvo { color: #c9a23f; background: #c9a23f1c; border-color: #c9a23f45; }
.lp-pill-zavershen    { color: #6ea36b; background: #6ea36b1c; border-color: #6ea36b45; }
.lp-pill-pay          { color: #d0a24a; background: #d0a24a18; border-color: #d0a24a40; }
/* Статус «клиент» (зелёный, тон .lp-pill-zavershen) и «залежался» (тревожный красный,
   пилюлей, а не бейджем text-bg-danger — единый вид со стадиями/оплатой). */
.lp-pill-client       { color: #6ea36b; background: #6ea36b1c; border-color: #6ea36b45; }
.lp-pill-stale        { color: #d98080; background: #d9808018; border-color: #d9808040; }
/* Пилюля-кнопка кликабельна (открывает список стадий/оплаты). */
button.lp-pill { cursor: pointer; }
.lp-pill.dropdown-toggle::after { margin-left: .15rem; vertical-align: middle; }

/* Мета-строка письма (адрес · время): моно, тихая, как .meta прототипа */
.lp-meta { font-family: var(--lp-mono); font-size: .72rem; color: var(--bs-tertiary-color); }
[data-bs-theme="dark"] .lp-meta { color: #6d6b66; }
.lp-meta a { color: inherit; }

/* Мини-тег статуса документа в строке заказа (прототип .tag/.tag.ok): моно, тихий контур;
   .is-done — выпущен (зелёный, тон .lp-pill-zavershen). Показываем ТОЛЬКО когда документы
   в игре (см. orders_list.html), чтобы не сыпать «✓» на каждый заказ (владелец 04.07). */
.lp-tag {
  display: inline-flex; align-items: center; gap: 3px;
  font-family: var(--lp-mono); font-size: .62rem; line-height: 1.5;
  color: var(--bs-tertiary-color);
  border: 1px solid var(--bs-border-color); border-radius: 5px; padding: 0 6px;
}
.lp-tag.is-done { color: #6ea36b; border-color: #6ea36b55; }
[data-bs-theme="dark"] .lp-tag { border-color: #33373e; color: #6d6b66; }
[data-bs-theme="dark"] .lp-tag.is-done { color: #6ea36b; border-color: #6ea36b55; }

/* Флеш-отчёты («Почта: новых нет») в тёмной теме выглядели пустыми полями —
   у alert-secondary не было ни фона, ни контраста. Плашка как карточка + компактно. */
.alert { --bs-alert-padding-y: .45rem; font-size: .875rem; }
[data-bs-theme="dark"] .alert-secondary {
  --bs-alert-bg: #212429;
  --bs-alert-color: #a6a49e;
  --bs-alert-border-color: #33373e;
}

/* Иерархия сумм сметы: итог — ГЛАВНАЯ цифра, крупнее сумм строк (владелец 06.07:
   «почему итог меньше сумм в таблице?»). */
.lp-sticky-bottom .js-total { font-size: 1.2rem; font-weight: 600; }

/* «Призрачные» кнопки в тёмной теме — серые ПРОТОТИПА, не холодный bootstrap-серый */
[data-bs-theme="dark"] .btn-outline-secondary {
  --bs-btn-color: #a6a49e;
  --bs-btn-border-color: #33373e;
  --bs-btn-bg: transparent;
  --bs-btn-hover-color: #e8e6e1;
  --bs-btn-hover-bg: #282c33;
  --bs-btn-hover-border-color: #454a52;
  --bs-btn-active-color: #e8e6e1;
  --bs-btn-active-bg: #31353c;
  --bs-btn-active-border-color: #454a52;
}
[data-bs-theme="dark"] .badge.text-bg-secondary {
  background-color: #818b9718 !important;
  border: 1px solid #818b9740;
  color: #98a1ab;
}

/* Входящие: клиенты — тихие строки с разделителем; ЖДУЩИЕ РАЗБОРА — карточка
   (.card прототипа) с кнопками под текстом: письмо → решение тут же. */
.lp-inbox-group { padding: .65rem 2px; border-bottom: 1px solid var(--bs-border-color-translucent); }
.lp-inbox-group:last-of-type { border-bottom: 0; }
.lp-inbox-card {
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  padding: 11px;
  margin-bottom: 9px;
}
[data-bs-theme="dark"] .lp-inbox-card { background: #212429; border-color: #33373e; }
/* Разобранные в «Все» — та же карточка, но тише: прозрачный фон, рамка мягче.
   Тихие строки БЕЗ обводки владелец прочитал «непонятно что это» (04.07). */
.lp-inbox-done { background: transparent; }
[data-bs-theme="dark"] .lp-inbox-done { background: transparent; border-color: #2a2d33; }

/* Тихая главная кнопка очереди разборки. Владелец (04.07): сплошная оранжевая заливка
   на каждой карточке — «токсично», а «у одних цвет, у других нет» в одном списке —
   разнобой. Поэтому В ОЧЕРЕДИ все кнопки одинаково спокойные (как действия строк в
   профи-inbox'ах), главная отличается акцентным ТЕКСТОМ, а заливку получает только
   когда рука дошла до карточки (hover/фокус). На таче — просто спокойная кнопка. */
.btn-lp-quiet {
  /* Владелец: «Это клиент» подсвечена ПОСТОЯННО, а не при наводке — сплошная заливка. */
  --bs-btn-color: var(--lp-accent-contrast);
  --bs-btn-bg: var(--lp-accent);
  --bs-btn-border-color: var(--lp-accent);
  --bs-btn-hover-bg: var(--lp-accent);
  --bs-btn-hover-border-color: var(--lp-accent);
  --bs-btn-hover-color: var(--lp-accent-contrast);
  --bs-btn-active-bg: var(--lp-accent-hi);
  --bs-btn-active-border-color: var(--lp-accent-hi);
  --bs-btn-active-color: var(--lp-accent-contrast);
  --bs-btn-focus-shadow-rgb: 217, 138, 82;
}
.lp-inbox-card:hover .btn-lp-quiet,
.lp-inbox-card:focus-within .btn-lp-quiet {
  color: var(--lp-accent-contrast);
  background-color: var(--lp-accent);
  border-color: var(--lp-accent);
}
/* На УЗКОМ экране (телефон, прототип рисует именно так) главная кнопка всегда с
   заливкой: видно ~одну карточку, «один акцент на видимый экран» соблюдается сам
   собой. Ширина, а не hover-способность: владелец смотрит телефонную ширину и
   мышью (DevTools) — вид должен совпадать. На широких экранах карточек много —
   там тихий вариант с подсветкой при наведении. */
@media (max-width: 767.98px) {
  .btn-lp-quiet {
    color: var(--lp-accent-contrast);
    /* ТОТ ЖЕ акцент, что у панели/бейджа — не accent-hi: «на ступень ярче» давало
       кнопке другой оттенок, чем нижнее меню (владелец 04.07: «в панели цвет
       нормальный, а у кнопок разный»). Один бренд-оранжевый на всё. */
    background-color: var(--lp-accent);
    border-color: var(--lp-accent);
  }
}

/* Заголовок-секция «КАК В МАКЕТЕ»: мелкий, капс, моно (.sec макета). */
.lp-sec {
  font-family: var(--lp-mono);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bs-tertiary-color);
  margin: 1rem 0 .4rem;
}

/* Бренд и активный раздел навигации — акцентом; остальное оставляем Bootstrap */
.navbar-brand { color: var(--lp-accent); font-weight: 600; }
.navbar-brand:hover, .navbar-brand:focus { color: var(--lp-accent); }
.navbar .nav-link.active { color: var(--lp-accent); font-weight: 600; }

/* Вкладки карточки заказа. Активную НЕ красим акцентом: Bootstrap и так метит её
   рамкой-язычком (индикатор не только цветом), а янтарный текст на белом в светлой теме
   не проходит контраст 4.5:1. На телефоне вкладки НЕ переносим в два ряда (стыковка рамки
   ломается), а прокручиваем в один ряд; тач-цель ≥44px — как у прочих контролов проекта. */
@media (max-width: 767.98px) {
  #order-tabs { flex-wrap: nowrap; overflow-x: auto; }
  #order-tabs .nav-link { white-space: nowrap; }
}
@media (pointer: coarse) {
  #order-tabs .nav-link { min-height: 44px; display: flex; align-items: center; }
}

/* Бейдж «неразобранные» — тоже акцентом, чтобы не спорил с красным «опасно» */
.lp-badge { background: var(--lp-accent); color: var(--lp-accent-contrast); }

/* Нижняя панель разделов — только на телефоне (d-md-none в разметке).
   Высота ~56px + запас под «бровь» iPhone (safe-area). */
.lp-bottomnav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 1030;
  display: flex;
  background: var(--bs-body-bg);
  border-top: 1px solid var(--bs-border-color);
  padding-bottom: env(safe-area-inset-bottom);
}
.lp-bottomnav .lp-tab {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: .45rem 0 .4rem;
  font-size: .7rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.lp-bottomnav .lp-tab .bi { font-size: 1.3rem; line-height: 1; }
.lp-bottomnav .lp-tab.active { color: var(--lp-accent); }
.lp-bottomnav .lp-tab.disabled { opacity: .4; }

/* Поиск — последний в полосе фильтров: без нижнего отступа, чтобы полоса была плотной. */
.lp-inbox-controls form[role="search"] { margin-bottom: 0 !important; }

/* КОМПЬЮТЕР (≥992px): места много — липнет ВСЯ шапка целиком (заголовок виден, не
   «обрезано» — владелец 04.07: «на компе места больше, зачем обрезать»). */
@media (min-width: 992px) {
  .lp-inbox-head {
    position: sticky;
    top: 0;
    z-index: 1020;
    background: var(--bs-body-bg);
    padding: .75rem 0 .5rem;
    margin-bottom: .5rem;
    border-bottom: 1px solid var(--bs-border-color);
  }
}

/* Чтобы нижняя панель не закрывала конец страницы (панель видна до 992px);
   верхней полосы бренда на телефоне нет — контенту свой отступ сверху
   (+ запас под «бровь» iPhone). */
@media (max-width: 991.98px) {
  body { padding-bottom: calc(3.8rem + env(safe-area-inset-bottom)); }
  .lp-main { padding-top: calc(.75rem + env(safe-area-inset-top)); }
  /* Обёртка .lp-inbox-head на телефоне НЕ создаёт бокс (display:contents): иначе
     sticky-полоса фильтров липла бы к короткому родителю и уезжала с ним вверх
     (владелец 04.07: «на телефоне нет закрепа»). Так полоса — прямой ребёнок
     колонки и липнет к ЭКРАНУ. На компе .lp-inbox-head сам sticky (там нужен бокс). */
  .lp-inbox-head { display: contents; }
  /* ТЕЛЕФОН/планшет: заголовок прокручивается, липнет только тонкая полоса
     фильтров+поиска (высота дорога). Full-bleed по ширине, фон + нижняя рамка,
     GPU-слой (sticky на iOS дёргается при смене высоты окна — владелец 04.07). */
  .lp-inbox-controls {
    position: sticky;
    top: 0;
    z-index: 1020;
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color);
    margin: 0 calc(var(--bs-gutter-x) * -.5) .5rem;
    padding: .5rem calc(var(--bs-gutter-x) * .5);
    transform: translateZ(0);
  }
}

/* Липкой шапки больше нет (полоса бренда убрана 04.07) — небольшой запас, чтобы
   прыжок по якорю (#notes, #msg-N) не прилипал вплотную к краю экрана. */
html { scroll-padding-top: 1rem; }

/* Chrome на iPhone (прогон владельца 04.07): при прокрутке панель браузера
   сжимается/растёт, вьюпорт меняет высоту и на миг обнажается фон <html> —
   по умолчанию БЕЛЫЙ (тема красит только body). Отсюда «белая полоса снизу».
   Красим корень в цвет темы — переменная резолвится на самом html. */
html { background-color: var(--bs-body-bg); }

/* Телефон, реальный прогон владельца 04.07: длинное «слово» клиента (URL из
   письма-уведомления, номер отслеживания) не переносится по пробелам и распирало
   страницу вбок — появлялся горизонтальный скролл и «белая полоса» скроллбара.
   anywhere: рвать длинные слова можно где угодно, обычный текст не трогается. */
.lp-content { overflow-wrap: anywhere; }
/* Страховка каркаса: что бы ни распёрло контент, страница вбок не ездит.
   Именно clip, не hidden: clip не создаёт скролл-контейнер и не ломает sticky. */
.lp-main { overflow-x: clip; }
/* Тач-цели кнопок шапки (тема, настройки) — 44px под палец на грубом указателе */
@media (pointer: coarse) {
  .lp-navbtn { min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center; }
}

/* Сниппет последнего сообщения в карточке списка: максимум две строки, дальше «…»
   (в Bootstrap есть только однострочный text-truncate) */
.lp-snippet {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Ростер клиентов (.listrow прототипа): плоские строки-ДЕЙСТВИЕ с тонким разделителем.
   НЕ карточки: список для СКАНИРОВАНИЯ (найти человека → открыть карточку), не для чтения —
   иначе 430 рамок утяжелили бы экран и замедлили поиск глазами. Вся строка — ссылка. */
.lp-row {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 11px 2px;
  border-bottom: 1px solid var(--bs-border-color-translucent);
  text-decoration: none;
  color: inherit;
}
.lp-row:last-child { border-bottom: 0; }
/* Строка-КНОПКА (режим выбора клиента: тап = выбрать — POST, не переход): тот же вид,
   что строка-ссылка, но <button> внутри <form> — сбрасываем его родные рамку/фон/шрифт. */
button.lp-row {
  width: 100%;
  background: none;
  font: inherit;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--bs-border-color-translucent);
}
.lp-row:hover, .lp-row:focus { background: var(--bs-tertiary-bg); }
[data-bs-theme="dark"] .lp-row:hover, [data-bs-theme="dark"] .lp-row:focus { background: #1c1e22; }
.lp-row-main { min-width: 0; }                 /* min-width:0 даёт длинным строкам ужиматься */
.lp-row-name { font-weight: 600; font-size: .92rem; color: var(--bs-body-color); }
.lp-row-right { margin-left: auto; text-align: right; flex: 0 0 auto; white-space: nowrap; align-self: center; }

/* Лента материала клиента — контейнер С ПРОКРУТКОЙ (прототип: один блок), чтобы длинная
   переписка не растягивала страницу до бесконечности (владелец 04.07: «зачем огромная
   страница, которую долго искать»). Крутится внутри, страница остаётся компактной. */
.lp-feed { max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; }

/* Иконки-кнопки (карандаш, корзина, «Убрать», ×): на десктопе компактные,
   на таче — крупная зона нажатия (аудит: у btn-link p-0 было ~16px при норме 44).
   Отрицательный вертикальный margin не даёт карточкам разъехаться по высоте;
   по горизонтали кнопки занимают честное место — зоны соседей не наползают. */
.lp-icon-btn { display: inline-block; padding: .125rem .25rem; line-height: 1; }
@media (pointer: coarse) {
  .lp-icon-btn { padding: .75rem .625rem; margin-top: -.5rem; margin-bottom: -.5rem; }
  /* Галочки отбора «в заказ» и переключатели — тоже крупнее под палец */
  .form-check-input { width: 1.3em; height: 1.3em; }
}

/* Чекбокс отбора «в заказ»/«на распознавание» — обёрнут в кликабельный ярлык.
   На десктопе компактный, как раньше; на таче — цель ≥44px (аудит: голый чекбокс ~21px). */
.lp-pick-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin-bottom: 0;
  cursor: pointer;
}
@media (pointer: coarse) {
  .lp-pick-check { min-width: 44px; min-height: 44px; }
}

/* Каталог: обложка в карточке списка (квадрат задаёт .ratio, фото заполняет его
   без искажений) и миниатюра фото на карточке изделия */
.lp-cover { object-fit: cover; width: 100%; height: 100%; }
.lp-photo-thumb { width: 7rem; height: 7rem; object-fit: cover; display: block; }
/* Миниатюра фото ИЗДЕЛИЯ — по натуральным пропорциям на фикс-высоте: ни обрезки (cover),
   ни полос (contain), просто фото (владелец 05.07). Главное фото — img-fluid в шаблоне. */
.lp-photo-thumb.lp-thumb-fit { width: auto; height: 7rem; }

/* Окно быстрого просмотра — по размеру самого фото, не огромный бокс вокруг маленькой
   картинки (владелец 05.07). На телефоне остаётся fullscreen (modal-fullscreen-md-down). */
@media (min-width: 768px) {
  .lp-preview-dialog { width: fit-content; max-width: 96vw; }
}
#file-preview-body img, #file-preview-body iframe { max-height: 86vh; max-width: 96vw; }
#file-preview-body img { width: auto; height: auto; }

/* Липкая панель действий у низа окна: «Отмечено → В заказ» на карточке клиента и
   «Итого + Сохранить» на карточке заказа. Видна при любой прокрутке;
   на телефоне — над нижней панелью разделов. */
/* ── Карточка заказа: источник и форма РЯДОМ (владелец 05.07: сотрудница работает ИЗ
   материала — сообщения клиента должны быть под рукой, пока она заполняет данные/смету,
   а не лежать стопкой сверху/снизу, из-под которой уезжают). На компьютере — две колонки:
   слева ЛИПКИЙ материал со своим скроллом (виден всегда), справа данные→смета→документы.
   Для этого экрана снимаем узкий лимит колонки (880px душит две панели + смету). */
@media (min-width: 992px) {
  .lp-content.lp-content--wide { max-width: 1160px; }
  .lp-order-grid {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
  }
  /* Материал липнет к верху — виден, пока справа мотают смету. СВОЕГО скролла НЕТ намеренно
     (владелец 05.07: «навожусь на материал — прокрутка страницы не работает»): собственный
     overflow перехватывал колесо, и страница не крутилась. Теперь колесо над материалом
     всегда крутит страницу; при длинной переписке материал просто пролистывается вместе с ней. */
  .lp-order-source {
    position: sticky;
    top: 1rem;
  }
}
/* Телефон/планшет (<992px): одна колонка, материал сверху и быстро сворачивается —
   доступ к нему на расстоянии одного тапа (см. кнопку сворачивания в шапке материала). */

/* ── Панель материала заказа (#material): лёгкие ПЛОСКИЕ строки вместо тяжёлых бутстрап-
   карточек (владелец 05.07: «нормальный дизайн для меню материалов»). Тонкий разделитель,
   компактно; действия-иконки тихие до наведения (на таче — всегда видны). */
#material .card {
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--bs-border-color-translucent);
  background: transparent;
  margin-bottom: 0 !important;
}
#material #notes .card:last-child { border-bottom: 0; }
#material .card > .card-body { padding: .55rem .15rem; }
/* Список сообщений не растягивает панель на сотни записей (владелец 05.07): выше порога —
   свой скролл ТОЛЬКО у списка. Порог щедрый (60vh): обычный заказ в него влезает и не
   перехватывает колесо — прокрутка страницы работает; сотни сообщений листаются внутри. */
#material #notes { max-height: 60vh; overflow-y: auto; scrollbar-gutter: stable; }
@media (hover: hover) {
  #material .lp-icon-btn { opacity: 0; transition: opacity .12s; }
  #material .card:hover .lp-icon-btn,
  #material .card:focus-within .lp-icon-btn { opacity: 1; }
}

.lp-sticky-bottom {
  position: sticky;
  bottom: 0;
  z-index: 1020; /* ниже нижней навигации (1030) */
  background: var(--bs-body-bg);
  border-top: 1px solid var(--bs-border-color);
  padding: .5rem 0;
}
@media (max-width: 767.98px) {
  .lp-sticky-bottom { bottom: calc(3.8rem + env(safe-area-inset-bottom)); }
}

/* Тосты (flash.js): всплывают в правом нижнем углу и сами гаснут — не распирают
   страницу, как прежний alert-блок. Кант слева цветом категории — тот же мотив, что
   у карточек «Документы» (глаз читает статус, не вчитываясь). До 992px нижняя панель
   видна — приподнимаем тосты над ней (её высота + safe-area), чтобы не перекрывались. */
.lp-toasts {
  right: 0;
  /* Приподнимаем не отступом, а самим углом (bottom): на телефоне контейнер встаёт
     НАД нижней панелью. Одно объявление bottom в базе — media ниже перебивает чисто
     (padding-bottom тут перебить не удавалось: в связке с шортхендом padding он
     выигрывал у media-правила). safe-area — «бровь» iPhone. */
  bottom: env(safe-area-inset-bottom, 0px);
  z-index: 1090;                      /* выше нижней навигации (1030) */
  max-width: min(92vw, 24rem);
  padding: .5rem;                     /* своё, не утилита p-2 (у неё !important) */
}
@media (max-width: 991.98px) {
  /* До 992px видна нижняя панель — ставим тосты над ней (её высота + safe-area). */
  .lp-toasts { bottom: calc(3.8rem + env(safe-area-inset-bottom)); }
}
.lp-toast { border-left: 3px solid var(--bs-border-color); }
.lp-toast .toast-body { align-items: center; }
.lp-toast .bi { font-size: 1.05rem; line-height: 1.35; }
.lp-toast-success { border-left-color: var(--bs-success); }
.lp-toast-success .bi { color: var(--bs-success); }
.lp-toast-danger { border-left-color: var(--bs-danger); }
.lp-toast-danger .bi { color: var(--bs-danger); }
.lp-toast-warning { border-left-color: var(--bs-warning); }
.lp-toast-warning .bi { color: var(--bs-warning); }
.lp-toast-info { border-left-color: var(--bs-info); }
.lp-toast-info .bi { color: var(--bs-info); }
.lp-toast-secondary .bi { color: var(--bs-secondary-color); }

/* Блок «Документы» — герой карточки заказа (мишень: «документы наверх, двое, не трое»).
   Договор и КП — двумя карточками рядом на десктопе, друг под другом на телефоне; кант
   слева бренд-оранжевым выделяет их как главное на экране. Внутри карточки: заголовок +
   одна кнопка («Скачать» у выпущенного / «Выпустить» у готового), статус строкой ниже —
   перевыпуск и удаление там ссылками. Строка статуса переносится (flex-wrap), поэтому
   ничего не уезжает за край даже на узком телефоне. */
.lp-docs { display: grid; gap: 9px; }
/* Значения ОДИН-В-ОДИН из прототипа (.doc): радиус 12px, паддинг 11px, кант слева 3px
   бренд-оранжевым, в тёмной теме — градиент #25292f→#212429. */
.lp-doc-card {
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-left: 3px solid var(--lp-accent);
  border-radius: 12px;
  padding: 11px;
}
[data-bs-theme="dark"] .lp-doc-card {
  background: linear-gradient(180deg, #25292f, #212429);
  border-color: #33373e;
}
.lp-doc-card strong { font-size: .9rem; }   /* .doc h4 прототипа */
.lp-doc-status { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: .6rem; row-gap: .15rem; }

/* Строка-сводка «ключ: значение» (.kv прототипа): тихая, мелкая, переносится. */
.lp-kv { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: .72rem; color: var(--bs-secondary-color); }
.lp-kv b { color: var(--bs-body-color); }

/* Смета — компактная таблица прототипа (.estimate): тонкие линии, мелкие моно-поля. */
.lp-estimate { width: 100%; border-collapse: collapse; font-size: .75rem; }
.lp-estimate td { padding: 5px 3px; border-bottom: 1px solid var(--bs-border-color-translucent); }

/* Заголовок карточки «Данные для документов»: кнопка-строка со сводкой и шевроном. */
.lp-data-head {
  display: flex; align-items: center; width: 100%;
  background: none; border: 0; padding: 0; color: inherit; text-align: left; cursor: pointer;
}
.lp-data-caret { transition: transform .2s; }
.lp-data-head[aria-expanded="true"] .lp-data-caret { transform: rotate(180deg); }
/* Свёрнутая сводка данных документов: «Заказчик · № · аванс» под заголовком — видно, что
   внутри, не разворачивая (владелец 05.07: «в прототипе сразу коротко пишут данные»).
   Открыли секцию → показываем поля, сводка лишняя (CSS-скрытие по .show соседа). */
.lp-doc-summary {
  display: flex; flex-wrap: wrap; gap: .15rem 1.1rem;
  margin-top: .5rem;
  font-size: .82rem; color: var(--bs-secondary-color);
}
.lp-doc-summary b { color: var(--bs-body-color); font-weight: 600; }
#doc-data.show + .lp-doc-summary { display: none; }

/* ── Смета: адаптивная «таблица» позиций (срез 3 «Мобильное ядро») ────────────
   Один набор полей (см. order.html) в двух раскладках. Десктоп — строка CSS-grid
   с колонками как в старой таблице; телефон — та же позиция карточкой: наименование
   во всю ширину, ряд Кол-во·Цена·Вес, примечание, крупная Сумма по правому краю.
   Лечит диагноз 2: боковой скролл на каждой строке сметы на телефоне. */
.lp-items { display: flex; flex-direction: column; gap: .5rem; }
.lp-item { display: grid; gap: .5rem; }
.lp-item .form-control { width: 100%; }
.lp-item-label { font-size: .75rem; color: var(--bs-secondary-color); }

/* Десктоп: колонки Наименование · Кол-во · Цена · Вес · Примечание · Сумма · «×» */
@media (min-width: 768px) {
  .lp-items-head, .lp-item, .lp-items-total {
    grid-template-columns:
      minmax(0, 2fr) 5rem 7rem 5.5rem minmax(0, 1.4fr) 7.5rem 2.5rem;
    gap: .5rem;
    align-items: center;
  }
  .lp-items-head {
    padding: 0 0 .1rem;                       /* без гориз. паддинга — колонки шапки на одной
                                                 вертикали со строками и «Итого» (раздел 7) */
    font-size: .8rem;
    color: var(--bs-secondary-color);
    white-space: nowrap;
  }
  /* На десктопе визуальный ярлык не нужен (есть шапка колонок), но он должен остаться
     ДОСТУПНЫМ именем поля: display:none исключил бы текст из дерева доступности, и
     оборачивающий <label> отдал бы пустое имя (скринридер читал бы «edit text»).
     Прячем sr-only-клипом — текст в дереве доступности остаётся именем input'а. */
  .lp-item-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .lp-item-sum { text-align: right; }
  /* Дышащий отступ над «Итого»: раньше сумма липла к «×» строки выше (владелец 05.07:
     «всё вплотную»). Полоса-разделитель + запас сверху отделяют итог от последней позиции. */
  .lp-items-total { margin-top: .35rem; padding-top: .6rem; border-top: 1px solid var(--bs-border-color); }
  .lp-total-label { grid-column: 1 / 6; text-align: right; font-weight: 600; }
  .lp-total-val { grid-column: 6; text-align: right; font-weight: 600; }
}

/* Телефон: позиция-карточка. Сетка 3 колонки под ряд Кол-во·Цена·Вес; наименование,
   примечание и Сумma — во всю ширину. Поля-ярлыки рядом с каждым полем (шапка скрыта). */
@media (max-width: 767.98px) {
  .lp-item {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-areas:
      "name  name  name"
      "qty   price weight"
      "note  note  note"
      "sum   sum   del";
    border: 1px solid var(--bs-border-color);
    border-radius: .5rem;
    padding: .75rem;
    background: var(--bs-body-bg);
  }
  .lp-item-name { grid-area: name; }
  .lp-item-qty { grid-area: qty; }
  .lp-item-price { grid-area: price; }
  .lp-item-weight { grid-area: weight; }
  .lp-item-note { grid-area: note; }
  .lp-item-sum { grid-area: sum; display: flex; align-items: baseline;
    justify-content: flex-end; gap: .4rem; }
  .lp-item-del { grid-area: del; justify-self: end; align-self: center; }
  /* Ярлык поля — над самим полем */
  .lp-item > label { display: flex; flex-direction: column; }
  .lp-item-label { display: block; margin-bottom: .15rem; }
  /* Тач-цель: числовые поля дефолтом 38px — мимо нормы 44px */
  .lp-item .form-control { min-height: 2.75rem; }
  /* Сумма строки — по правому краю на одной вертикали; мельче итога (иерархия) */
  .lp-item-sum .js-row-sum { font-size: 1rem; font-weight: 600; }
}

/* ── Примерка, «студия» (третья версия формы, 03.07) ──────────────────────────
   Раскладка профессиональных визуализаторов (Roomvo/Floori/IKEA Kreativ):
   слева большой холст с фото места (он же дроп-зона), справа узкая панель шагов
   с изделиями; одна главная кнопка. На телефоне — холст сверху, шаги ниже. */

/* Левая колонка на десктопе липкая: холст виден, пока листаешь изделия справа */
@media (min-width: 992px) {
  .lp-sticky-lg { position: sticky; top: 4.5rem; }
}

/* Холст: пустой — приглашение «положите фото» (дроп-зона на всю площадь),
   с фото — тёмный подиум, снимок целиком (contain), поверх — точка «сюда» */
.lp-canvas {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 15rem;          /* умеренная коробка-дропзона, не гигант на всю ширину */
  border-radius: .75rem;
  overflow: hidden;
}
.lp-canvas.has-photo {
  border: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg);
  padding: 0;
}
.lp-canvas-img-wrap { position: relative; max-width: 100%; }
.lp-canvas img {
  display: block;
  max-width: 100%;
  max-height: 58vh;
  cursor: crosshair;           /* намёк «можно коснуться — поставить точку» */
}
.lp-canvas .lp-canvas-empty { padding: 1.5rem 1rem; }
.lp-canvas.has-photo .lp-canvas-empty { display: none; }
.lp-canvas:not(.has-photo) .lp-canvas-img-wrap { display: none; }

/* Точка «поставить сюда» — красное кольцо, тот же маркер, что уйдёт модели
   (place_marker): человек видит ровно то, что увидит ИИ */
.lp-fit-dot {
  position: absolute;
  width: 22px;
  height: 22px;
  border: 3px solid #e03131;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .6);
}
.lp-fit-dot::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 6px;
  background: #e03131;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

/* Подсказка «перетащить / Ctrl+V» — только на устройстве с указателем (десктоп).
   На телефоне вставки из буфера нет и ведущая кнопка «Снять фото» стоит первой, так
   что подсказка там лишь мешает. Скрываем по умолчанию, показываем при hover-указателе. */
.lp-hover-only { display: none; }
@media (hover: hover) { .lp-hover-only { display: block; } }

/* Липкое мини-превью фото места вверху панели шагов: на телефоне холст уходит вверх за
   экран, а настраивать изделие вслепую нельзя. Только показ (без data-paste — вставку
   Ctrl+V не перехватывает). :not([hidden]) — чтобы атрибут hidden продолжал прятать блок. */
#fit-miniphoto:not([hidden]) { display: flex; align-items: center; gap: .5rem; }
#fit-miniphoto img {
  width: 3rem;
  height: 3rem;
  object-fit: cover;
  border-radius: .375rem;
  border: 1px solid var(--bs-border-color);
}
#fit-miniphoto .lp-mini-cap { font-size: .8rem; color: var(--bs-secondary-color); }
@media (max-width: 767.98px) {
  #fit-miniphoto:not([hidden]) {
    position: sticky;
    top: calc(3.25rem + env(safe-area-inset-top, 0px));
    z-index: 4;
    background: var(--bs-body-bg);
    padding: .35rem 0;
    margin-bottom: .25rem;
  }
}
/* На десктопе холст слева и так липкий (.lp-sticky-lg) — мини-превью там не нужно */
@media (min-width: 768px) { #fit-miniphoto:not([hidden]) { display: none; } }

/* Заголовок шага панели: номер-кружок, название, статус выбора справа */
.lp-step {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin: 1.25rem 0 .5rem;
}
.lp-step:first-child { margin-top: 0; }
.lp-step-n {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  font-size: .8rem;
  font-weight: 600;
  border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
}
.lp-step.is-done .lp-step-n {
  background: var(--lp-accent);
  border-color: var(--lp-accent);
  color: var(--lp-accent-contrast);
}
.lp-step-t { font-weight: 600; }
.lp-step-s {
  font-size: .8rem;
  color: var(--bs-secondary-color);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Чипы категорий — одна прокручиваемая строка, не съедают панель */
.lp-chip-row {
  display: flex;
  gap: .25rem;
  overflow-x: auto;
  white-space: nowrap;
  padding-bottom: .25rem;
}
.lp-chip-row .btn { flex: 0 0 auto; }

/* Дроп-зона (перетащить / Ctrl+V): холст примерки и возврат результата */
.lp-dropzone {
  border: 2px dashed var(--bs-border-color);
  border-radius: .5rem;
  padding: .75rem;
  text-align: center;
  transition: border-color .15s, background-color .15s;
}
.lp-dropzone.is-drag {
  border-color: var(--lp-accent);
  background: var(--bs-tertiary-bg);
}
.lp-dropzone-icon { font-size: 1.6rem; color: var(--bs-secondary-color); }
/* Превью «Готовой картинки»: вставка не должна проходить молча.
   display перебивает d-none только когда класс снят (у d-none !important). */
#fit-result-preview:not(.d-none) {
  display: block;
  max-width: 100%;
  max-height: 180px;
  border-radius: .375rem;
  margin: 0 auto .5rem;
}

/* Лента миниатюр: фото клиента (radio в label) и фото изделия (button + бейдж) */
.lp-thumb-strip {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding: .25rem 0;
}
.lp-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 86px;
  cursor: pointer;
  border: 2px solid var(--bs-border-color);
  border-radius: .375rem;
  padding: 2px;
  background: none;
  text-align: center;
}
.lp-thumb input { position: absolute; opacity: 0; pointer-events: none; }
.lp-thumb img {
  width: 100%;
  height: 64px;
  object-fit: cover;
  border-radius: .25rem;
  display: block;
}
/* Галерея фото ИЗДЕЛИЯ («какие взять»): крупнее и ЦЕЛИКОМ — узор не обрезаем
   (владелец 07.07). Свой модификатор, чтобы миниатюры мест/вариантов остались как были. */
.lp-thumb-ref { width: 116px; }
.lp-thumb-ref img { height: 92px; object-fit: contain; background: var(--bs-tertiary-bg); }
.lp-thumb:has(input:checked), .lp-thumb.is-on { border-color: var(--lp-accent); }
/* Фокус-кольцо на карточках/миниатюрах: настоящие radio скрыты (opacity:0), поэтому фокус
   клавиатуры и экранной лупы был невидим. Рисуем кольцо на обёртке по :focus-visible скрытого
   input — ≥2px, со смещением, акцентом (доступность, раздел 7 редизайна). */
.lp-pick-card:has(input:focus-visible),
.lp-thumb:has(input:focus-visible) {
  outline: 2px solid var(--lp-accent);
  outline-offset: 2px;
}
/* Лента вариантов сцены (страница примерки): те же миниатюры, но ссылками */
a.lp-thumb { display: block; text-decoration: none; color: inherit; }
/* Единая галерея: результат помечен уголком «результат» + акцентная рамка — чтобы в
   одном списке было видно, где фото места, а где результат (у него ещё до/после) */
.lp-thumb.is-result { border-color: var(--lp-accent); }
.lp-thumb-badge {
  position: absolute;
  top: 4px;
  left: 4px;
  font-size: .58rem;
  font-weight: 600;
  line-height: 1;
  padding: .15rem .3rem;
  border-radius: .25rem;
  background: var(--lp-accent);
  color: #1a1d20;
  pointer-events: none;
}

/* Кнопка-лупа в углу миниатюры/карточки: смотреть крупно, не выбирая */
.lp-thumb, .lp-pick-card { position: relative; }
.lp-zoom-btn {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 22px;
  height: 22px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 4px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .75rem;
  opacity: 0;
  transition: opacity .12s;
  cursor: zoom-in;
}
.lp-thumb:hover .lp-zoom-btn, .lp-pick-card:hover .lp-zoom-btn,
.lp-zoom-btn:focus-visible { opacity: 1; }
@media (hover: none) { .lp-zoom-btn { opacity: 1; } }   /* на телефоне ховера нет — всегда видно */

/* «Как получен»: рецепт результата — основа + параметры (только чтение) */
.lp-made {
  border: 1px solid var(--bs-border-color);
  border-radius: .5rem;
  padding: .6rem .75rem;
}
.lp-made-h {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  font-weight: 600;
  color: var(--bs-secondary-color);
  margin-bottom: .45rem;
}
.lp-made-body { display: flex; gap: .75rem; align-items: flex-start; }
.lp-made-place {
  flex: 0 0 auto;
  border: 0;
  background: none;
  padding: 0;
  cursor: zoom-in;
  text-align: center;
}
.lp-made-place img {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: .375rem;
  display: block;
}
.lp-made-cap { font-size: .62rem; color: var(--bs-secondary-color); }
.lp-made-params { margin: 0; font-size: .8rem; min-width: 0; }
.lp-made-params > div { display: flex; gap: .4rem; margin-bottom: .15rem; }
.lp-made-params dt { flex: 0 0 4.5rem; color: var(--bs-secondary-color); font-weight: 500; }
.lp-made-params dd { margin: 0; }

/* Единая галерея картинок клиента: у каждой — ЯВНЫЕ опции (посмотреть / выбрать /
   скопировать / открыть), а не один скрытый клик. Лента с горизонтальным скроллом —
   страница не растёт на сотни картинок (владелец: «нахуя мне страница длиной в километр»). */
.lp-gal {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding: .25rem 0;
}
.lp-gal-item {
  position: relative;
  flex: 0 0 auto;
  width: 116px;
  border: 2px solid var(--bs-border-color);
  border-radius: .375rem;
  padding: 3px;
}
.lp-gal-item.is-result { border-color: var(--lp-accent); }         /* результат — акцентная рамка */
.lp-gal-item.is-on { outline: 2px solid var(--lp-accent); outline-offset: 1px; }  /* показан сейчас */
/* Картинка = ссылка «выбрать основой»: клик по ней ставит фото/результат на холст
   (владелец 06.07: «нахуя мне галочка, я просто нажимаю на фото»). */
.lp-gal-img {
  position: relative;
  display: block;
  cursor: pointer;
  border-radius: .25rem;
  overflow: hidden;
}
.lp-gal-img img {
  width: 100%;
  height: 80px;
  object-fit: cover;
  display: block;
}
.lp-gal-pickhint {                                 /* «выбрать» — проступает на наведении */
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .25rem;
  font-size: .7rem;
  color: #fff;
  background: rgba(0, 0, 0, .45);
  opacity: 0;
  transition: opacity .12s;
}
.lp-gal-img:hover .lp-gal-pickhint,
.lp-gal-img:focus-visible .lp-gal-pickhint { opacity: 1; }
@media (hover: none) { .lp-gal-pickhint { display: none; } }  /* на телефоне тап и так выбирает */
/* Результат отличается ТИХО: маленький значок в углу (владелец 06.07: «зачем обводки и
   подпись — можно чтобы немного выделялось, не перегружать вид»). */
.lp-gal-mark {
  position: absolute;
  top: 3px;
  left: 3px;
  font-size: .7rem;
  line-height: 1;
  padding: .15rem;
  border-radius: .25rem;
  background: rgba(0, 0, 0, .45);
  color: var(--lp-accent);
  pointer-events: none;
}

/* Плитка «добавить» в пуле — ОДНА, с двумя входами в общей рамке (файл | буфер):
   две отдельные плитки под одно действие ели двойное место (владелец 06.07). */
.lp-gal-add { cursor: pointer; }
button.lp-gal-item { background: none; color: inherit; font: inherit; }
.lp-gal-addbox {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80px;
  border: 1px dashed var(--bs-border-color);
  border-radius: .25rem;
  color: var(--bs-secondary-color);
  font-size: 1.1rem;
}
.lp-gal-add:hover .lp-gal-addbox { border-color: var(--lp-accent); }
.lp-gal-addsplit { padding: 0; overflow: hidden; }
.lp-gal-addhalf {
  flex: 1 1 0;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: 0;
  background: none;
  color: inherit;
}
.lp-gal-addhalf + .lp-gal-addhalf { border-left: 1px dashed var(--bs-border-color); }
.lp-gal-addhalf:hover { color: var(--lp-accent); }
.lp-gal-actions { display: flex; gap: 2px; margin-top: 3px; }
.lp-gal-btn {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 26px;
  padding: 0;
  border: 1px solid var(--bs-border-color);
  border-radius: 4px;
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-size: .8rem;
  text-decoration: none;
  cursor: pointer;
}
.lp-gal-btn:hover { border-color: var(--lp-accent); color: var(--lp-accent); }
.lp-gal-del:hover { border-color: var(--bs-danger); color: var(--bs-danger); }  /* удалить — красным */
.lp-gal-cap {
  display: block;
  margin-top: 2px;
  font-size: .65rem;
  text-align: center;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Блок «изделия нет в каталоге» — свои фото + параметры, один понятный вход */
.lp-own {
  border: 1px dashed var(--bs-border-color);
  border-radius: .5rem;
  padding: .6rem .75rem;
}

/* Рецепт результата — карточка-«окошко» поверх страницы (внутри лайтбокс-подложки) */
.lp-recipe-card {
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  border-radius: .6rem;
  width: min(680px, 100%);
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, .5);
}
.lp-recipe-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .7rem .9rem;
  border-bottom: 1px solid var(--bs-border-color);
  position: sticky;
  top: 0;
  background: var(--bs-body-bg);
}
.lp-recipe-body { padding: .8rem .9rem; }
.lp-recipe-prompt {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: .75rem;
  background: var(--bs-tertiary-bg);
  border-radius: .375rem;
  padding: .6rem .7rem;
  margin: .3rem 0 0;
  max-height: 40vh;
  overflow-y: auto;
}
/* Крупный просмотр ИЗ рецепта: лайтбокс ПОВЕРХ окошка, не за ним (владелец 06.07:
   «фото открываются за окошком, приходится его закрывать») */
#fit-lightbox { z-index: 1100; }

/* Лайтбокс: крупный просмотр картинки поверх страницы */
.lp-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1080;
  background: rgba(0, 0, 0, .85);
  /* если что-то и лайтбокс, и рецепт открыты — см. правило #fit-lightbox ниже */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3.5rem 1rem 1rem;
}
.lp-lightbox img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: .375rem;
}
.lp-lightbox-bar {
  position: absolute;
  top: .6rem;
  right: .6rem;
  display: flex;
  gap: .4rem;
}
.lp-thumb-cap {
  display: block;
  font-size: .65rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Номер порядка выбора фото изделия («1 · эталон», «2»…) */
.lp-order-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  background: var(--lp-accent);
  color: var(--lp-accent-contrast);
  border-radius: 999px;
  font-size: .65rem;
  font-weight: 600;
  padding: 0 .4rem;
  line-height: 1.5;
}

/* Сетка карточек изделий: radio + label. На десктопе — ВНУТРЕННЯЯ прокрутка
   фиксированной высоты: страница не растёт от числа изделий (владелец 06.07:
   «список разрастается до бесконечности, страница длиной в километр»).
   На телефоне вложенный скролл снят ниже — там длину держит кэп «Показать ещё». */
.lp-pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));   /* крупные плитки — видно узор */
  gap: .5rem;
  border: 1px solid var(--bs-border-color);
  border-radius: .5rem;
  padding: .5rem;
  max-height: 56vh;
  overflow-y: auto;
}
/* Категории — переносом на десктопе (не горизонтальный скролл с обрезкой «Очаги и манг…») */
@media (min-width: 768px) {
  #fit-pick-cats, #cat-pick-cats { flex-wrap: wrap; overflow-x: visible; }
}
/* Карточка изделия как <button> (модалка сметы заказа): убрать родной вид кнопки —
   вид задаёт общий .lp-pick-card, как у label-карточек примерки. */
button.lp-pick-card { font: inherit; color: inherit; }
.lp-pick-card {
  position: relative;
  border: 1px solid var(--bs-border-color);
  background: var(--bs-secondary-bg);
  border-radius: 10px;
  padding: .25rem;
  cursor: pointer;
  text-align: center;
}
.lp-pick-card:hover { border-color: var(--bs-secondary-color); }
.lp-pick-card input { position: absolute; opacity: 0; pointer-events: none; }
/* :has — основной путь; .is-checked дублирует его из JS для старых браузеров */
.lp-pick-card:has(input:checked), .lp-pick-card.is-checked {
  border-color: var(--lp-accent);
}
.lp-pick-card img,
.lp-pick-noimg {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;          /* изделие видно целиком, не обрезано */
  border-radius: .25rem;
  display: block;
  background: var(--bs-tertiary-bg);
}
.lp-pick-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg);
}
.lp-pick-name {
  display: block;
  font-size: .7rem;
  line-height: 1.2;
  margin-top: .25rem;
  max-height: 2.4em;
  overflow: hidden;
}
/* Размер — одной строкой (полный текст в title карточки): выбор идёт по картинкам,
   а «Высота …; Ширина …; Диаметр …» на 3–4 строки превращали сетку в простыню */
.lp-pick-size {
  display: block;
  font-size: .65rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Результат: выбранное изделие компактной строкой, полный пикер — по кнопке «Сменить» */
.lp-pick-cur {
  display: flex;
  align-items: center;
  gap: .5rem;
  border: 1px solid var(--bs-border-color);
  border-radius: .5rem;
  padding: .35rem .5rem;
}
.lp-pick-cur > div { min-width: 0; }   /* иначе text-truncate внутри flex не работает */
.lp-pick-cur img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: .375rem;
  background: var(--bs-tertiary-bg);
  flex-shrink: 0;
}

/* Кнопки запуска примерки: на телефоне липнут над нижней панелью (всегда под пальцем) */
@media (max-width: 767.98px) {
  .lp-fit-actions {
    position: sticky;
    bottom: calc(3.8rem + env(safe-area-inset-bottom));
    background: var(--bs-body-bg);
    padding: .5rem 0;
    z-index: 5;
  }
}

/* Результат примерки: шторка «до/после» (фирменный приём визуализаторов).
   Низ — результат («после»), поверх — фото места («до»), обрезанное по --pos;
   двигает невидимый range на всю площадь (мышь, палец и стрелки клавиатуры).
   Без JS --pos = 0% — виден просто результат, ничего не ломается. */
.lp-ba {
  --pos: 0%;
  position: relative;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  border-radius: .75rem;
  border: 1px solid var(--bs-border-color);
}
.lp-ba > img { display: block; max-width: 100%; max-height: 68vh; }
.lp-ba-before {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}
.lp-ba-handle {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 2px;
  margin-left: -1px;
  background: #fff;
  box-shadow: 0 0 6px rgba(0, 0, 0, .55);
  pointer-events: none;
}
.lp-ba-handle::after {
  content: "\2194";              /* ↔ на кружке-ручке */
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #fff;
  color: #1a1d20;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
}
.lp-ba-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  /* Вертикальный свайп скроллит страницу (шторка не крадёт его на телефоне), горизонтальное
     перетаскивание всё ещё двигает «до/после». */
  touch-action: pan-y;
}
.lp-ba-tag {
  display: none;
  position: absolute;
  top: .5rem;
  padding: .1rem .5rem;
  border-radius: 999px;
  font-size: .7rem;
  font-weight: 600;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  pointer-events: none;
}
.lp-ba-tag-before { left: .5rem; }
.lp-ba-tag-after { right: .5rem; }
.lp-ba.is-active .lp-ba-handle, .lp-ba.is-active .lp-ba-tag { display: block; }

/* Режим правки точки «изделие сюда» поверх результата: шторка «до/после» замирает
   (range перестаёт ловить указатель), клик уходит на картинку — ставит точку. Курсор-
   прицел подсказывает, что можно коснуться. Выход из режима возвращает шторку (JS). */
.lp-ba.is-editing { cursor: crosshair; }
.lp-ba.is-editing .lp-ba-range { pointer-events: none; }

/* Карточка результата в разделе «Примерка» */
.lp-fit-cover { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

/* Старт примерки/заказа: клиента выбирают на странице «Клиенты» (?pick=…) — свой
   список .lp-client расформирован как дубль (владелец 05.07/06.07). */
/* На телефоне вложенный скролл сетки изделий — ловушка: палец не попадает, где скроллить.
   Снимаем, листается страница целиком; длину держит фильтр (и «показать ещё» — часть 2). */
@media (max-width: 767.98px) {
  .lp-pick-grid { max-height: none; overflow: visible; }
}

/* Оверлей долгой генерации: платный вызов на 15–40 секунд не должен выглядеть
   как зависшая страница (принцип 4 редизайна — процесс виден) */
.lp-busy {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  text-align: center;
  padding: 1rem;
  background: color-mix(in srgb, var(--bs-body-bg) 82%, transparent);
  backdrop-filter: blur(2px);
}
