/* DESKTOP STYLES — 3-column layout for configurator */
* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
/* Скругления по макету: R=4 у всего, кроме карточек — они остаются прямоугольными
   (см. .d-house-card / .d-mat-card ниже). Селектор * имеет нулевую специфичность,
   поэтому любое явное правило — круги 50%, прямые углы карточек — его перекрывает. */
*, *::before, *::after { border-radius: var(--r); }
/* Панели и окна — прямоугольные, скругляются только контролы. У .d-center-view
   скругление было заметно: она обрезает 3D по overflow, и углы вида срезались. */
.d-sidebar, .d-panel, .d-3d-container, .d-center-canvas,
.d-center-view, .d-center-3d, .d-center-3d canvas, .d-3d-container canvas,
.d-summary-box, .d-3d-loading, #d-toast { border-radius: 0; }

/* Полоса прокрутки: серая линия 2px по центру жёлоба, оранжевый движок 4px. */
* { scrollbar-width: thin; scrollbar-color: var(--accent) transparent; }
*::-webkit-scrollbar { width: 4px; height: 4px; }
*::-webkit-scrollbar-track {
  background: linear-gradient(to right, transparent 1px, var(--border) 1px 3px, transparent 3px);
}
*::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 0; }
*::-webkit-scrollbar-corner { background: transparent; }
:root {
  --bg: #fff;
  --card: #d9d9d9;
  --card-hover: #ccc;
  --text: #000;
  --r: 4px;
  /* Кнопки по макету: первичная — оранжевая с белой надписью; второстепенная —
     белая с обводкой 2px; неактивная — серый фон с тёмно-серой надписью. */
  --btn-border: #e0e0e0;
  --btn-off-bg: #f8f8f8;
  --btn-off-text: #999999;
  --radio-off-border: #d9d9d9;
  /* Реакция на наведение у белых кнопок и карточек. */
  --hover-shadow: 0 0 4px 4px rgba(0,0,0,.12);
  /* Акцент кнопок действий (бывшая чёрная заливка). Тот же цвет — выбранная
     карточка дома в макете Figma. */
  --accent: #f2722c;
  --accent-hover: #f48549;
  /* Токены из Figma-макета: рамки и фоны карточек первого экрана. */
  --separator: #c6c6c8;  /* Separators/Opaque — рамка карточки дома */
  --gray: #8e8e93;       /* Grays/Gray — рамка карточки «Участок без дома» */
  --center-bg: #f0f0f0;  /* color/center-bg — фон карточки загрузки фото */
  --center-bg-hover: #e8e8e8;
  --border: #e0e0e0;     /* color/border */
  /* Ширина левой панели = ширина заголовка + 32px с каждой стороны. Значение
     подставляет _dSyncSidebarWidth (nav-desktop.js) по РЕАЛЬНЫМ метрикам шрифта:
     Segoe UI на машине пользователя и запасной шрифт в другом окружении дают
     разную ширину, а «на глаз» пришлось бы закладывать запас. Здесь — фолбэк,
     если скрипт почему-то не отработал. */
  --sidebar-w: 364px;
  --panel-w: 364px;          /* правая панель той же ширины, что левая */
  --panel-title-fz: 28px;    /* кегль заголовка раздела: подбирается под ширину */
  --header-h: 48px;          /* высота хедера; на неё опущены все экраны */
}
/* Шрифт интерфейса — Segoe UI (как в макетах Figma). Roboto оставлен запасным
   вариантом для систем без Segoe UI. Подписи на canvas используют UI_FONT
   из canvas.js — держать оба списка согласованными. */
body { font-family:'Segoe UI',system-ui,Roboto,sans-serif; background:#e0e0e0; min-height:100vh; overflow:hidden; }
/* Кнопки и поля ввода шрифт от body НЕ наследуют — браузер подставляет им свой
   системный. Из-за этого надписи на кнопках рисовались не Segoe UI (TODO п.1). */
button, input, select, textarea { font-family: inherit; }

/* ═══════════════════════════════════════════
   КНОПКА «СМЕТА» (низ правой панели)
   ═══════════════════════════════════════════ */
/* «СМЕТА» — во всю ширину внизу правой панели (была плавающей в углу экрана). */
.d-fab-summary {
  width: 100%; height: 40px; background: var(--accent); color: #fff;
  border: none; border-radius: var(--r);
  font-size: 22px; font-weight: 600; line-height: 1; cursor: pointer;
  transition: background .15s;
}
.d-fab-summary:hover { background: var(--accent-hover); }

/* ═══════════════════════════════════════════
   ХЕДЕР — общий для всех экранов
   ═══════════════════════════════════════════ */
/* Заголовок приложения на два пункта крупнее заголовка панели («Благоустройство»,
   --panel-title-fz). Кнопка «На главную» — как второстепенные кнопки левой панели:
   белая с серой обводкой. Ссылка открывается в новой вкладке, чтобы не потерять
   настроенный проект. */
.d-header {
  position: fixed; top: 0; left: 0; right: 0; height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 20px; z-index: 50;
  background: var(--bg); border-bottom: 1px solid var(--border);
}
.d-header-title {
  font-size: calc(var(--panel-title-fz, 25px) + 2px); font-weight: 400;
  color: var(--text); white-space: nowrap;
}
.d-header-home {
  flex: 0 0 auto; height: 34px; padding: 0 16px; font-size: 15px;
  display: inline-flex; align-items: center; text-decoration: none;
}

/* ═══════════════════════════════════════════
   SCREENS SYSTEM
   ═══════════════════════════════════════════ */
.d-screen { display: none; position: fixed; top: var(--header-h); left: 0; right: 0; bottom: 0; }
.d-screen.active { display: flex; animation: dIn .25s ease; }
@keyframes dIn { from{opacity:0} to{opacity:1} }

/* ═══════════════════════════════════════════
   STEP 1 — HOUSE TYPE (fullscreen grid)
   ═══════════════════════════════════════════ */
/* Контент выровнен по левому краю, вертикальные интервалы — общий gap 17px
   (по макету Figma «01 — Выбор типа дома»). */
.d-select-wrap {
  flex: 1; display: flex; flex-direction: column; align-items: flex-start;
  gap: 17px; padding: 32px 80px 32px 120px; background: var(--bg); overflow: hidden;
}
.d-select-title { font-size: 36px; font-weight: 400; flex-shrink: 0; }
.d-select-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px; max-width: 1100px; width: 100%;
}
/* Сетка 5 карточек в ряд, вертикальный скролл. Карточки стыкуются без зазоров:
   отрицательные margin'ы схлопывают рамки соседей в одну линию 1px, а padding
   возвращает её по внешним краям сетки. */
.d-house-grid {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0; width: 100%; max-width: 1200px;
  overflow-y: auto; padding: 0 1px 1px 0;
  align-content: start; min-height: 0;
}
.d-house-grid .d-house-card .preview-img {
  width: 100%; height: 100%; display: block; object-fit: cover;
}
@keyframes d-spin { to { transform: rotate(360deg); } }
/* Общий прогресс-каунтер над сеткой. */
.d-house-progress {
  font-size: 16px; color: #888; font-weight: 400;
  min-height: 20px; flex-shrink: 0;
  transition: opacity 0.3s;
}
.d-house-progress.done { opacity: 0; pointer-events: none; }
/* Initial loading state в области сетки (виден до выполнения JS, на ~5 сек загрузки скриптов). */
.d-grid-initial-loading {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; min-height: 360px;
  color: #777; font-size: 15px; font-weight: 400;
}
.d-loading-spinner {
  width: 40px; height: 40px;
  border: 4px solid #e0e0e0; border-top-color: #666; border-radius: 50%;
  animation: d-spin 0.9s linear infinite;
}
/* Карточка дома 240×180: белый фон, рамка 1px, подпись поверх превью снизу слева.
   Углы прямые — карточки единственное, что не скругляется (см. правило * выше). */
.d-house-card {
  position: relative; height: 180px; background: var(--bg); border-radius: 0;
  border: 1px solid var(--separator); margin: 0 -1px -1px 0;
  cursor: pointer; overflow: hidden;
  transition: border-color .2s, box-shadow .2s;
}
/* Наведение: мягкая тень по контуру, без подъёма карточки. z-index нужен, чтобы
   тень не закрашивалась белым фоном соседних карточек (они стыкуются вплотную). */
.d-house-card:hover { z-index: 1; box-shadow: 0 0 4px 4px rgba(0,0,0,.12); }
/* Выбранная: контур 3px акцентным цветом = рамка 1px + внутренняя тень 2px.
   Через box-shadow, а не border-width, чтобы содержимое не смещалось на 2px. */
.d-house-card.selected {
  z-index: 2; border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent);
}
.d-house-card.selected .hcl,
.d-house-card.selected .hcl-sub { color: var(--accent); }
/* Превью занимает всю карточку; подпись лежит поверх него. */
.d-house-card .hcp {
  position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; overflow: hidden;
}
/* Плейсхолдер до готовности 3D-рендера: белый фон и подпись, без спиннера. */
.d-house-card .hcp .hc-ph { font-size: 16px; color: #bbb; }
.d-house-card .hcl {
  position: absolute; left: 16px; right: 16px; bottom: 12px;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 20px; font-weight: 600; line-height: 20px; color: var(--text);
}
.d-house-card .hcl-sub {
  font-size: 14px; font-weight: 400; line-height: 20px; color: rgba(0,0,0,.75);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Ряд под сеткой: «Участок без дома» + загрузка фото, две карточки 240px вплотную. */
.d-house-extra { display: flex; gap: 0; flex-shrink: 0; }
/* Кнопка «Дальше» на экране выбора дома — появляется только когда дом уже выбран
   (пользователь вернулся на первый экран). См. _dSyncSelectNext в nav-desktop.js. */
/* Кнопка стандартного размера, у нижнего края карточки «Участок без дома». */
.d-select-actions { display: none; flex-shrink: 0; align-items: flex-end; margin-left: 24px; }
.d-select-actions.active { display: flex; }
.d-select-actions .d-btn {
  height: 48px; min-width: 180px; padding: 0 24px;
  border-radius: var(--r); font-size: 18px; cursor: pointer;
  transition: background .15s, box-shadow .2s;
}
.d-house-card-empty {
  position: relative; flex: 0 0 240px; height: 180px; background: var(--bg);
  border-radius: 0; border: 1px solid var(--gray); cursor: pointer; overflow: hidden;
  transition: border-color .2s, box-shadow .2s;
}
.d-house-card-empty:hover { z-index: 1; box-shadow: 0 0 4px 4px rgba(0,0,0,.12); }
.d-house-card-empty.selected {
  z-index: 2; border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent);
}
.d-house-card-empty.selected .hcl { color: var(--accent); }
/* Отступ снизу оставляет место подписи, лежащей поверх этой области. */
.d-house-card-empty .hcp {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px;
  padding: 16px 16px 58px; color: #bbb; font-size: 16px; text-align: center;
}
.d-house-card-empty .hcp .ic { font-size: 36px; opacity: .3; }
.d-house-card-empty .hcl {
  position: absolute; left: 16px; right: 16px; bottom: 12px;
  font-size: 20px; font-weight: 600; line-height: 20px; color: var(--text);
}
.d-upload-card {
  position: relative; flex: 0 0 240px; height: 180px; border-radius: 0;
  background: var(--center-bg); border: 1px solid var(--border);
  cursor: pointer; overflow: hidden; transition: background .2s;
}
.d-upload-card:hover { background: var(--center-bg-hover); }
.d-upload-card span {
  position: absolute; left: 16px; right: 16px; bottom: 12px;
  font-size: 20px; font-weight: 600; line-height: 20px; color: var(--text);
}
#d-upload-input { display: none; }
.d-select-next {
  margin-top: 32px; height: 56px; min-width: 240px; padding: 0 32px;
  background: var(--accent); color: #fff; border: none; border-radius: var(--r);
  font-size: 20px; font-weight: 700; letter-spacing: .04em;
  cursor: pointer; transition: background .15s, transform .1s;
  display: flex; align-items: center; justify-content: center; gap: 12px;
}
.d-select-next:hover { background: var(--accent-hover); }
.d-select-next:active { transform: scale(.98); }

/* ═══════════════════════════════════════════
   STEP 2 — PARAMS + 3D (center)
   ═══════════════════════════════════════════ */
.d-params-layout { flex: 1; display: flex; background: var(--bg); }
.d-params-left {
  width: var(--sidebar-w); padding: 12px 20px 14px; border-right: 1px solid #e0e0e0;
  display: flex; flex-direction: column; gap: 0;
  overflow: hidden;
}
/* Заголовки левой панели — тем же кеглем, что заголовок правой (--panel-title-fz),
   его подбирает _dSyncSidebarWidth (правка 2026-09-03). */
.d-params-title {
  font-size: var(--panel-title-fz, 25px); font-weight: 400;
  margin-bottom: 12px; flex: none;
}
/* Заголовок и кнопки «Назад/Дальше» приколочены; скроллится только этот блок. */
/* Отступ сверху — чтобы первый слайдер не упирался в кромку скролла и не
   срезался; по бокам 2px с компенсацией margin’ом: тень бегунка в крайних
   положениях выходит за дорожку, а ширина содержимого остаётся прежней. */
.d-params-scroll {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 8px 2px 0; margin: 0 -2px;
}
/* ── Слайдер параметра ──
   По макету: подпись слева, поле значения 44×44 справа, ниже дорожка 2px с
   оранжевой заливкой слева от бегунка, под ней — границы диапазона.
   Используется и в параметрах дома, и в настройках элементов в редакторах. */
.d-param-group { margin-bottom: 14px; }
.d-floor-title { font-size: 15px; font-weight: 600; margin-bottom: 8px; }
.d-param-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.d-param-label { font-size: 16px; font-weight: 400; color: #999; }
.d-param-input {
  width: 44px; height: 44px; flex-shrink: 0;
  background: var(--btn-off-bg); border: 1px solid var(--btn-border); border-radius: var(--r);
  text-align: center; font-size: 18px; font-weight: 600; color: var(--text);
  outline: none; transition: border-color .15s; -moz-appearance: textfield;
}
.d-param-input::-webkit-outer-spin-button,
.d-param-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.d-param-input:focus { border-color: var(--accent); }
/* Границы диапазона: минимум слева, максимум справа. */
.d-param-unit {
  display: flex; justify-content: space-between;
  font-size: 16px; font-weight: 400; color: #999; margin-top: 8px;
}
/* Заливку слева от бегунка нативный range не умеет — долю считает
   _dSyncRangeFill (nav-desktop.js) и кладёт в --fill. */
.d-param-range {
  --fill: 0%;
  width: 100%; height: 24px; margin: 14px 0 0; padding: 0;
  background: none; -webkit-appearance: none; appearance: none; cursor: pointer;
}
.d-param-range::-webkit-slider-runnable-track {
  height: 2px;
  background: linear-gradient(to right, var(--accent) var(--fill), var(--border) var(--fill));
}
.d-param-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 24px; height: 24px; margin-top: -11px; border: none; border-radius: 50%;
  background: radial-gradient(circle at center, var(--accent) 0 4px, #fff 4px);
  box-shadow: 0 0 6px 2px rgba(0,0,0,.25);
}
.d-param-range::-moz-range-track { height: 2px; background: var(--border); }
.d-param-range::-moz-range-progress { height: 2px; background: var(--accent); }
.d-param-range::-moz-range-thumb {
  width: 24px; height: 24px; border: none; border-radius: 50%;
  background: radial-gradient(circle at center, var(--accent) 0 4px, #fff 4px);
  box-shadow: 0 0 6px 2px rgba(0,0,0,.25);
}
/* 3D-вид занимает всю правую часть: рамки вокруг него по макету нет, поэтому
   ни отступа, ни отдельного фона у контейнера. */
.d-params-center {
  flex: 1; display: flex; align-items: stretch; justify-content: center;
  padding: 0; background: var(--bg); position: relative;
}
.d-3d-container {
  flex: 1; background: var(--bg);
  position: relative; overflow: hidden; cursor: grab; touch-action: none;
}

/* .d-3d-hint — подсказка активного раздела над сценой (см. ниже). Подсказка по
   УПРАВЛЕНИЮ ВИДОМ отдельная: всплывающее окно один раз при первом запуске
   (dShow3dHint). */
/* Материалы дома — квадратные образцы (крыша/фундамент/стены) */
.d-hm-group { margin-bottom: 16px; }
.d-hm-label { font-size: 16px; font-weight: 400; color: #999; margin-bottom: 8px; }
.d-hm-row { display: flex; gap: 8px; flex-wrap: wrap; }
.d-hm-sw {
  width: 46px; height: 46px; padding: 0; cursor: pointer;
  border: 2px solid #ccc; background-size: cover; background-position: center;
  transition: border-color .15s, box-shadow .15s;
}
.d-hm-sw:hover { border-color: #888; }
.d-hm-sw.active { border-color: #000; box-shadow: 0 0 0 2px #000 inset; }

.d-params-actions {
  display: flex; gap: 8px; flex: none; padding-top: 14px;
}
/* Обводку задаёт вариант кнопки (.d-btn-back / .d-btn-next), поэтому здесь
   border не сбрасываем — иначе он перебивает вариант по специфичности. */
.d-params-actions .d-btn {
  flex: 1; height: 38px; border-radius: var(--r);
  font-size: 15px; cursor: pointer; transition: background .15s, box-shadow .2s;
}
/* Второстепенная кнопка: белая, обводка 2px, надпись Semibold. */
.d-btn-back {
  background: var(--bg); color: var(--text);
  border: 2px solid var(--btn-border); font-weight: 600;
}
.d-btn-back:hover { box-shadow: var(--hover-shadow); }
/* Первичная кнопка: оранжевая заливка, белая надпись Bold. Обводка в цвет
   заливки — чтобы внутренняя коробка совпадала со второстепенной кнопкой. */
.d-btn-next {
  background: var(--accent); color: #fff; font-weight: 700;
  border: 2px solid var(--accent);
}
.d-btn-next:hover { background: var(--accent-hover); }
/* Неактивная: серый фон, тёмно-серая надпись. */
.d-btn:disabled, .d-btn.locked {
  background: var(--btn-off-bg); color: var(--btn-off-text);
  border-color: var(--btn-border); box-shadow: none;
  cursor: not-allowed; pointer-events: none;
}

/* ═══════════════════════════════════════════
   STEP 3 — WORKSPACE (left + center + right)
   ═══════════════════════════════════════════ */
.d-workspace { flex: 1; display: flex; background: var(--bg); }

/* LEFT SIDEBAR — button menu */
/* Заголовок и кнопки «Назад/Дальше» приколочены, скроллится только список
   элементов: с раскрытым аккордеоном содержимое перестаёт помещаться. */
.d-sidebar {
  width: var(--sidebar-w); border-right: 1px solid #e0e0e0;
  display: flex; flex-direction: column; overflow: hidden;
}
/* Заголовки экранов — единый кегль с заголовком правой панели (--panel-title-fz). */
.d-sidebar-title {
  font-size: var(--panel-title-fz, 25px); font-weight: 400; color: var(--text);
  padding: 12px 20px 8px;    /* по этим 20px (SIDEBAR_PAD) считается ширина панели */
}
.d-sidebar-list {
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px; padding: 0 8px;
}
/* Кнопки правки и удаления стоят справа от кнопки элемента и выравниваются
   по её верхнему краю (в аккордеоне под кнопкой раскрываются настройки). */
.d-sb-row { display: flex; gap: 2px; align-items: flex-start; }
.d-sb-btn {
  width: 100%; height: 38px; background: var(--bg); border: 2px solid var(--btn-border);
  border-radius: var(--r); font-size: 15px; font-weight: 600; cursor: pointer;
  /* Подпись строго в одну строку (TODO п.5): ширину панели под самую длинную
     («Ограждения террасы») считает _dSyncSidebarWidth. */
  text-align: left; padding: 0 12px; white-space: nowrap;
  transition: border-color .2s, box-shadow .2s, background .15s;
  user-select: none;
}
.d-sb-btn:hover:not(:disabled) { box-shadow: var(--hover-shadow); }
/* Выбранный пункт меню: белый фон, оранжевая обводка и надпись. */
.d-sb-btn.active {
  border-color: var(--accent); color: var(--accent); font-weight: 700;
}
/* Галочка «настроено» больше не нужна: у настроенного элемента появляются
   кнопки правки и удаления справа (.d-sb-edit / .d-sb-delete). */
.d-sb-btn.configured { position: relative; }
/* Пока какой-то раздел раскрыт, остальные приглушены (TODO п.3): фон серее белого,
   надпись тусклее. Кнопка при этом рабочая — в отличие от .locked. */
.d-sb-btn.dimmed {
  background: #ededed; color: #6b6b6b; border-color: #dcdcdc;
}
.d-sb-btn.dimmed:hover:not(:disabled) { background: var(--bg); color: var(--text); }
.d-sb-btn.locked, .d-sb-btn:disabled {
  background: var(--btn-off-bg); color: var(--btn-off-text);
  border-color: var(--btn-border); box-shadow: none;
  cursor: not-allowed; pointer-events: none;
}
/* Настроенный раздел правится ОДНОЙ кнопкой «Изменить» справа от его кнопки
   (TODO.md, этап 2 п.2). Квадратов с иконками правки и удаления больше нет:
   сброс раздела делает кнопка «Удалить всё» внутри самого редактора. */
.d-sb-edit {
  height: 38px; flex-shrink: 0; padding: 0 12px; background: var(--accent);
  border: none; border-radius: var(--r); cursor: pointer;
  color: #fff; font-size: 14px; font-weight: 600; white-space: nowrap;
  transition: background .15s;
}
.d-sb-edit:hover:not(:disabled) { background: var(--accent-hover); }
.d-sb-edit.locked, .d-sb-edit:disabled {
  background: var(--btn-off-bg); color: var(--btn-off-text);
  cursor: not-allowed; pointer-events: none;
}

.d-sidebar-divider { height: 1px; background: #e8e8e8; margin: 8px 20px; }
/* ── Аккордеон редактора в левой панели ──
   Открытый раздел — одна колонка во всю ширину панели: кнопка раздела, под ней
   кнопки действий, под ними настройки (слайдеры, переключатели). Кнопка
   подтверждения уходит вниз панели рядом с «Назад». Узлы переносятся из футера
   редактора (_dMountEditorControls). Раньше кнопки действий стояли колонкой
   СПРАВА и укорачивали кнопку раздела, а слайдеры зажимались в остаток ширины
   (TODO пп.4, 5). */
.d-sb-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Панель активного раздела: параметры (слайдеры, тумблеры), под ними кнопки
   действий — столбиком во всю ширину, чтобы подписи не переносились. */
.d-sb-accordion { padding: 10px 2px 4px; }
.d-sb-accordion:empty { display: none; }
.d-sb-accordion .d-param-group:last-child { margin-bottom: 0; }
.d-sb-accordion .tg:last-child { margin-bottom: 0; }
.d-sb-accordion .d-canvas-actions {
  display: flex; flex-direction: column; gap: 4px; padding-top: 6px;
}
.d-sb-accordion .d-canvas-btn { width: 100%; height: 38px; font-size: 15px; white-space: nowrap; }
/* Специфические фильтры раздела с правки 2026-10-04 — в правой панели (.d-filters-box). */
/* Справочная строка раздела (например «Высота забора: 1920 мм»). */
.d-param-note { font-size: 14px; color: var(--muted, #666); padding: 2px 2px 6px; }
.d-sidebar-actions { display: flex; gap: 8px; padding: 10px 12px; flex-shrink: 0; }
.d-sidebar-actions .d-btn { flex: 1; height: 38px; font-size: 15px; }
.d-sidebar-actions .d-btn.hidden { display: none; }

/* CENTER — 3D / Canvas editor */
.d-center {
  flex: 1; display: flex; flex-direction: column; background: #f0f0f0;
  position: relative; min-width: 0;
}
.d-center-view {
  flex: 1; position: relative; overflow: hidden;
}
.d-center-3d {
  position: absolute; inset: 0; cursor: grab; touch-action: none;
}
/* Подсказка активного раздела: белая непрозрачная плашка в левом верхнем углу
   вида, видна всё время, пока раздел открыт (раньше так же висела над планом).
   Кликов не ловит — под ней идёт выбор объектов. */
.d-3d-hint {
  position: absolute; top: 20px; left: 24px; z-index: 21;
  max-width: 440px; padding: 12px 16px;
  background: var(--bg); color: var(--text);
  font-size: 15px; font-weight: 400; line-height: 1.35;
  box-shadow: 0 2px 12px rgba(0,0,0,.12);
  pointer-events: none;
}
.d-3d-hint:empty { display: none; }

/* Оверлей размеров и площадей: HTML-плашки поверх сцены, позиции пересчитывает
   editor3d.js каждый кадр. Кликов не ловит — иначе перекрывал бы выбор объектов. */
.d-3d-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 20; }
.d-3d-dim {
  position: absolute; transform: translate(-50%, -50%);
  padding: 2px 7px; background: rgba(255,255,255,.92);
  border: 1px solid rgba(0,0,0,.12); border-radius: 3px;
  font-size: 13px; font-weight: 600; color: #333; white-space: nowrap;
}
/* Индикатор загрузки 3D-моделей (мебель из каталога — файлы 4–12 МБ).
   Поверх 3D-вида и открытого редактора; показывается через d3dLoadingSet(). */
.d-3d-loading {
  position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%);
  display: none; flex-direction: column; align-items: center; gap: 8px;
  padding: 12px 18px; background: rgba(255,255,255,.94);
  border: 1px solid #e0e0e0; box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 30; pointer-events: none;
}
.d-3d-loading.on { display: flex; }
.d-3d-loading-bar { width: 200px; height: 3px; background: #e3e3e3; position: relative; overflow: hidden; }
.d-3d-loading-fill { position: absolute; top: 0; left: 0; height: 100%; width: 0; background: #555; transition: width .15s linear; }
/* Размер файла неизвестен (нет Content-Length) — бегущая полоса вместо процентов. */
.d-3d-loading-bar.indet .d-3d-loading-fill { width: 40%; animation: dcatbar 1s linear infinite; transition: none; }
.d-3d-loading-txt { font-size: 12px; color: #555; white-space: nowrap; }

/* Canvas editor overlay (hidden by default) */
.d-center-canvas {
  position: absolute; inset: 0; display: none;
  background: var(--bg); flex-direction: column;
}
.d-center-canvas.active { display: flex; }
/* Инструкция редактора — в левом верхнем углу поверх плана, на БЕЛОЙ непрозрачной
   плашке (TODO.md, этап 1 п.16): поверх сетки плана текст без подложки читался плохо.
   Заголовка у редактора нет, только текст подсказки. */
.d-canvas-header {
  position: absolute; top: 0; left: 0; z-index: 2;
  padding: 20px 24px; pointer-events: none;
}
.d-canvas-title { display: none; }
.d-canvas-hint {
  padding: 12px 16px; background: var(--bg);
  font-size: 16px; font-weight: 400; color: var(--text);
  line-height: 1.35; max-width: 440px;
}
/* Короткое сообщение (dToast): белая непрозрачная плашка, как остальные подсказки,
   по центру внизу рабочей области.
   Правило одно и на id: раньше рядом жил ещё блок #d-toast (тёмная плашка вверху),
   он выигрывал по специфичности и вместе с этим давал элементу И top, И bottom —
   плашка растягивалась узкой полосой во всю высоту окна. А #d-toast.show ставил ей
   pointer-events: auto, и сообщение на 2.6 с перехватывало клики по 3D-сцене:
   после отказа («ближе 3 м к дому забор не ставится») следующий клик не доходил
   до сцены. Кликов плашка не ловит НИКОГДА. */
#d-toast {
  position: fixed; left: 50%; bottom: 40px; transform: translateX(-50%);
  z-index: 9999; padding: 12px 20px; background: var(--bg); color: var(--text);
  font-size: 16px; line-height: 1.35; max-width: 560px; text-align: center;
  box-shadow: 0 2px 12px rgba(0,0,0,.22);
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
#d-toast.show { opacity: 1; }

.d-canvas-actions { display: flex; gap: 8px; }
/* Кнопки действий редактора — в правый нижний угол (в футере, прижаты вправо). */
.d-canvas-footer .d-canvas-actions { margin-left: auto; }
.d-canvas-btn {
  height: 40px; padding: 0 16px; background: var(--bg);
  border: 2px solid var(--btn-border); border-radius: var(--r);
  font-size: 16px; font-weight: 600; cursor: pointer;
  transition: box-shadow .2s, background .15s;
}
.d-canvas-btn:hover { box-shadow: var(--hover-shadow); }
.d-canvas-btn.confirm {
  background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 700;
}
.d-canvas-btn.confirm:hover {
  background: var(--accent-hover); border-color: var(--accent-hover); box-shadow: none;
}
.d-canvas-btn:disabled {
  background: var(--btn-off-bg); color: var(--btn-off-text);
  border-color: var(--btn-border); box-shadow: none;
  cursor: not-allowed; pointer-events: none;
}
/* Курсор на плане — чёрная стрелка с тонкой белой обводкой: системная белая
   на светлом плане не различима (курсор задавался инлайново как default). */
.d-canvas-area {
  flex: 1; position: relative; overflow: hidden; touch-action: none;
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><path d='M3 2 L3 16.5 L7 12.8 L9.4 18 L12 16.8 L9.6 11.8 L14.8 11.8 Z' fill='%23000' stroke='%23fff' stroke-width='1.2' stroke-linejoin='round'/></svg>") 3 2, default;
  display: flex; align-items: center; justify-content: center;
}
.d-canvas-area canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
/* Область канваса занимает ВСЁ окно редактора (как 3D-вид), а не вписанный
 * квадрат: поле плана (GRID×GRID м) центрируется внутри неё средствами canvas.js
 * (fitCanvasToWrap кладёт смещение в ox/oy pan-состояния).
 * flex: 1 + min-height: 0 — область занимает пространство между header и footer;
 * footer с toggle'ами не выталкивается за пределы .d-center-view. */
.d-canvas-area[id^="cw-"] {
  flex: 1; min-height: 0; width: 100%; height: auto;
  align-self: stretch; margin: 0;
}
/* Ввод высоты настила террасы (футер редактора) */
.d-terrace-h {
  width: 68px; height: 30px; background: var(--card); border: none;
  text-align: center; font-size: 14px; font-weight: 600; outline: none;
}
.d-terrace-h:focus { background: #c0c0c0; }

/* Canvas footer with toggles */
.d-canvas-footer {
  padding: 10px 20px; border-top: 1px solid #e0e0e0;
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  flex-shrink: 0;
}
.d-canvas-toggle {
  display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
}
.d-canvas-toggle-label { font-size: 13px; font-weight: 600; }

/* Селектор высоты грядки (дискретный) */
.bed-h-row { display: flex; align-items: center; gap: 10px; }
.bed-h-lbl { font-size: 16px; font-weight: 400; color: #999; }
.bed-h-unit { font-size: 13px; color: #888; }
.bed-h-seg { display: inline-flex; border: 1px solid #ccc; border-radius: var(--r); overflow: hidden; }
.bed-h-btn {
  border: none; background: var(--card, #e8e8e8); color: #333;
  padding: 7px 14px; font-size: 14px; font-weight: 600; cursor: pointer;
  border-right: 1px solid #ccc;
}
.bed-h-btn:last-child { border-right: none; }
/* Вариант «подпись строкой, кнопки под ней во всю ширину» (TODO п.12). */
.bed-h-col { flex-direction: column; align-items: stretch; gap: 8px; }
.bed-h-col .bed-h-seg { display: flex; }
.bed-h-col .bed-h-btn { flex: 1 1 0; height: 40px; padding: 0; }
.bed-h-btn:hover { background: var(--card-hover, #ddd); }
.bed-h-btn.active { background: var(--accent); color: #fff; }

/* RIGHT PANEL — materials / catalog */
.d-panel {
  width: var(--panel-w); border-left: 1px solid #e0e0e0;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg);
}
.d-panel.hidden { display: none; }
.d-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px 12px; border-bottom: 1px solid #e8e8e8; flex-shrink: 0;
}
/* Название раздела — в одну строку (TODO п.5). Панель шириной с левую (--panel-w =
   --sidebar-w), поэтому кегль подбирается под самое длинное название: его считает
   _dSyncSidebarWidth (--panel-title-fz), один на все разделы. */
.d-panel-title {
  font-size: var(--panel-title-fz, 36px); font-weight: 400; color: var(--accent);
  white-space: nowrap;
}
.d-panel-close {
  width: 32px; height: 32px; background: none; border: none;
  border-radius: 50%; font-size: 18px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s;
}
.d-panel-close:hover { background: #e8e8e8; }
/* Тело панели само не скроллится: фильтры приколочены сверху, «СМЕТА» — снизу,
   прокручивается только список карточек товаров. */
.d-panel-body {
  flex: 1; min-height: 0; overflow: hidden; padding: 16px 20px 0;
  display: flex; flex-direction: column;
}
/* Фильтры каталога в правой панели: закреплены над списком товаров и свёрнуты
   по умолчанию — развёрнутый блок занимает половину панели и оттесняет карточки
   (версия 3D-UI; раньше фильтры жили в левой панели). */
.d-panel-filters { flex-shrink: 0; }
.d-filters-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; height: 34px; padding: 0 12px; margin-bottom: 8px;
  background: var(--bg); border: 2px solid var(--btn-border); border-radius: var(--r);
  font-size: 14px; font-weight: 600; color: var(--text); cursor: pointer;
}
.d-filters-toggle:hover { box-shadow: var(--hover-shadow); }
.d-filters-caret { transition: transform .15s; }
.d-filters-toggle.open .d-filters-caret { transform: rotate(180deg); }
.d-filters-box { display: none; padding: 0 2px 8px; }
.d-filters-box.open { display: block; }
.d-filters-box .d-color-section { margin-bottom: 12px; }
.d-filters-box .d-color-section:last-child { margin-bottom: 0; }
/* Специфические фильтры раздела — над цветом и ценой; пустой блок не занимает места. */
.d-filters-box .d-spec-filters:empty { display: none; }
.d-filters-box .d-spec-filters .d-color-section:last-child { margin-bottom: 12px; }
.d-filters-box .d-color-grid { grid-template-columns: repeat(8, 1fr); }
.d-filters-box .d-price-grid { grid-template-columns: 1fr; gap: 6px; margin-bottom: 0; }
.d-panel-footer { flex-shrink: 0; padding: 12px 20px; }
.d-panel-footer.hidden { display: none; }

/* Sub-toggle in panel (Терраса / Ограждение) */
.d-panel-sub-toggle {
  display: flex; gap: 4px; margin-bottom: 14px;
}
.d-sub-btn {
  flex: 1; height: 34px; background: var(--card); border: 2px solid transparent;
  border-radius: var(--r); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .15s, border-color .2s;
}
.d-sub-btn:hover { background: var(--card-hover); }
.d-sub-btn.active { border-color: #000; background: #f0f0f0; }

/* Catalog section selector */
.d-section-row { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.d-section-row:empty { display: none; }
.d-section-lbl { font-size: 13px; font-weight: 700; color: #333; white-space: nowrap; }
.d-section-select {
  flex: 1; height: 36px; padding: 0 10px; border: 1px solid #ccc; border-radius: var(--r);
  background: var(--card, #f0f0f0); font-size: 14px; color: #222; cursor: pointer;
}
.d-section-select:focus { outline: none; border-color: #000; }

/* Индикатор загрузки товаров раздела (прямоугольная индет-полоса) */
.d-cat-loading { padding: 28px 16px; color: #888; font-size: 13px; text-align: center; }
.d-cat-spinner {
  width: 140px; height: 3px; background: #e3e3e3; margin: 0 auto 14px;
  position: relative; overflow: hidden;
}
.d-cat-spinner::after {
  content: ''; position: absolute; top: 0; left: -40%; width: 40%; height: 100%;
  background: #555; animation: dcatbar 1s linear infinite;
}
@keyframes dcatbar { from { left: -40%; } to { left: 100%; } }

/* Samples in panel */
.d-samples-title { font-size: 12px; color: #999; margin-bottom: 8px; }
.d-samples-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }

/* Color picker in panel */
.d-color-section { margin-bottom: 18px; }
.d-color-title { font-size: 13px; font-weight: 700; margin-bottom: 10px; color: #333; }
.d-color-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px; margin-bottom: 4px;
}
/* Образец цвета: диаметр на 20% меньше прежнего, обводка выбранного — ТОЛЬКО
   внешняя (TODO.md, этап 2 п.1). Внутренняя рамка съедала и без того небольшой
   кружок, из-за неё цвет читался хуже. */
.d-color-dot {
  width: 80%; aspect-ratio: 1; justify-self: center;
  border-radius: 50%; cursor: pointer;
  border: none; transition: box-shadow .15s, transform .12s;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
}
.d-color-dot:hover { transform: scale(1.1); }
/* Название цвета — своей подписью над образцом: браузерный title всплывает через
   секунду с лишним, и цвет приходилось выжидать. Показывается сразу. */
.d-color-dot { position: relative; }
.d-color-dot::after {
  content: attr(data-label);
  position: absolute; left: 50%; bottom: calc(100% + 7px); transform: translateX(-50%);
  padding: 3px 8px; background: #333; color: #fff;
  font-size: 12px; font-weight: 400; line-height: 1.2; white-space: nowrap;
  border-radius: var(--r); opacity: 0; pointer-events: none;
  transition: opacity .08s; z-index: 60;
}
.d-color-dot:hover::after { opacity: 1; }
.d-color-dot.selected { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent); }

/* Material cards in panel */
.d-mat-list {
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px 0;
}
/* Карточка товара: прямые углы, белый фон, обводка как у кнопок; при наведении
   тень, у выбранной — оранжевая обводка (как у карточки дома). */
.d-mat-card {
  background: var(--bg); border-radius: 0; overflow: hidden;
  border: 2px solid var(--btn-border); flex-shrink: 0;
  transition: border-color .2s, box-shadow .2s;
}
.d-mat-card:hover { box-shadow: var(--hover-shadow); }
.d-mat-card.selected { border-color: var(--accent); }
.d-mat-head {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; cursor: pointer;
}
.d-mat-thumb {
  position: relative;
  width: 52px; height: 52px; background: #bbb; border-radius: var(--r); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
/* Фото товара: затемнение такое же, как у окна сметы. */
.d-photo-overlay {
  display: none; position: fixed; inset: 0; z-index: 300;
  background: rgba(0,0,0,.5); align-items: center; justify-content: center;
  padding: 40px; cursor: zoom-out;
}
.d-photo-overlay.active { display: flex; }
.d-photo-overlay img {
  max-width: 100%; max-height: 100%; object-fit: contain; background: var(--bg);
}
.d-mat-info { flex: 1; min-width: 0; }
.d-mat-name { font-size: 13px; font-weight: 700; margin-bottom: 2px; }
.d-mat-price { font-size: 12px; font-weight: 700; margin-top: 3px; color: #333; }
.d-mat-exp {
  width: 26px; height: 26px; background: rgba(0,0,0,.05); border: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  font-size: 12px; color: #555; transition: transform .25s; flex-shrink: 0; margin-top: 2px;
}
.d-mat-card.open .d-mat-exp { transform: rotate(180deg); }
.d-mat-body { max-height: 0; overflow: hidden; transition: max-height .3s; padding: 0 12px; }
.d-mat-card.open .d-mat-body { max-height: 400px; }
.d-mat-detail {
  padding-bottom: 12px; border-top: 1px solid rgba(0,0,0,.08); padding-top: 10px;
}
.d-mat-desc { font-size: 12px; font-weight: 300; color: #444; line-height: 1.6; margin-bottom: 10px; }
.d-mat-actions { display: flex; gap: 8px; }
.d-mat-btn {
  flex: 1; height: 34px; border: none; border-radius: var(--r);
  font-size: 12px; font-weight: 700; cursor: pointer; transition: background .15s;
  white-space: nowrap;
}
/* «Посмотреть текстуру» длиннее «Применить» — отдаём левой кнопке больше места,
   иначе надпись переносится в две строки (TODO.md, этап 1 п.11). */
.d-mat-btn-view { flex: 1.7; }
.d-mat-btn-apply { flex: 1; }
.d-mat-btn-apply { background: var(--accent); color: #fff; }
.d-mat-btn-apply:hover:not(:disabled) { background: var(--accent-hover); }
/* Применённый товар: кнопка гаснет по общему соглашению для неактивных. */
.d-mat-btn-apply:disabled {
  background: var(--btn-off-bg); color: var(--btn-off-text);
  border: 2px solid var(--btn-border); cursor: not-allowed;
}
/* «Посмотреть» — второстепенная кнопка слева от «Применить». */
.d-mat-btn-view {
  background: var(--bg); color: var(--text); border: 2px solid var(--btn-border);
}
.d-mat-btn-view:hover { box-shadow: var(--hover-shadow); }

/* Price filter in panel */
.d-price-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 14px; }
/* ── Radio: квадрат 24×24, при выборе оранжевый с галочкой ──
   Заменил тумблеры и кнопки-плитки. Логика прежняя (одиночный выбор у цены,
   независимые вкл/выкл у настроек) — по макету меняется только вид. */
.d-radio {
  width: 24px; height: 24px; flex-shrink: 0; border-radius: var(--r);
  background: var(--btn-off-bg); border: 1px solid var(--radio-off-border);
  position: relative; transition: background .15s, border-color .15s;
}
/* Галочка — две стороны рамки, повёрнутые на 45°. */
.d-radio::after {
  content: ''; position: absolute; left: 8px; top: 4px;
  width: 6px; height: 11px; border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg); opacity: 0; transition: opacity .15s;
}
.selected > .d-radio, .on > .d-radio {
  background: var(--accent); border-color: var(--accent);
}
.selected > .d-radio::after, .on > .d-radio::after { opacity: 1; }

.d-price-btn {
  display: flex; align-items: flex-start; gap: 8px; text-align: left;
  background: none; border: none; padding: 0; cursor: pointer;
}
.d-price-lbl { display: flex; flex-direction: column; gap: 2px; }
.d-price-btn { font-size: 18px; font-weight: 600; color: var(--text); line-height: 1.15; }

.d-filter-divider { height: 1px; background: #e8e8e8; margin: 14px 0; }

/* (panel is a single scrollable view — no view toggling) */

/* ═══════════════════════════════════════════
   SUMMARY overlay
   ═══════════════════════════════════════════ */
/* Инструкция при первом заходе в редактор (TODO.md, этап 1 п.15). */
.d-hint-overlay {
  display: none; position: fixed; inset: 0; z-index: 250;
  background: rgba(0,0,0,.5); align-items: center; justify-content: center;
}
.d-hint-overlay.active { display: flex; }
.d-hint-box {
  width: 440px; max-width: calc(100vw - 64px); background: var(--bg);
  padding: 24px; display: flex; flex-direction: column; gap: 16px; align-items: flex-start;
}
.d-hint-title { font-size: 22px; font-weight: 400; }
.d-hint-text { font-size: 16px; font-weight: 400; line-height: 1.4; color: var(--text); }
/* Кнопка «Понятно»: .d-btn рассчитана на футер панели (flex:1), в окне её надо
   задать явно, иначе она сжимается до ширины текста. */
.d-hint-box .d-btn {
  align-self: flex-end; flex: none;
  min-width: 160px; height: 48px; padding: 0 24px; font-size: 18px;
}

/* ═══ ОКНО ЗАЯВКИ ═══ */
/* Тот же бокс, что у подсказок: заголовок, поля, согласие и две кнопки. */
.d-req-box { width: 460px; gap: 12px; }
.d-req-field {
  display: flex; flex-direction: column; gap: 6px; width: 100%;
  font-size: 15px; font-weight: 400; color: #666;
}
.d-req-input {
  width: 100%; height: 44px; padding: 0 12px;
  background: var(--bg); border: 2px solid var(--btn-border); border-radius: var(--r);
  font-size: 16px; color: var(--text); outline: none; transition: border-color .15s;
}
.d-req-input:focus { border-color: var(--accent); }
.d-req-note { font-size: 13px; font-weight: 400; color: #888; line-height: 1.35; }
/* Галочка согласия: флажок акцентного цвета, текст в две строки рядом с ним,
   ссылка на политику — подчёркнутая, в цвет акцента. */
.d-req-consent {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; cursor: pointer;
  font-size: 13px; font-weight: 400; color: #666; line-height: 1.35;
}
.d-req-consent input {
  flex: none; width: 18px; height: 18px; margin: 1px 0 0; cursor: pointer;
  accent-color: var(--accent);
}
.d-req-consent a { color: var(--accent); text-decoration: underline; }
.d-req-err { font-size: 14px; color: #c0392b; min-height: 18px; }
.d-req-err:empty { min-height: 0; }
/* Ссылка-кнопка под ошибкой: обычный путь её не показывает (hidden снимается
   только после отказа сервера), поэтому оформлена скромно. */
.d-req-dump {
  align-self: flex-start; background: none; border: none; padding: 0;
  font: inherit; font-size: 13px; color: var(--accent, #e8730a);
  text-decoration: underline; cursor: pointer;
}
.d-req-dump[hidden] { display: none; }
.d-req-actions { display: flex; gap: 8px; width: 100%; }
/* Пустая выдача под выбранные фильтры: текст и кнопка сброса. */
.d-cat-empty { padding: 16px 4px; color: #888; font-size: 14px; display: flex; flex-direction: column;
  align-items: flex-start; gap: 10px; }
.d-cat-reset { background: none; border: 2px solid var(--btn-border); border-radius: var(--r);
  padding: 8px 14px; font: inherit; font-size: 14px; font-weight: 600; color: var(--text); cursor: pointer; }
.d-cat-reset:hover { border-color: var(--accent); }
/* Окно «Размеры террасы»: два поля в ряд через «×». */
.d-size-box { width: 380px; }
.d-size-row { display: flex; align-items: flex-end; gap: 10px; width: 100%; }
.d-size-row .d-req-field { flex: 1; }
.d-size-x { font-size: 20px; color: #888; padding-bottom: 10px; }
.d-req-actions .d-btn { flex: 1; height: 44px; font-size: 16px; cursor: pointer; }

.d-summary-overlay {
  display: none; position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,.5); align-items: center; justify-content: center;
}
.d-summary-overlay.active { display: flex; }
.d-summary-box {
  width: 520px; max-height: 80vh; background: var(--bg); border-radius: var(--r);
  overflow: hidden; display: flex; flex-direction: column;
}
.d-summary-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 24px; border-bottom: 1px solid #e8e8e8;
}
.d-summary-title { font-size: 22px; font-weight: 700; }
.d-summary-body { flex: 1; overflow-y: auto; padding: 20px 24px; }
.d-summary-actions { display: flex; gap: 12px; padding: 16px 24px; border-top: 1px solid #e8e8e8; }
.d-summary-btn {
  flex: 1; height: 48px; border: none; border-radius: var(--r);
  font-size: 16px; font-weight: 700; cursor: pointer; transition: background .15s;
}

/* Reuse swatch styles from mobile */
.swatch { width:64px; height:64px; background:var(--card); border-radius:var(--r);
  border:2px solid #ccc; display:flex; align-items:center; justify-content:center;
  flex-direction:column; gap:3px; cursor:pointer; position:relative; }
.swatch-name { font-size:8px; font-weight:600; color:#555; text-align:center;
  line-height:1.2; padding:0 3px; }
.swatch-del { position:absolute; top:1px; right:2px; font-size:9px; color:#aaa;
  cursor:pointer; line-height:1; background:none; border:none; padding:0; }
.swatch-del:hover { color:#000; }
.swatch-active { box-shadow:0 0 0 3px #fff, 0 0 0 5px #000; border-color:#000 !important; }

/* Reuse toggle styles */
/* Переключатель настройки — тот же radio, что у фильтров цены: квадрат слева,
   подпись справа. Тумблер-пилюля убран по макету. */
.tg { display:flex; align-items:center; gap:8px;
  height:40px; cursor:pointer; user-select:none; margin-bottom:6px;
  background:none; border:none; padding:0; }
.tg-txt { font-size:18px; font-weight:600; order:1; }
.tg-ind { width:24px; height:24px; flex-shrink:0; border-radius:var(--r);
  background:var(--btn-off-bg); border:1px solid var(--radio-off-border);
  position:relative; transition:background .15s, border-color .15s; }
.tg-ind::after { content:''; position:absolute; left:8px; top:4px;
  width:6px; height:11px; border:solid #fff; border-width:0 2px 2px 0;
  transform:rotate(45deg); opacity:0; transition:opacity .15s; }
.tg.on .tg-ind { background:var(--accent); border-color:var(--accent); }
.tg.on .tg-ind::after { opacity:1; }

/* Reuse param row from mobile */
.p-row { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; gap:10px; }
.p-lbl { font-size:14px; font-weight:300; flex:1; }
.p-inp { width:70px; height:36px; background:var(--card); border:none; border-radius:var(--r);
  text-align:center; font-size:16px; outline:none; flex-shrink:0; transition:background .15s; }
.p-inp:focus { background:#c0c0c0; }

/* Смета: только расчёт по спецификации (правка 2026-10-04) */
.est-title { font-size:16px; font-weight:700; margin:4px 0 10px; }
.est-empty { font-size:13px; color:#999; padding:8px 0; }
.est-table { width:100%; border-collapse:collapse; font-size:13px; }
.est-table th, .est-table td { padding:8px 8px; border-bottom:1px solid #eee; text-align:left; vertical-align:top; }
.est-table thead th { font-weight:700; color:#555; font-size:12px; text-transform:uppercase; letter-spacing:.02em; }
.est-table .est-r { text-align:right; white-space:nowrap; }
.est-mat { color:#333; }
.est-table tfoot td { border-top:2px solid #333; border-bottom:none; font-weight:700; padding-top:10px; }
.est-total { font-size:16px; }
/* Смета проекта: раздел на каждый объект и общий итог под ними. */
.est-obj-title { font-size:14px; font-weight:600; margin:18px 0 6px; }
.est-project-total {
  display:flex; justify-content:space-between; align-items:baseline;
  margin-top:16px; padding-top:10px; border-top:2px solid #333;
  font-size:16px; font-weight:700;
}

/* ── Отделка фасада: счётчик в футере план-редактора ── */
.d-facade-count { font-size:12px; color:#777; white-space:nowrap; }
