/* Визуальный конфигуратор — токены и раскладка по docs/design.md и
   docs/design-handoff-2026-09-15/README.md. Система плоская: без теней и скруглений,
   кроме капсулы тумблера и RAL-свотчей (радиуса у них тоже нет — они квадратные). */
/* Шрифты Manrope и PT Serif подключает тема сайта (локальные файлы), отдельно плагин их не грузит — без обращений к Google. */

.avtogates-configurator {
  --ag-ink: #16201c;
  --ag-paper: #f3f0e7;
  --ag-surface: #fffdf8;
  --ag-surface-card: #edf0e6;
  --ag-surface-card-alt: #e2e7dc;
  --ag-pine: #153b33;
  --ag-lime: #d7f06a;
  --ag-line: #d4d3c9;
  --ag-muted: #647068;
  --ag-eyebrow: #53635a;
  --ag-ink-subtle: #4f5b55;
  --ag-status: #8b948e;
  --ag-disabled-bg: #e4e2d8;
  --ag-overlay: rgba(22, 32, 28, 0.6);
  --ag-focus: #95c9ff;
  --ag-error-bg: #fff0ed;
  --ag-error-border: #b43f26;
  --ag-font-body: Manrope, Arial, Helvetica, sans-serif;
  --ag-font-price: "PT Serif", Georgia, "Times New Roman", serif;
  display: block;
  background: var(--ag-paper);
  color: var(--ag-ink);
  font: 400 15px/1.5 var(--ag-font-body);
  max-width: 1240px;
  margin: 0 auto;
  padding: 64px 32px 88px;
  box-sizing: border-box;
}
.avtogates-configurator *, .avtogates-configurator *::before, .avtogates-configurator *::after { box-sizing: border-box; }
.avtogates-configurator [hidden] { display: none !important; }
/* Сброс кнопок — только для classic: в виде ДС кнопки задают font/color своими классами (сброс ДС — в configurator-ds.css, :where). */
.avtogates-configurator:where(:not([data-layout="ds"])) button { font: inherit; color: inherit; }

.avtogates-configurator-fallback { background: var(--ag-paper); color: var(--ag-ink); padding: 32px; font: 400 15px/1.5 var(--ag-font-body); }
.avtogates-configurator-fallback a { color: var(--ag-pine); }

/* ---- Заголовок ---- */
.avtogates-configurator__eyebrow { margin: 0 0 8px; font: 800 12px/1 var(--ag-font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--ag-eyebrow); }
.avtogates-configurator__title { max-width: 720px; margin: 0 0 12px; font: 400 44px/1.06 var(--ag-font-price); letter-spacing: -.02em; text-wrap: pretty; }
.avtogates-configurator__lead { max-width: 600px; margin: 0 0 32px; font: 400 17px/1.55 var(--ag-font-body); color: var(--ag-ink-subtle); }

/* ---- Сетка ---- */
.avtogates-configurator__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; align-items: start; }
.avtogates-configurator__scene-col { display: flex; flex-direction: column; gap: 20px; }
.avtogates-configurator__panel { display: flex; flex-direction: column; gap: 26px; background: var(--ag-surface); padding: 28px; }
/* [data-sections] держит все разделы каталога (Зашивка, Цвет RAL, Калитка, Автоматика, …) —
   это ОДИН flex-item панели, поэтому gap самого .panel действует только снаружи этого блока.
   Без собственного display:flex+gap здесь разделы каталога стоят вплотную друг к другу
   (заголовок следующего раздела упирается в карточки предыдущего) — тот же ритм 26px/24px,
   что и у .panel, чтобы разделы из ширины/высоты/отката и разделы из каталога не расходились. */
.avtogates-configurator__sections { display: flex; flex-direction: column; gap: 26px; }
.avtogates-configurator__section { display: flex; flex-direction: column; gap: 12px; }
.avtogates-configurator__section-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.avtogates-configurator__section-label { margin: 0; font: 800 12px/1 var(--ag-font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--ag-eyebrow); }
.avtogates-configurator__value { font: 700 15px var(--ag-font-body); color: var(--ag-ink); }

/* ---- Ползунки ---- */
.avtogates-configurator__section input[type="range"] { width: 100%; height: 28px; accent-color: var(--ag-pine); }
.avtogates-configurator__range-ends { display: flex; justify-content: space-between; font: 400 12px var(--ag-font-body); color: var(--ag-muted); }

/* ---- Опции: сетка кнопок и свотчи ---- */
/* align-items: stretch (уже значение по умолчанию для grid, но задаём явно) — карточки в одной
   строке всегда равной высоты, даже если у одной из них название перенеслось на 2 строки. */
.avtogates-configurator__option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; align-items: stretch; }
.avtogates-configurator__option-grid--2 { grid-template-columns: repeat(2, 1fr); }
.avtogates-configurator__option-grid--3 { grid-template-columns: repeat(3, 1fr); }
.avtogates-configurator__option {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  height: 100%; min-height: 48px; min-width: 0; padding: 12px 14px; text-align: left; text-wrap: pretty; box-sizing: border-box;
  background: var(--ag-surface); border: 1px solid var(--ag-line); cursor: pointer;
  font: 500 14px/1.3 var(--ag-font-body); color: var(--ag-ink);
}
.avtogates-configurator__option:hover { background: var(--ag-surface-card); }
.avtogates-configurator__option--on { border: 1px solid var(--ag-pine); box-shadow: inset 0 0 0 1px var(--ag-pine); background: var(--ag-surface-card); font-weight: 700; }
.avtogates-configurator__option-name { min-width: 0; }
.avtogates-configurator__option-price { font: 400 12px var(--ag-font-body); color: var(--ag-muted); white-space: nowrap; }
.avtogates-configurator__option--2, .avtogates-configurator__option-grid--2 .avtogates-configurator__option, .avtogates-configurator__option-grid--3 .avtogates-configurator__option { align-items: center; justify-content: center; text-align: center; }

/* Свотчи — отдельный ряд с переносом, а не сетка карточек option-grid (иначе квадраты уходят в
   столбики по числу колонок сетки). renderPanel() выбирает этот класс для любого раздела, где у
   позиций есть swatch_hex — независимо от кода раздела. */
.avtogates-configurator__swatch-row { display: flex; flex-wrap: wrap; gap: 10px; }
.avtogates-configurator__swatch { width: 44px; height: 44px; padding: 0; min-height: 0; border: 0; cursor: pointer; }
/* Светлый образец (яркость > 200 по формуле из reference/configurator-logic.js, см.
   swatchLuminance() в configurator-ui.js) иначе сливается с фоном панели. */
.avtogates-configurator__swatch--light { border: 1px solid var(--ag-line); }
.avtogates-configurator__swatch:focus-visible, .avtogates-configurator__option[aria-pressed="true"].avtogates-configurator__swatch { outline: 2px solid var(--ag-pine); outline-offset: 3px; }

/* Подпись выбранного образца в заголовке раздела — «Название · + 4 500 ₽» справа от label
   (design.md/README → «Цвет RAL»). min-width:0 и обычный white-space дают перенос слов вместо
   переполнения строки на узких экранах. */
.avtogates-configurator__swatch-selected { flex: 1; min-width: 0; text-align: right; font: 400 13px var(--ag-font-body); color: var(--ag-muted); }

/* ---- Размеры: кнопки-варианты и «Свой размер» (0.6.5) ----
   Кнопки собирает renderSizePresets() из пределов каталога. Это те же .option, поэтому выбранная кнопка
   получает --on вместе с aria-pressed. «Свой размер» открывает ползунок точного значения: на телефоне он
   скрыт, пока data-collapsed="true" (см. медиазапрос ниже), на компьютере виден всегда. */
.avtogates-configurator__size-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; }
.avtogates-configurator__size-button { align-items: center; justify-content: center; min-height: 44px; padding: 8px 6px; text-align: center; white-space: nowrap; }
.avtogates-configurator__size-button--custom { border-style: dashed; }
.avtogates-configurator__size-button--custom.avtogates-configurator__option--on { border-style: solid; }
[data-size-presets="width"] .avtogates-configurator__size-button--custom { grid-column: span 2; }

/* ---- «Ещё» (0.6.5): необязательные разделы свёрнуты под одной кнопкой ---- */
.avtogates-configurator__extras { display: flex; flex-direction: column; gap: 24px; }
.avtogates-configurator__extras-toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 52px; padding: 10px 14px; text-align: left; background: var(--ag-surface); border: 1px solid var(--ag-line); cursor: pointer; font: 700 14px/1.3 var(--ag-font-body); color: var(--ag-ink); }
.avtogates-configurator__extras-toggle:hover { background: var(--ag-surface-card); }
.avtogates-configurator__extras-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.avtogates-configurator__extras-picked { font: 400 12px/1.4 var(--ag-font-body); color: var(--ag-pine); }
.avtogates-configurator__extras-icon { flex: none; width: 20px; text-align: center; font: 700 18px/1 var(--ag-font-body); }
.avtogates-configurator__extras-icon::before { content: "+"; }
.avtogates-configurator__extras-toggle[aria-expanded="true"] .avtogates-configurator__extras-icon::before { content: "–"; }

/* ---- Чекбокс-строки (множественный выбор) ---- */
.avtogates-configurator__checkbox-list { display: flex; flex-direction: column; border-top: 1px solid var(--ag-line); }
.avtogates-configurator__checkbox-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--ag-line); cursor: pointer; min-height: 44px; }
.avtogates-configurator__checkbox-box { width: 20px; height: 20px; flex: none; display: flex; align-items: center; justify-content: center; border: 1px solid var(--ag-line); font: 800 13px var(--ag-font-body); color: var(--ag-lime); }
.avtogates-configurator__checkbox-box--on { border: 0; background: var(--ag-pine); }
.avtogates-configurator__checkbox-box--on::after { content: "✓"; }
/* Недоступная позиция (нужная группа не выбрана, aria-disabled — см. syncPanel в configurator-ui.js): не
   реагирует на наведение и не выглядит кликабельной; приглушение (opacity) задаёт сам скрипт. */
.avtogates-configurator__option[aria-disabled="true"], label.avtogates-configurator__checkbox-row[aria-disabled="true"],
label.avtogates-configurator__checkbox-row[aria-disabled="true"] .avtogates-configurator__checkbox-box { cursor: not-allowed; }
.avtogates-configurator__option[aria-disabled="true"]:hover { background: var(--ag-surface); }
.avtogates-configurator__checkbox-name { flex: 1; min-width: 0; font: 500 14px/1.3 var(--ag-font-body); }
.avtogates-configurator__checkbox-price { font: 400 13px var(--ag-font-body); color: var(--ag-muted); white-space: nowrap; }
.avtogates-configurator__visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

.avtogates-configurator__catalog-status { margin: 0; font: 400 12px var(--ag-font-body); color: var(--ag-status); }

/* ---- «Показать больше» (ТЗ 22.09.2026, п.2.5) — район/звонок/фото свёрнуты по умолчанию,
   имя/телефон/согласие/кнопка отправки остаются вне этого блока и видны сразу. ---- */
.avtogates-configurator__more { border-top: 1px solid var(--ag-line); border-bottom: 1px solid var(--ag-line); }
.avtogates-configurator__more-summary { cursor: pointer; padding: 13px 0; min-height: 44px; display: flex; align-items: center; font: 700 14px var(--ag-font-body); color: var(--ag-pine); list-style: none; }
.avtogates-configurator__more-summary::-webkit-details-marker { display: none; }
.avtogates-configurator__more-summary::before { content: "+"; margin-right: 10px; font: 700 16px var(--ag-font-body); }
.avtogates-configurator__more[open] .avtogates-configurator__more-summary::before { content: "–"; }
.avtogates-configurator__more[open] .avtogates-configurator__more-summary { border-bottom: 1px solid var(--ag-line); }
.avtogates-configurator__more > *:not(summary) { margin-top: 16px; }
.avtogates-configurator__more > *:last-child { margin-bottom: 16px; }

/* ---- Сцена ---- */
.avtogates-configurator__scene { position: relative; aspect-ratio: 1376 / 768; overflow: hidden; background: var(--ag-surface-card-alt); }
/* Кадр v2 — стопка слоёв на холсте 1376×768: контейнер повторяет пропорции холста, каждый слой
   позиционируется инлайн в процентах холста (left/top/width/height, см. configurator-layers.js).
   max-width/height:auto темы сайта для <img> слоям не нужны — размеры слоя заданы им самим. */
.avtogates-configurator__scene-layers { position: absolute; inset: 0; aspect-ratio: 1376 / 768; }
.avtogates-configurator__scene-layer { position: absolute; display: block; max-width: none; margin: 0; padding: 0; border: 0; pointer-events: none; }
.avtogates-configurator__scene-fallback { position: absolute; inset: 0; }
.avtogates-configurator__scene-fallback svg { display: block; width: 100%; height: 100%; }
/* Центр сцены, а не нижний край — иначе на узкой мобильной сцене подпись оказывается в той же
   зоне, что и бирка направления отката (.dim-direction, тоже у нижнего края), и они
   накладываются друг на друга. Центр свободен при любом состоянии сцены (фотокадр/запасная SVG). */
.avtogates-configurator__scene-note-overlay { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; padding: 4px 10px; background: rgba(255, 253, 248, .92); font: 700 12px var(--ag-font-body); }
.avtogates-configurator__scene-caption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; margin: 0; font: 400 13px var(--ag-font-body); color: var(--ag-muted); }

/* ---- Размерные выноски над сценой ---- */
/* Разметка одна поверх обоих вариантов сцены (фото-кадр и запасная SVG) — README →
   «Десктоп» → «Правая колонка». Подпись «Визуализация…» лежит в .scene-caption, ВНЕ .scene,
   поэтому выноски (position: absolute внутри .scene) её никогда не перекрывают. */
.avtogates-configurator__dimensions { position: absolute; inset: 0; pointer-events: none; }
/* Дефект (Stage без каталога CRM, узкий мобильный экран): gate-scene.js рисует на запасной
   SVG-схеме собственные подписи ширины/высоты («4000 мм», «Ширина неизвестна») — при показанном
   этом слое поверх схемы наши «проём 4,0 м» / «2,0 м» накладывались на них. Прячем только линии
   и подписи размеров по режиму сцены (data-scene-mode на [data-scene], см. configurator-ui.js).
   Бирку направления (.dim-direction) не трогаем — схема направление текстом не выводит, только
   стрелкой (state.direction в gate-scene.js), поэтому дублирования с ней нет и на схеме бирка
   остаётся единственным текстовым указанием стороны отката. */
[data-scene][data-scene-mode="fallback"] .avtogates-configurator__dim-line,
[data-scene][data-scene-mode="fallback"] .avtogates-configurator__dim-label { display: none; }
.avtogates-configurator__dim-line { position: absolute; background: var(--ag-surface); box-shadow: 0 0 0 1px rgba(22, 32, 28, .35); }
.avtogates-configurator__dim-line--width { left: 21%; right: 21%; top: 22%; height: 1px; }
.avtogates-configurator__dim-line--height { left: 16%; top: 30%; bottom: 27%; width: 1px; }
.avtogates-configurator__dim-tick { position: absolute; background: var(--ag-surface); box-shadow: 0 0 0 1px rgba(22, 32, 28, .35); }
.avtogates-configurator__dim-line--width .avtogates-configurator__dim-tick { top: -8px; width: 1px; height: 16px; }
.avtogates-configurator__dim-line--width .avtogates-configurator__dim-tick--start { left: 0; }
.avtogates-configurator__dim-line--width .avtogates-configurator__dim-tick--end { right: 0; }
.avtogates-configurator__dim-line--height .avtogates-configurator__dim-tick { left: -8px; width: 16px; height: 1px; }
.avtogates-configurator__dim-line--height .avtogates-configurator__dim-tick--start { top: 0; }
.avtogates-configurator__dim-line--height .avtogates-configurator__dim-tick--end { bottom: 0; top: auto; }
/* «Не знаю размеры»: линия становится пунктирным ориентиром без засечек, подпись — «неизвестна». */
.avtogates-configurator__dim-line--unknown { background: transparent; box-shadow: none; }
.avtogates-configurator__dim-line--width.avtogates-configurator__dim-line--unknown { border-top: 1px dashed rgba(22, 32, 28, .45); }
.avtogates-configurator__dim-line--height.avtogates-configurator__dim-line--unknown { border-left: 1px dashed rgba(22, 32, 28, .45); }
.avtogates-configurator__dim-line--unknown .avtogates-configurator__dim-tick { display: none; }
.avtogates-configurator__dim-label { position: absolute; left: 50%; top: 50%; background: var(--ag-surface); padding: 4px 10px; font: 700 12px var(--ag-font-body); color: var(--ag-ink); white-space: nowrap; }
.avtogates-configurator__dim-label--width { transform: translate(-50%, -50%); }
.avtogates-configurator__dim-label--height { transform: translate(-50%, -50%) rotate(-90deg); }
.avtogates-configurator__dim-direction { position: absolute; bottom: 12%; background: rgba(255, 253, 248, .92); padding: 4px 10px; font: 700 12px var(--ag-font-body); color: var(--ag-ink); white-space: nowrap; }
.avtogates-configurator__dim-direction--left { left: 4%; }
.avtogates-configurator__dim-direction--right { right: 4%; }

/* ---- Цена ---- */
.avtogates-configurator__price-card { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 24px; background: var(--ag-surface); padding: 28px; }
.avtogates-configurator__price { margin: 4px 0; font: 400 44px/1 var(--ag-font-price); letter-spacing: -.02em; }
/* «для проёма 4 × 2 м — укажите свой размер» (0.6.5) — сразу под ценой, чтобы стартовую цену не принимали за окончательную. */
.avtogates-configurator__opening-note { max-width: 380px; margin: 0 0 6px; font: 600 13px/1.4 var(--ag-font-body); color: var(--ag-ink-subtle); }
.avtogates-configurator__price-note { max-width: 380px; margin: 0; font: 400 14px/1.5 var(--ag-font-body); color: var(--ag-muted); }
/* Расшифровка состава и сроки под ценой (ТЗ 22.09.2026, п.2.3/2.4) — оба необязательные, узлы
   скрыты через [hidden], пока CRM не прислала соответствующие поля (см. updatePriceDisplay). */
.avtogates-configurator__price-breakdown { max-width: 380px; margin: 8px 0 0; font: 400 13px/1.5 var(--ag-font-body); color: var(--ag-muted); }
.avtogates-configurator__price-lead-time { max-width: 380px; margin: 4px 0 0; font: 400 13px/1.5 var(--ag-font-body); color: var(--ag-muted); }
.avtogates-configurator__price-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }

/* Компактная строка цены в липком блоке сцены — видна только на мобильном (см. медиазапрос ниже),
   на десктопе полная карточка .price-card и так видна в липкой правой колонке. Настоящая кнопка
   (тот же data-open-modal, что у «Рассчитать эту конфигурацию») — решение владельца 16.09.2026:
   после отказа от закреплённой панели это единственная всегда видимая кнопка действия во время
   прокрутки разделов. Сумма внутри помечена aria-hidden — озвучивает aria-label самой кнопки
   (обновляется вместе с текстом в updatePriceDisplay), скринридеру не нужно читать её дважды. */
/* Та же подпись проёма, что в карточке, отдельной строкой под суммой (0.6.5). */
.avtogates-configurator__scene-price-note { flex: 0 0 100%; margin-top: -2px; font: 400 12px/1.3 var(--ag-font-body); color: var(--ag-ink-subtle); }
.avtogates-configurator__scene-price { display: none; flex-wrap: wrap; width: 100%; margin: 0; align-items: baseline; justify-content: space-between; gap: 10px; border: 0; background: none; padding: 0; text-align: left; cursor: pointer; }

/* ---- Кнопки ---- */
.avtogates-configurator__button--primary { border: 0; padding: 17px 22px; background: var(--ag-lime); color: var(--ag-ink); font: 700 15px var(--ag-font-body); cursor: pointer; min-height: 44px; }
.avtogates-configurator__button--primary:disabled { background: var(--ag-disabled-bg); color: var(--ag-status); cursor: not-allowed; }
.avtogates-configurator__button--full { width: 100%; }
.avtogates-configurator__link-button { display: inline-flex; align-items: center; min-height: 44px; background: none; border: 0; padding: 0; color: var(--ag-ink); font: 500 14px var(--ag-font-body); text-decoration: underline; text-underline-offset: 4px; cursor: pointer; }
.avtogates-configurator__link-button:hover { color: var(--ag-pine); }

/* Кнопка «Зафиксировать цену на замере» / «Оставить телефон — менеджер посчитает» у цены (0.6.4): одна и та же
   кнопка в двух местах, показ задаёт атрибут hidden из syncQuoteCta(). --card стоит в карточке прямо под
   ценой и составом; --compact — в липком блоке сцены на телефоне (там цена видна всегда), на десктопе
   скрыта. На телефоне, наоборот, скрыта --card: карточка стоит после разделов, а кнопка уже рядом с ценой.
   Правило стоит ПОСЛЕ .button--primary: его шорткат font сбросил бы line-height. */
.avtogates-configurator__quote-cta { max-width: 100%; margin-top: 16px; white-space: normal; text-align: center; line-height: 1.25; }
.avtogates-configurator__quote-cta--compact { display: none; }

/* Строка «что дальше» под главной кнопкой (0.7.0) и строка доверия в карточке цены. Показ — атрибутом hidden
   (syncQuoteCta / updatePriceDisplay). */
.avtogates-configurator__quote-cta-note { max-width: 380px; margin: 8px 0 0; font: 400 12px/1.4 var(--ag-font-body); color: var(--ag-muted); }
.avtogates-configurator__quote-cta-note--compact { display: none; }
.avtogates-configurator__trust { display: flex; flex-direction: column; gap: 4px; max-width: 380px; margin: 12px 0 0; padding: 0; list-style: none; font: 400 13px/1.45 var(--ag-font-body); color: var(--ag-muted); }
.avtogates-configurator__trust .avtogates-configurator__price-lead-time { margin: 0; }
.avtogates-configurator__form-lead { margin: 0; font: 400 14px/1.5 var(--ag-font-body); color: var(--ag-muted); }

/* Форма заявки в карточке цены (телефон, 0.7.0): тот же блок, что окно, без рамки окна, прокрутки и подложки.
   Заголовок и поля те же; крестик и свёрнутая сводка конфигурации не нужны — цена и состав уже выше в карточке. */
.avtogates-configurator__inline-form { width: 100%; display: flex; flex-direction: column; gap: 16px; border-top: 1px solid var(--ag-line); padding-top: 16px; }
.avtogates-configurator__modal--inline { max-width: none; max-height: none; overflow: visible; padding: 0; background: transparent; }
.avtogates-configurator__modal--inline .avtogates-configurator__close,
.avtogates-configurator__modal--inline .avtogates-configurator__config,
.avtogates-configurator__modal--inline .avtogates-configurator__eyebrow { display: none; }
.avtogates-configurator__modal--inline .avtogates-configurator__modal-header { justify-content: flex-start; }
/* На телефоне форма стоит прямо в карточке: отдельные «Рассчитать…» и ссылка Telegram рядом с ней дублировали бы
   кнопки самой формы. */
.avtogates-configurator__price-card--inline-form .avtogates-configurator__price-actions { display: none; }

.avtogates-configurator__fallback { margin-top: 24px; font: 400 14px var(--ag-font-body); }
.avtogates-configurator__fallback a { color: var(--ag-pine); }

/* ---- Модалка ---- */
.avtogates-configurator__overlay { position: fixed; inset: 0; z-index: 1000; background: var(--ag-overlay); display: flex; align-items: center; justify-content: center; padding: 24px; overflow-y: auto; }
.avtogates-configurator__modal { width: 100%; max-width: 540px; max-height: calc(100dvh - 48px); overflow-y: auto; background: var(--ag-surface); padding: 32px; display: flex; flex-direction: column; gap: 24px; }
.avtogates-configurator__modal-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.avtogates-configurator__modal h3 { margin: 0; font: 400 28px/1.15 var(--ag-font-price); }
.avtogates-configurator__close { border: 0; background: none; font: 400 22px var(--ag-font-body); color: var(--ag-muted); cursor: pointer; line-height: 1; padding: 4px; min-height: 44px; min-width: 44px; }

/* Свёрнутая сводка конфигурации в форме заявки (WEB-2026-10-03-01): строка-заголовок с ценой
   видна всегда, состав — по нажатию. Стоит над полями, но занимает одну строку, поэтому поля
   имени и телефона остаются на первом экране телефона. */
.avtogates-configurator__config { border: 1px solid var(--ag-line); background: var(--ag-paper); }
.avtogates-configurator__config-summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; padding: 8px 14px; cursor: pointer; list-style: none; }
.avtogates-configurator__config-summary::-webkit-details-marker { display: none; }
.avtogates-configurator__config-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.avtogates-configurator__config-price { font: 400 22px/1.15 var(--ag-font-price); letter-spacing: -.02em; color: var(--ag-ink); }
.avtogates-configurator__config-hint { flex: none; font: 700 13px var(--ag-font-body); color: var(--ag-pine); text-decoration: underline; text-underline-offset: 4px; }
.avtogates-configurator__config-hint::after { content: " ▾"; text-decoration: none; display: inline-block; }
.avtogates-configurator__config[open] .avtogates-configurator__config-hint::after { content: " ▴"; }
.avtogates-configurator__config-hint-open { display: none; }
.avtogates-configurator__config[open] .avtogates-configurator__config-hint-open { display: inline; }
.avtogates-configurator__config[open] .avtogates-configurator__config-hint-closed { display: none; }
.avtogates-configurator__config[open] > dl { margin: 0 14px 8px; }

/* Строка сводки — ОДИН элемент на всю ширину карточки с одной парой границ (border-top у
   списка целиком + border-bottom у каждой строки), а не dt/dd с границей у каждой ячейки по
   отдельности: раньше это давало две несовпадающие линии с зазором между ними. */
.avtogates-configurator__summary-list { margin: 0; display: flex; flex-direction: column; border-top: 1px solid var(--ag-line); }
.avtogates-configurator__summary-row { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin: 0; padding: 10px 0; border-bottom: 1px solid var(--ag-line); }
.avtogates-configurator__summary-row dt { margin: 0; min-width: 0; font: 400 14px var(--ag-font-body); color: var(--ag-ink-subtle); }
.avtogates-configurator__summary-row dd { margin: 0; min-width: 0; font: 600 14px var(--ag-font-body); color: var(--ag-ink); text-align: right; }
/* «Ориентировочно» — всегда последняя строка сводки, оформлена иначе: подпись как section
   label, цена крупным PT Serif, которая никогда не переносится на вторую строку. */
.avtogates-configurator__summary-row--price { padding: 14px 0; }
.avtogates-configurator__summary-row--price dt { font: 800 12px var(--ag-font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--ag-eyebrow); }
.avtogates-configurator__summary-row--price dd { font: 400 26px var(--ag-font-price); color: var(--ag-ink); letter-spacing: -.02em; white-space: nowrap; flex: none; }

/* Статус формы — подложка ошибки появляется только для isError:true (announceForm), нейтральный
   и успешный статус выглядят как обычный текст (успех вообще не проходит через этот блок —
   переключается на модалку подтверждения). */
.avtogates-configurator__status { min-height: 1.4em; margin: 0; font: 500 13px var(--ag-font-body); color: var(--ag-pine); }
.avtogates-configurator__status--error { background: var(--ag-error-bg); border-left: 3px solid var(--ag-error-border); padding: 10px 12px; color: var(--ag-ink); font-weight: 700; }
.avtogates-configurator__error { margin: 6px 0 0; font: 500 13px var(--ag-font-body); color: var(--ag-error-border); }

/* Прежде форма не задавала gap вовсе — все блоки (поля, фото, тумблер звонка, согласие,
   кнопки, абзацы) шли вплотную друг к другу. Тот же ритм 24px, что у .modal между своими
   секциями (шапка/сводка/статус/форма). */
.avtogates-configurator__form { display: flex; flex-direction: column; gap: 24px; }
.avtogates-configurator__field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.avtogates-configurator__field { display: flex; flex-direction: column; gap: 12px; }
.avtogates-configurator__field input, .avtogates-configurator__field select, .avtogates-configurator__field textarea {
  padding: 13px 14px; border: 1px solid var(--ag-line); background: var(--ag-surface); color: var(--ag-ink);
  font: 500 15px var(--ag-font-body); width: 100%; min-height: 44px;
}
/* Ошибка поля — не только текст рядом, но и рамка на самом контроле (взгляд сразу находит
   проблему); target.classList — выше специфичность, чем у базового правила border, поэтому
   .avtogates-configurator__field--error побеждает независимо от порядка объявления. */
.avtogates-configurator__field input.avtogates-configurator__field--error,
.avtogates-configurator__field select.avtogates-configurator__field--error,
.avtogates-configurator__field textarea.avtogates-configurator__field--error { border-color: var(--ag-error-border); }
.avtogates-configurator__checkbox-row--error .avtogates-configurator__checkbox-box { border-color: var(--ag-error-border); }
.avtogates-configurator__photos.avtogates-configurator__photos--error { border: 1px solid var(--ag-error-border); padding: 10px; }

.avtogates-configurator__toggle { display: flex; align-items: center; gap: 14px; width: 100%; padding: 16px; border: 1px solid var(--ag-line); background: var(--ag-paper); cursor: pointer; text-align: left; }
.avtogates-configurator__toggle-track { width: 46px; height: 26px; flex: none; border-radius: 13px; background: var(--ag-line); display: flex; align-items: center; padding: 3px; box-sizing: border-box; justify-content: flex-start; transition: background .18s; }
.avtogates-configurator__toggle--on .avtogates-configurator__toggle-track { background: var(--ag-pine); justify-content: flex-end; }
.avtogates-configurator__toggle-knob { width: 20px; height: 20px; border-radius: 10px; background: var(--ag-surface); }
.avtogates-configurator__toggle--on .avtogates-configurator__toggle-knob { background: var(--ag-lime); }
.avtogates-configurator__toggle-text { display: flex; flex-direction: column; gap: 2px; }
.avtogates-configurator__toggle-title { font: 700 15px var(--ag-font-body); }

.avtogates-configurator__checkbox-row.avtogates-configurator__checkbox-row { cursor: pointer; }
label.avtogates-configurator__checkbox-row { gap: 12px; border: 0; padding: 0; }

.avtogates-configurator__photos { display: flex; flex-direction: column; gap: 10px; }
/* Визуально скрытый, но НЕ display:none/hidden — реальный <input type=file> должен оставаться в
   доступности и в естественном порядке табуляции (см. AGENTS.md → зона в духе Reshaped
   FileUpload: дропзона связана с ним через for/id, клавиатурный Enter/Space на самом input
   открывает системный диалог нативно, без JS). */
.avtogates-configurator__file-input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
/* Дропзона (в духе Reshaped FileUpload) — прямоугольник с пунктирной рамкой, связанный с
   визуально скрытым .file-input через for/id (не оборачивает его — см. комментарий у
   photosInputId в configurator-ui.js). Вся зона кликабельна нативно (label → for), без
   JS-пересылки клика. */
.avtogates-configurator__dropzone {
  display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 88px;
  padding: 18px 20px; border: 2px dashed var(--ag-line); background: var(--ag-surface);
  color: var(--ag-muted); text-align: left; cursor: pointer;
  transition: border-color .18s, background-color .18s;
}
.avtogates-configurator__dropzone:hover { border-color: var(--ag-pine); }
.avtogates-configurator__dropzone-icon { flex: none; color: var(--ag-pine); }
.avtogates-configurator__dropzone-text { font: 500 14px/1.4 var(--ag-font-body); color: var(--ag-ink); }
/* Подсветка при перетаскивании файла над зоной — dragenter/dragover в configurator-ui.js.
   Плавность самого перехода снимается общим правилом prefers-reduced-motion выше в файле. */
.avtogates-configurator__dropzone--drag { border-color: var(--ag-pine); background: var(--ag-surface-card); }
/* Лимит фотографий достигнут ИЛИ форма заблокирована на отправке (lockForm) — сам input получает
   атрибут disabled (не даёт открыть диалог даже по клику/Enter/Space), здесь только визуальный
   сигнал недоступности. */
.avtogates-configurator__dropzone--disabled { cursor: not-allowed; opacity: .55; }
/* Фокус реального input — рамка переносится на зону соседним селектором, а не на сам 1px-инпут
   (который и так не виден пользователю за clip-путём выше). */
.avtogates-configurator__file-input:focus-visible + .avtogates-configurator__dropzone { outline: 2px solid var(--ag-focus); outline-offset: 2px; }
.avtogates-configurator__photo-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
.avtogates-configurator__photo-grid li { position: relative; }
.avtogates-configurator__photo-grid img { display: block; width: 100%; height: 120px; object-fit: cover; border: 1px solid var(--ag-line); }
.avtogates-configurator__photo-grid button { position: absolute; top: 6px; right: 6px; min-width: 32px; min-height: 32px; border: 1px solid var(--ag-pine); background: var(--ag-surface); cursor: pointer; }

.avtogates-configurator__help { margin: 0; font: 400 12px/1.5 var(--ag-font-body); color: var(--ag-muted); }

/* ---- Подтверждение ---- */
.avtogates-configurator__sent-badge { width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; background: var(--ag-pine); color: var(--ag-lime); font: 700 24px var(--ag-font-body); }
.avtogates-configurator__sent-config { background: var(--ag-paper); padding: 18px; display: flex; flex-direction: column; gap: 6px; }

/* ---- Фокус ---- */
.avtogates-configurator :focus-visible { outline: 2px solid var(--ag-focus); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .avtogates-configurator * { transition: none !important; scroll-behavior: auto !important; }
}

/* ---- Десктоп: закреплённая правая колонка ---- */
@media (min-width: 721px) {
  .avtogates-configurator__grid { grid-template-columns: minmax(300px, 420px) minmax(0, 1fr); }
  .avtogates-configurator__panel { order: -1; }
  .avtogates-configurator__scene-col { position: sticky; top: 24px; }
}

/* ---- Мобайл (до 720px): закреплённый рендер сверху, полная карточка цены — после разделов ---- */
/* 720px — то же число, что MOBILE_BREAKPOINT_PX/MOBILE_MEDIA_QUERY в configurator-ui.js
   (applyPriceCardPlacement); значения не должны разъезжаться. */
@media (max-width: 720px) {
  .avtogates-configurator { padding: 0 0 32px; }
  .avtogates-configurator__header { padding: 6px 20px 12px; }
  .avtogates-configurator__title { font-size: 26px; }
  .avtogates-configurator__lead { display: none; }
  /* position: sticky у грид-элемента «липнет» только в пределах его собственной строки грида —
     в один столбец .scene-col и .panel оказывались каждый в своей строке высотой ровно в свой
     контент, и сцене было некуда «прилипать» (уезжала вместе со страницей). Flex-колонка вместо
     грида даёт им общий containing block на всю высоту блока — сцена остаётся закреплённой,
     пока под ней прокручивается panel. align-items: stretch — оба блока на всю ширину, как в
     обычном потоке (базовое правило .grid — align-items: start, оно только для десктопной
     двухколоночной раскладки). */
  .avtogates-configurator__grid { display: flex; flex-direction: column; align-items: stretch; }
  .avtogates-configurator__scene-col { position: sticky; top: 0; z-index: 2; background: var(--ag-paper); padding-bottom: 10px; gap: 8px; }
  .avtogates-configurator__price { font-size: 30px; }
  /* Компактная строка цены — видна только здесь, в липком блоке сцены (владелец, 16.09.2026:
     закреплённой снизу панели цены на мобильном больше нет — она занимала ~1/4 экрана и
     перекрывалась чужой закреплённой кнопкой темы «Обсудить участок»; полная карточка теперь
     стоит после разделов, см. правило .price-card ниже и applyPriceCardPlacement() в JS). */
  .avtogates-configurator__scene-price { display: flex; min-height: 44px; padding: 0 20px; }
  .avtogates-configurator__scene-price [data-scene-price-value] { font: 400 20px var(--ag-font-price); letter-spacing: -.02em; }
  /* Кнопка у цены в липком блоке: во всю ширину, 14px и 12px отступы — подпись «Оставить телефон — менеджер
     посчитает» помещается в одну строку на 375px, блок вырастает ровно на одну кнопку (44px + зазор 8px). */
  .avtogates-configurator__quote-cta--compact:not([hidden]) { display: block; width: 100%; margin-top: 0; padding: 12px; min-height: 44px; font-size: 14px; }
  .avtogates-configurator__quote-cta--card { display: none; }
  /* Строка «что дальше» под кнопкой в липком блоке: видна, пока видна сама кнопка (hidden ставит syncQuoteCta). */
  .avtogates-configurator__quote-cta-note--compact:not([hidden]) { display: block; max-width: none; margin: 0; padding: 0 20px; text-align: center; font-size: 11px; }
  .avtogates-configurator__quote-cta-note--card { display: none; }
  .avtogates-configurator__panel { padding: 16px 20px 24px; gap: 24px; }
  .avtogates-configurator__sections { gap: 24px; }
  .avtogates-configurator__section { gap: 10px; }
  .avtogates-configurator__section-label { font-size: 11px; }
  /* Полная карточка цены — обычный блок в потоке, последний ребёнок [data-panel]
     (applyPriceCardPlacement() в configurator-ui.js переносит её туда по этому же медиазапросу).
     Больше не position: fixed — раньше эта панель перекрывала чужую закреплённую кнопку темы
     сайта «Обсудить участок» и наоборот. Раскладка — колонка (label+цена, кнопка на всю ширину,
     ссылка по центру под ней), а не строка: в строке кнопка и ссылка не помещались и обрезались. */
  .avtogates-configurator__price-card { flex-direction: column; align-items: stretch; gap: 12px; padding: 20px; border-top: 1px solid var(--ag-line); }
  .avtogates-configurator__price-main { flex: none; }
  .avtogates-configurator__price-actions { flex-direction: column; align-items: center; width: 100%; gap: 12px; }
  .avtogates-configurator__price-actions .avtogates-configurator__button--primary { width: 100%; padding: 16px; }
  .avtogates-configurator__price-actions .avtogates-configurator__link-button { justify-content: center; width: 100%; font-size: 13px; }
  .avtogates-configurator__button--full { width: 100%; }
  .avtogates-configurator__swatch { width: 46px; height: 46px; }
  /* Размеры на телефоне (макет 09.10.2026): пять кнопок в ряду (3,5 / 4 / 4,5 / 5 / 5,5 …), «Свой размер» в
     две колонки; цель касания 44px. Ползунок точного значения скрыт, пока не нажат «Свой размер». */
  .avtogates-configurator__size-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
  .avtogates-configurator__size-button { padding: 8px 2px; font-size: 14px; }
  .avtogates-configurator__size-button--custom { font-size: 13px; }
  .avtogates-configurator__size-slider[data-collapsed="true"] { display: none; }
  .avtogates-configurator__extras { gap: 20px; }
  /* Выноски — раздельные, как на десктопе (владелец на реальном телефоне: объединённая мобильная
     бирка не показывала высоту проёма отдельно от ширины). Шрифт остаётся уменьшенным. */
  .avtogates-configurator__dim-label { font-size: 11px; }
  .avtogates-configurator__dim-direction { bottom: 8%; font-size: 11px; }
  .avtogates-configurator__field-grid { grid-template-columns: 1fr; }
  .avtogates-configurator__field { gap: 10px; }
  .avtogates-configurator__summary-row { padding: 9px 0; }
  .avtogates-configurator__summary-row--price dd { font-size: 24px; }
  .avtogates-configurator__overlay { align-items: flex-end; padding: 0; }
  .avtogates-configurator__modal { max-width: none; max-height: calc(100dvh - 64px); padding: 18px 20px 24px; gap: 14px; }
  /* Форма заявки на 375×667: заголовок, свёрнутая сводка, имя, телефон, «Показать больше»,
     согласие и кнопка отправки помещаются в один экран без прокрутки (WEB-2026-10-03-01) —
     поэтому в модалке уплотнены шапка, зазоры и подписи полей. */
  .avtogates-configurator__modal h3 { font-size: 22px; }
  .avtogates-configurator__modal-header { gap: 8px; }
  .avtogates-configurator__modal-header .avtogates-configurator__eyebrow { margin: 0 0 4px; }
  .avtogates-configurator__modal .avtogates-configurator__form { gap: 14px; }
  .avtogates-configurator__modal .avtogates-configurator__field-grid { gap: 12px; }
  .avtogates-configurator__modal .avtogates-configurator__field { gap: 6px; }
  /* Пустой статус не занимает строку и не добавляет лишний зазор flex-колонки. */
  .avtogates-configurator__modal .avtogates-configurator__status:empty { min-height: 0; margin: -7px 0; }
  .avtogates-configurator__config-hint { font-size: 12px; }
  /* Приёмка на dev.avtogates.ru (375×812): кнопка удаления фото в модалке заявки была 32×32 —
     меньше зоны касания 44px (docs/design.md → Components → Фокус). Десктопный размер (32px,
     рядом с крупными 120px миниатюрами) не трогаем — только мобильный. */
  .avtogates-configurator__photo-grid button { min-width: 44px; min-height: 44px; }
  .avtogates-configurator__dropzone { padding: 14px 16px; }
}
