/* Оформление страницы расчёта раскроя листа.
 *
 * ## Что здесь есть и чего здесь нет
 *
 * Палитра, гарнитура, кегли, поля, кнопки, таблицы и справка живут в общем
 * листе `ax-oblik.css`, перенесённом из ProfileCut Optimizer (документ
 * «Облик…» от 19.08.2026). Здесь — только то, чего у соседа нет: карта
 * раскроя, правимая ведомость, листы по раскроям, правовые страницы, подвал
 * приложения.
 *
 * **Своих цветов не заводится.** Всё берётся переменными общего листа. Прежний
 * фон `#F4F6F8` и зелёный `#1F6B3A` были вне палитры сайта, причём зелёный не
 * совпадал и с `--ax-color-success` (`#3D8B5F`): за указатель состояния он не
 * читался.
 *
 * **Насыщенности не существует.** У гарнитуры OpenGost Type B одно начертание;
 * `font-weight: 600` заставлял браузер подделывать полужирный утолщением
 * контура, и на тонком чертёжном шрифте это расплывалось. Выделение —
 * разрядкой, цветом и кеглем. Стережётся проверкой `check_look.py`.
 *
 * Стандарт справочной системы, ТРЕБОВАНИЕ 1.1.2: подсказка держится до
 * закрытия и переставляется при прокрутке — она не всплывающая по наведению.
 * Наведение непригодно: на сенсорном экране его нет, а читать длинный текст,
 * удерживая указатель, неудобно.
 */

/* --- Ссылка обхода ------------------------------------------------------
 *
 * «Перейти к основному содержимому» — первая ссылка шапки сайта. Она для
 * клавиатуры и чтения с экрана: нажал Tab, попал сразу к работе, минуя меню.
 * Указателем по ней не ходят, и **видна она быть не должна**.
 *
 * Правила скрытия не оказалось ни у нас, ни в `app.css` образца: оно живёт в
 * собственных стилях темы сайта, которых мы не подключаем. Разметка от сайта
 * пришла, стиль — нет, и ссылка встала посреди страницы.
 *
 * ## Почему не `display: none`
 *
 * Скрытая так ссылка исчезает и для чтения с экрана — то есть перестаёт
 * делать то единственное, ради чего заведена. Требование проекта сайта (2.2 их
 * ответа) — чтобы она работала, а не чтобы её не было видно.
 *
 * Приём: ссылка уводится за верхний край окна и возвращается при получении
 * клавиатурного внимания. Для чтения с экрана она всё это время на месте.
 *
 * ## Имя класса названо сайтом 21.08.2026
 *
 * `ax-visually-hidden`. Прежде правило писалось по трём общепринятым именам
 * сразу и по признаку адреса перехода — своё имя было неизвестно.
 *
 * **Угаданные имена оставлены**, и это не небрежность: разметку отдаёт сайт, и
 * при следующей правке темы класс может смениться. Признак по адресу
 * (`a[href="#ax-main-content"]`) сработает при любом имени — он и есть
 * настоящий заслон, а перечень имён лишь делает правило точнее.
 */
.ax-visually-hidden,
.skip-link,
.screen-reader-text,
.ax-header__skip,
a[href="#ax-main-content"] {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.ax-visually-hidden:focus,
.skip-link:focus,
.screen-reader-text:focus,
.ax-header__skip:focus,
a[href="#ax-main-content"]:focus {
  position: fixed;
  left: 12px;
  top: 12px;
  width: auto;
  height: auto;
  z-index: 1000;
  padding: 10px 16px;
  background: var(--ax-color-text);
  color: var(--ax-color-bg);
  border-radius: var(--ax-radius-base);
  text-decoration: none;
}

/* --- Шапка приложения --------------------------------------------------
 *
 * Это шапка ПРОГРАММЫ, а не сайта. Шапка сайта (`ax-header`) живёт в теме, и
 * сюда она ещё не надета: разметка запрошена у проекта сайта. Пока её нет,
 * название программы стоит первым в рабочей колонке.
 *
 * Правило `header` из общего листа делает шапку липкой полосой во всю ширину —
 * это шапка соседа, с переключателем языка и отметкой редакции. У нас в ней
 * заголовок и подзаголовок, и липкость им не нужна: они уезжают вместе со
 * страницей.
 */
/* Шапка приложения — правила ПЕРЕНЕСЕНЫ, здесь только то, чего в заготовке
 * нет.
 *
 * Выравнивание, кегли, отступы и место номера редакции задаёт общий слой
 * (раздел «ШАПКА ПРИЛОЖЕНИЯ» заготовки редакции 5). Повторять их здесь
 * значило бы завести второе место для одной величины: правка у составителя
 * пришла бы переносом, а наша осталась бы поверх и тихо взяла верх.
 */
.intro {
  padding: 14px 0 4px;
}

/* Условия расчёта — строка в ТЕЛЕ страницы, над карточкой работы.
 *
 * Прежде стояла четвёртой строкой шапки под именем `.intro__terms`. Решением
 * Правообладателя от 23.08.2026 условия из шапки вынесены: шапка называет
 * программу и её назначение, и только их.
 *
 * Имя своё, не `intro__*`: строка перестала быть частью общей шапки, и носить
 * её имя значило бы обещать, что заготовка ею занимается. Она ею не
 * занимается и не будет.
 */
.условия-расчёта {
  margin: 0 auto 14px;
  max-width: var(--pco-work-max);
  font-size: 17px;
  text-align: center;
  color: var(--text-muted);
}

/* Заголовок ВНУТРЕННЕЙ страницы — оферта, тарифы, реквизиты, библиотека.
 *
 * Общая шапка приложения (`.intro`) — только у главной: она называет
 * программу и её назначение. У внутренних страниц заголовок свой, с
 * крошками, и выравнивать его по середине незачем — читают его как заголовок
 * раздела, а не как имя изделия.
 *
 * Правило возвращено отдельно 23.08.2026: до этого дня оно звалось `.шапка` и
 * служило обоим случаям разом. Разведя их, легко было бы оставить внутренние
 * страницы без отступов и с кеглем `body` — незаметно, потому что отказа
 * такое не даёт.
 */
.шапка {
  position: static;
  display: block;
  padding: 14px 0 4px;
  background: transparent;
}
.шапка h1 { margin: 0; font-size: 28px; letter-spacing: .03em; line-height: 1.2; }

/* Строчный девиз: кегль ТОТ ЖЕ, что у назначения программы.
 *
 * Требование заготовки относительное — «тот же, что у `.intro__lead`». Теперь
 * оба берут одно и то же выражение, и связь эта записана, а не держится на
 * совпадении чисел.
 */
.ax-shell__motto-inline { font-size: clamp(20px, 2.6vw, 28px); }

.карта { max-width: var(--pco-work-max); margin-inline: auto; }

section + section { margin-top: 22px; }

/* --- Поля ---------------------------------------------------------------
 *
 * `.поле` — это `label`, обнимающая подпись и поле ввода. Правило общего листа
 * красит `label` приглушённым: подпись так и задумана, а введённое значение
 * обязано быть в основном цвете, иначе оно читается хуже подписи к нему.
 */
/* Поля соразмерны содержимому, а не растянуты поровну (решение 24.08.2026).
 *
 * Прежде всякое поле тянулось `flex: 1 1 190px` — то есть занимало равную
 * долю строки независимо от того, что в него вводят. Число «5» получало ту же
 * ширину, что марка материала, и строка выглядела разлаженной: короткие поля
 * пустовали, длинные жались.
 *
 * Теперь ширина задаётся классом по роду величины. Умолчание оставлено
 * прежним: поле без класса ведёт себя как раньше, и ни одна страница не
 * ломается от того, что класс ей не проставили.
 */
/* Строка выравнивается по НИЖНЕЙ линии окон ввода, а не по верху подписей
 * (решение Правообладателя от 02.09.2026).
 *
 * Подписи полей бывают в одну строку и в две — «Зазор между деталями, мм»
 * переносится, «Поля листа, мм» нет. При выравнивании по верху окна ввода
 * оказывались на разной высоте, и строка выглядела ступенчатой.
 *
 * `flex-end` ставит поля так, чтобы совпали их низы: подписи растут вверх,
 * а окна стоят на одной линии. Это и есть та линия, по которой человек
 * читает форму. */
.строка {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-end;
}

/* Подпись прижата к низу своего места: между нею и окном ввода остаётся
 * постоянный просвет независимо от числа строк в подписи. */
.поле > span {
  display: flex;
  align-items: flex-end;
  min-height: 2.6em;
}
.поле { flex: 1 1 190px; margin-bottom: 12px; }

/* Число в миллиметрах: пять знаков и запас. */
.поле.число { flex: 0 0 118px; }
/* Перечисление: ширина по самому длинному названию. */
.поле.перечень { flex: 1 1 220px; }
/* Редакция: в названии цена и число контуров — самое длинное на форме. */
.поле.широкое { flex: 1 1 320px; }
/* Примечания заказчика — во всю ширину строки.
 *
 * Решение Правообладателя от 13.09.2026. Поле стояло гибким наравне с
 * прочими и занимало треть строки, а текст в него пишут длинный: марка
 * проката с конкретного завода, требование к кромке, срок, номер заказа.
 * Человек растягивал его рукой за уголок при всяком расчёте.
 *
 * `flex-basis: 100%` — а не `width`: строка `.строка` живёт по гибкой
 * раскладке, и ширина, заданная мимо неё, спорила бы с переносом. */
.поле.во-всю-строку { flex: 1 1 100%; }
.поле.во-всю-строку textarea { width: 100%; min-height: 5.2em; resize: vertical; }
/* Прежнее правило подписи снято: оно ставило `display: block` и перебивало
 * выравнивание по нижней линии. Отступ задан просветом в `.поле > span`. */
.поле > span { margin-bottom: 4px; gap: 6px; }
.поле input, .поле select { color: var(--text-main); }
.поле small { display: block; margin-top: 4px; color: var(--text-muted); font-size: 14px; }
.поле.узкое { max-width: 130px; }

.флажки { gap: 22px; }
.флажок { display: flex; align-items: center; gap: 8px; }
.флажок span { color: var(--text-main); }

/* Значок на золотой кнопке: рамка и знак графитом. Приглушённый серый общего
   листа на золоте не читается. */
.знак.светлый {
  border-color: rgba(39, 51, 65, .45);
  background: transparent;
  color: var(--ax-color-text);
}

.действия { display: flex; align-items: center; gap: 16px; margin-top: 20px; }
.счётчик { color: var(--text-muted); font-size: 15px; }

/* Строка состояния разбора: сообщение о ходе работы, а не результат. Золотая
   грань слева связывает её с прочими выделениями страницы. */
.разбор-состояние {
  margin: 12px 0 0;
  padding: 8px 12px;
  background: rgba(220, 165, 48, .12);
  border-left: 3px solid var(--accent);
  border-radius: var(--ax-radius-base);
  font-size: 16px;
}

/* --- Правимая ведомость ------------------------------------------------ */

.сводка { color: var(--text-muted); margin: 4px 0 10px; }
/* Строка сводки и кнопки «Очистить спецификацию» (выпуск 3.2.10): сводка
   слева, необратимое действие справа — в стороне от рабочих кнопок. */
.спец-шапка {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 8px 16px;
}
.очистка-задания { display: flex; gap: 8px; align-items: center; margin: 4px 0 10px; }
#очистить_задание:hover { border-color: var(--danger); color: var(--danger); }

.спец-всем {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin: 12px 0 18px;
  padding: 12px 14px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
}
.спец-всем-подпись { align-self: center; font-weight: 600; }
.спец-всем .поле { margin-bottom: 0; }

.спец-таблица th { white-space: nowrap; }

/* Ровные цифры: столбцы размеров и количества читаются сверкой сверху вниз, и
   разнобой в ширине знаков этому мешает. */
.спец-таблица .число,
.раскрои-таблица .число {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.спец-таблица tr:hover td { background: var(--bg-soft); }

/* Поля правки в таблице. Ширина задана ЧИСЛОМ ЗНАКОВ, которое обязано в них
   поместиться: в толщину пять («1250,5»), в количество четыре, в марку
   восемь («09Г2С-15»). Поднимется кегль таблицы — эти числа обязаны
   подняться вместе с ним, иначе текст перестанет помещаться, причём молча.
   Соразмерность стережётся проверкой `check_look.py`. */
.спец-таблица input.правка,
.раскрои-таблица input.лист { width: 82px; }
.спец-таблица input.правка-марка { width: 118px; }

/* Источник величины. Пометка стоит рядом со значением, а не отдельным
   столбцом: столбец пришлось бы читать, а знак виден сам.
   Вес не задаётся — жирного начертания у гарнитуры нет; выделение разрядкой. */
.источник { margin-left: 5px; cursor: help; }
.источник-умолчание {
  /* Цвет внимания, а не опасности.
   *
   * Замечание Правообладателя от 24.08.2026: «что за непонятные красные знаки
   * вопроса?». Пометка означает «в имени файла не указано — принято по
   * умолчанию»: это осторожность, а не ошибка. Красный — цвет опасности, и
   * человек читает его как отказ, которого нет.
   *
   * Величина при этом правильная и расчёт пойдёт; сказать надо лишь, что взята
   * она не из чертежа. */
  color: var(--ax-color-accent);
  letter-spacing: .06em;
}
.источник-вами { color: var(--success); }

/* Прежние пометки ведомости (до правимых полей). Оставлены: разметка отказов
   и старые снимки на них ссылаются. */
.по-умолчанию, .не-определена { color: var(--danger); cursor: help; }

.раскрои-таблица { margin-top: 8px; }

/* --- Итог: варианты мер успеха ---------------------------------------- */

/* Раскрои идут СТОЛБЦОМ, карточки внутри раскроя — рядом.
 *
 * Прежде заголовки и карточки всех раскроев лежали в одном ряду с переносом.
 * Спрятанная карточка освобождала место, и в него вставала карточка чужого
 * раскроя, а заголовок оказывался сбоку от карт. Теперь перенос идёт внутри
 * блока, и чужому в нём взяться неоткуда. */
.варианты { display: flex; flex-direction: column; gap: 22px; }

.раскрой-блок {
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
  padding: 14px 16px 16px;
}
.варианты-ряд { display: flex; gap: 16px; flex-wrap: wrap; }

.вариант {
  flex: 1 1 340px;
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
  padding: 16px 18px;
  background: var(--bg-panel);
}
.вариант h3 { margin: 0 0 4px; font-size: 20px; font-weight: 600; }
.вариант .кому { color: var(--text-muted); font-size: 15px; margin: 0 0 12px; }
.вариант dl {
  display: grid; grid-template-columns: auto 1fr; gap: 5px 12px;
  margin: 0 0 14px; font-size: 16px;
}
.вариант dt { color: var(--text-muted); }
.вариант dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.вариант .главная { width: 100%; }

/* Заголовок раскроя показывается, только когда раскроев больше одного: при
   одном он был бы шумом. Раскрои разной марки или толщины — разные задания на
   станок, и путать их нельзя. */
/* Заголовок лежит ВНУТРИ блока своего раскроя и сверху: к какой карте
   относится «1,5 мм · деталей 3», должно читаться, а не додумываться. */
.раскрой-заголовок { margin: 0 0 12px; font-size: 20px; font-weight: 600; }

/* Лист называется у самой карты: раскроев несколько, листы у них разные, и
   размер из раздела 2 к этой карте может не относиться вовсе. */
.лист-подпись { margin: 4px 0 10px; color: var(--text-muted); font-size: 16px; }

.оборвано { color: var(--warning); font-size: 16px; margin: 0 0 10px; }
.сноска { color: var(--text-muted); font-size: 15px; margin-bottom: 0; }

.отказ { border-color: var(--danger); }
.отказ h2 { color: var(--danger); }
.отказ li { margin-bottom: 8px; }
.отказ .знак { border-color: var(--danger); color: var(--danger); }

/* «Скрыто» прячет ВСЕГДА, какое бы правило вида ни стояло у элемента ниже.
 *
 * Выпуск 3.2.9, реестр 28.2. Правило `.ожидание-справка { display: flex }`
 * стоит в этом листе НИЖЕ, весит столько же — и перебивало `.скрыто`: знак
 * справки ожидания расчёта стоял под формой всегда, одиноким «?» без
 * подписи (снимок Правообладателя 02.10.2026). Так было не позднее чем с
 * выпуска 3.2.4. Порядок правил в листе — не защита: всякое новое правило
 * вида с `display`, поставленное ниже, повторило бы беду молча.
 *
 * `!important` здесь — единственное в листе, и намеренно: «скрыто» — не
 * оформление, а состояние, и состояние главнее оформления. Стережёт
 * `check_hidden`: всякий элемент с этим классом на отданной странице не
 * виден. */
.скрыто { display: none !important; }

/* --- Подсказка --------------------------------------------------------
 *
 * Пузырь оформлен общим листом: тёмная плашка, видимая золотая черта,
 * `position: fixed`. Здесь — только то, чего у соседа в разметке нет: кнопка
 * закрытия и предел высоты расширенной части.
 *
 * Расширенная часть набирается с сохранением переводов строк: статьи справки
 * разбиты на абзацы, и склеенные в один поток они читаются простынёй.
 */
.подсказка .краткая { padding-right: 18px; }
.подсказка .расширенная {
  white-space: pre-line;
  max-height: 340px;
  overflow-y: auto;
  font-size: 15px;
}
.подсказка .закрыть {
  position: absolute; top: 4px; right: 7px;
  border: 0; background: none; font-size: 20px; line-height: 1;
  color: var(--ax-color-bg); cursor: pointer;
}

/* --- Карта раскроя ----------------------------------------------------
 *
 * Тёмная подложка листа выбрана не для вида: на ней различимы и контуры
 * деталей, и наложения, если они появятся. На белом фоне тонкая линия поверх
 * другой такой же незаметна, и дефект раскладки прошёл бы мимо глаза.
 *
 * Цвета — из палитры: лист графитом, деталь ватманом, обводка золотом.
 * Наложение двух деталей даёт видимую золотую линию поперёк светлого поля —
 * то самое свойство, ради которого подложка и делалась тёмной. Прежние цвета
 * (`#2a3340`, `#1f6b3a`, `#57d98a`) в палитре сайта не значатся вовсе.
 */
.лист-карта { margin: 0 0 12px; position: relative; }

/* ПОЛОСЫ КНОПОК ЛЕЖАТ НА КАРТЕ.
 *
 * Решение Правообладателя от 27.09.2026: «Кнопки наверху, детали внизу.
 * Видно либо детали, либо кнопки».
 *
 * Отчего не липкая полоса: `position: sticky; top: 0` прижимает её к верху
 * окна, а верх окна занят шапкой сайта, высота которой нам не принадлежит
 * (разбор 11.09.2026 — полоса уезжала под шапку и была невидима). Полоса,
 * приклеенная к самой карте, видна всегда, когда видна карта, и не зависит
 * ни от какой чужой величины.
 *
 * Заливка — цвет панели из палитры сайта, своих цветов здесь не заводится.
 * Вписывание по деталям поднимает окно на высоту полос
 * (`запас_под_полосы`), так что детали из-под кнопок выходят.
 */
.полосы-карты {
  position: absolute;
  top: 6px;
  left: 6px;
  right: 6px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
}
.полосы-карты .снаряжение,
.полосы-карты .правки-детали { margin: 0; }
.лист-карта figcaption {
  margin-top: 4px;
  font-size: 15px;
  color: var(--text-muted);
  text-align: center;
}

.карта-раскроя { width: 100%; height: auto; display: block; }
/* Рука над картой — знак того, что её можно тащить.
 * Появляется только на увеличенной: вписанную тащить некуда. */
.карта-раскроя[data-тащится] { cursor: grab; }
.карта-раскроя.тащим { cursor: grabbing; }

/* ТОЛЩИНА ВСЕХ ЛИНИЙ КАРТЫ — ОДИН ПИКСЕЛЬ ЭКРАНА.
 *
 * Решение Правообладателя от 11.09.2026.
 *
 * ## Отчего не в единицах чертежа
 *
 * `stroke-width` считается в единицах картинки, а картинка сжата: лист 1500 мм
 * ширины показывается на 500 единицах. Толщина «1,1» выходила 0,71 пикселя —
 * линия тоньше пикселя, которую браузер размазывает сглаживанием в серое.
 * При увеличении беда оборачивалась другой стороной: на сороковом увеличении
 * та же «1,1» давала 44 пикселя, и деталь тонула в собственной обводке.
 *
 * `vector-effect: non-scaling-stroke` снимает и то и другое: толщина
 * считается в пикселях экрана и от увеличения не зависит.
 *
 * ## Пунктир — тоже в пикселях
 *
 * Замерено в браузере 11.09.2026: `non-scaling-stroke` держит и штрихи.
 * Длина штриха 5 остаётся пятью пикселями на увеличениях от 1 до 40. Это
 * поведение браузера, а не наша выдумка, и оттого замерено, а не выведено.
 *
 * ## Что различает линии, когда толщина у всех одна
 *
 * Цвет, заливка и пунктир. Толщиной различаются только два случая, и оба
 * названы у своих правил: выбранная деталь и дужка поворота. */
.карта-раскроя .лист {
  fill: var(--ax-color-text);
  stroke: rgba(242, 239, 230, .35);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.карта-раскроя .полезная {
  fill: none;
  stroke: rgba(242, 239, 230, .45);
  stroke-width: 1;
  stroke-dasharray: 5 4;
  vector-effect: non-scaling-stroke;
}
.карта-раскроя .остаток {
  fill: rgba(220, 165, 48, .14);
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 8 4;
  vector-effect: non-scaling-stroke;
}
.карта-раскроя .деталь {
  fill: var(--ax-color-bg);
  stroke: var(--accent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.карта-раскроя .отверстие {
  fill: var(--ax-color-text);
  stroke: var(--accent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* Деталь, нарушающая правила размещения (Ф-4.2.12-бис).
 *
 * Отличается ТРЕМЯ признаками разом: цветом обводки, заливкой и штриховым
 * пунктиром. Одного цвета мало — человек с нарушением цветовосприятия
 * (а это каждый двенадцатый мужчина) красное от зелёного не отличит, и
 * нарушение осталось бы для него невидимым.
 *
 * Пунктир виден всем и переживает чёрно-белую печать цехового листа.
 *
 * Толщина в число этих признаков не входила и прежде — оттого с 11.09.2026
 * она здесь такая же, как у всех линий карты. Все три признака на месте. */
.карта-раскроя .деталь.нарушение {
  fill: color-mix(in srgb, var(--danger) 22%, transparent);
  stroke: var(--danger);
  stroke-width: 1;
  stroke-dasharray: 5 3;
  vector-effect: non-scaling-stroke;
}

/* Деталь массива совмещённого реза (ТЗ ред. 16, Ф-4.3.11).
 *
 * Заливка светлее обычной детали — различимо и на чёрно-белой распечатке,
 * без опоры на один цвет. Массив двигается и вращается целиком, и человек
 * должен видеть, какие детали поедут вместе, прежде чем потянет одну. */
.карта-раскроя .деталь.в-массиве {
  fill: color-mix(in srgb, var(--accent) 22%, var(--ax-color-bg));
}

/* Деталь, к стороне которой притянулась ведомая: обводка пунктиром и
 * заливка светлее — видно без опоры на цвет. Толщина — как у всех линий
 * карты, один пиксель экрана (решение Правообладателя от 11.09.2026,
 * `check_map_lines`). */
.карта-раскроя .деталь.клеим {
  fill: color-mix(in srgb, var(--accent) 35%, var(--ax-color-bg));
  stroke-width: 1;
  stroke-dasharray: 4 2;
  vector-effect: non-scaling-stroke;
}

/* Общая кромка, на которую притянулась деталь: отрезок поверх карты.
 *
 * Знак того, ЧТО именно сойдётся в одну линию реза, — до отпускания, пока
 * человек ещё может передумать. Толщина — один пиксель экрана, как у всех
 * линий карты; пунктир отличает её от самого реза, которого ещё нет. */
.карта-раскроя .кромка-притяжки {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 6 3;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Предупреждение о совмещённом резе (решение Правообладателя от
 * 26.09.2026): сведение, а не отказ — оттого без красного. */
.о-совмещённом {
  margin: 8px 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  font-size: 15px;
}

/* Без `nowrap`: полоса правок переносится строками на узком экране, и поле
 * сдвига переносится вместе с ней (`check_width`: запрет переноса — причина
 * не сжиматься). */
.сдвиг-приклейки { font-size: 14px; }
.сдвиг-приклейки-поле { width: 6em; margin-left: 4px; }

.огрубление { margin: 4px 0 12px; font-size: 15px; color: var(--text-muted); }

/* Нарушения размещения и причина отсутствия остатка.
 *
 * Строка нарушений заметна, но не кричит: это не отказ, а сведение. Расчёт
 * состоялся, карта верна, и человеку решать, мириться ли с недобором.
 *
 * Строка об отсутствии остатка — приглушённая: она объясняет пустоту, а не
 * сообщает о беде. */
.нарушения {
  margin: 8px 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  font-size: 15px;
}
/* Доводка вручную: деталь берётся мышью.
 *
 * Указатель-«рука» — единственный знак того, что карту можно править. Без
 * него правка остаётся тайной: человек не станет тянуть картинку, если ничто
 * не намекнуло, что она тянется. */
.карта-раскроя.правится .деталь.подвижная {
  cursor: grab;
}
.карта-раскроя.правится .деталь.подвижная:active {
  cursor: grabbing;
}
/* Выбранная деталь — та, к которой относятся кнопки правки.
 *
 * Отличается ТОЛЩИНОЙ обводки, а не одним цветом: цвет теряется на
 * чёрно-белой распечатке и различим не всем. То же правило, по которому
 * нарушившая деталь помечена ещё и пунктиром. */
/* Работа с выбранным вариантом: второй убран, этот развёрнут.
 *
 * Величина тут — размер карты на экране, и она решает, работает доводка или
 * нет: на карте шириною в половину колонки деталь под указателем мельче
 * самого указателя. Оттого разворот — не украшение. */
.вариант.убран {
  display: none;
}
/* Взятый в работу вариант занимает ВЕСЬ ряд своего блока.
   Прежде здесь стояло `grid-column: 1 / -1` — свойство сетки, а ряд устроен
   гибкой раскладкой, и оно не делало ничего: карта оставалась в половину
   ширины, а на такой карте деталь под указателем мельче самого указателя. */
.вариант.в-работе {
  flex: 1 1 100%;
  max-width: none;
}
.вариант.в-работе .карта-раскроя {
  width: 100%;
  height: auto;
  /* 62 % высоты окна, а не 78: над картой стоит строка о совмещённом резе с
     предупреждением, и при 78 % карта с полосами не помещалась в окно целиком
     — человек прокручивал страницу и терял из виду то кнопки, то детали
     (замечание Правообладателя от 27.09.2026). */
  max-height: 62vh;
}
.снаряжение {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 10px 0 8px;
}
/* Липкой полоса БЫЛА и оттого пропадала.
 *
 * `position: sticky; top: 0` прижимает её к верху окна — а верх окна занят
 * шапкой сайта, которая нам не принадлежит и высота которой нам неизвестна.
 * Полоса уезжала под шапку и была невидима: Правообладатель искал увеличение
 * и не нашёл. Величина, от которой зависит наш облик, но которой мы не
 * распоряжаемся, в расчёт браться не должна. */
/* Нажатая кнопка обихода отличается ЗАЛИВКОЙ, а не одним цветом рамки:
 * человек обязан видеть, в каком обиходе он находится, и на чёрно-белом
 * экране тоже. */
.правка-кнопка.нажата {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--bg);
}
/* Обвязка выделенной детали — по образцу векторных редакторов.
 *
 * Приём человеку уже знаком, и узнавать его не надо. Оттого и знаки те же:
 * рамка габарита, квадратные метки, косой крест середины при выделении и
 * кружок с точкой при повороте. */
/* Толщина линий обвязки — В ПИКСЕЛЯХ ЭКРАНА.
 *
 * `stroke-width` считается в единицах чертежа, а у карты лист 1500 мм ширины
 * на пятьсот пикселей показа: линия толщиной «2» выходит толщиной в две трети
 * пикселя и не видна вовсе. `vector-effect: non-scaling-stroke` снимает это:
 * толщина перестаёт зависеть от увеличения.
 *
 * Дужки поворота по этой причине и были невидимы — Правообладатель сказал
 * «нет поворота», и он был прав: поворот был, а взяться за него было не за
 * что. */
.карта-раскроя .рамка-габарита {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.карта-раскроя .метка-габарита {
  fill: var(--ink);
  stroke: none;
  pointer-events: none;
}
/* Дужка поворота — единственная часть обвязки, за которую тянут. Оттого
 * только у неё есть указатель и отклик на нажатие. */
/* Дужка рисуется тонкой, а ловится толстой.
 *
 * Видимая толщина — два пикселя, зона нажатия — четырнадцать. Без этого в
 * дужку надо попасть точно, а она тонкая: «не могу зацепить» — это про
 * ширину зоны, а не про размер знака. */
/* Дужка видна ЗАМЕТНО, а не намёком.
 *
 * Правообладатель на живой странице: «нет указателей, что деталь можно
 * вращать». Знак, который надо искать, знаком не работает. Оттого дужка
 * толще обводки рамки и того же цвета, что и всё, за что в этом изделии
 * тянут рукой. */
.карта-раскроя .дужка-поворота {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
/* Ловушка — заливка, а не обводка.
 *
 * Попадание браузер считает по геометрической ширине обводки, и
 * `vector-effect` на этот счёт не влияет: толстая прозрачная обводка в
 * единицах чертежа выходила тоньше пикселя, и нажатие проходило мимо. */
.карта-раскроя .ловушка-дужки {
  fill: rgba(0, 0, 0, 0);
  stroke: none;
  cursor: grab;
}
.карта-раскроя .ловушка-дужки:hover ~ .дужка-поворота,
.карта-раскроя .ловушка-дужки:active ~ .дужка-поворота {
  stroke: var(--accent);
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
}
.карта-раскроя .дужка-поворота:active {
  cursor: grabbing;
}
/* Косой крест середины: один пиксель, как все линии карты (11.09.2026).
 * Прежние 1,2 были остатком от тех времён, когда толщина считалась в
 * единицах чертежа и её подбирали на глаз под одно увеличение. */
.карта-раскроя .середина-габарита {
  vector-effect: non-scaling-stroke;
  stroke: var(--ink);
  stroke-width: 1;
  fill: none;
  pointer-events: none;
}
.карта-раскроя .середина-поворота {
  fill: none;
  vector-effect: non-scaling-stroke;
  stroke: var(--ink);
  stroke-width: 1;
  pointer-events: none;
}
.карта-раскроя .середина-точка {
  fill: var(--ink);
  stroke: none;
  pointer-events: none;
}
/* В обиходе поворота указатель над деталью говорит, что будет поворот, а не
 * перенос. Без этого человек узнаёт об обиходе только по знакам обвязки, а
 * их надо ещё заметить. */
.карта-раскроя .обвязка.вращаем ~ .деталь.выбранная,
.карта-раскроя .деталь.выбранная.вращаем {
  cursor: crosshair;
}
/* Выбранная деталь — единственная линия карты толще пикселя.
 *
 * Отличается ТОЛЩИНОЙ, а не одним цветом: цвет теряется на чёрно-белой
 * распечатке и различим не всем. Три пикселя против одного видны и там.
 * С 11.09.2026 это ровно три пикселя на любом увеличении, а не три единицы
 * чертежа, которые на сороковом увеличении давали сто восемнадцать. */
.карта-раскроя.правится .деталь.выбранная {
  stroke-width: 3;
  stroke: var(--accent);
  vector-effect: non-scaling-stroke;
}
.правки-детали {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 8px 0 6px;
}
.правка-кнопка {
  padding: 4px 10px;
  font-size: 14px;
  font-family: inherit;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  cursor: pointer;
}
.правка-кнопка:hover {
  border-color: var(--accent);
}
.о-правке {
  margin: 6px 0 8px;
  padding: 6px 10px;
  border-left: 3px solid var(--accent);
  font-size: 15px;
}
.о-правке.беда {
  border-left-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}
/* ШАГ 7. ПОЛУЧЕНИЕ РЕЗУЛЬТАТА (выпуск 3.2.41).
 *
 * По образцу ProfileCut Optimizer (снимки Правообладателя 10.10.2026):
 * внутри окна шага — карточка выдачи с пунктирной рамкой, цена крупно и
 * по середине, под нею разбор; условия испытаний — в рамке цвета акцента;
 * строка состояния под кнопкой — своим цветом для хода, готовности и
 * отказа. Цвета — из общего облика и цвета редакции, своих не заводится. */
.знак-бесплатно {
  display: inline-block; vertical-align: middle; margin-left: 8px;
  padding: 2px 8px; border-radius: 4px;
  background: color-mix(in srgb, var(--ax-color-success) 18%, transparent);
  color: var(--ax-color-success);
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
}
.выбор-выдачи { border: 0; margin: 4px 0 14px; padding: 0; }
.выбор-выдачи legend { font-size: 15px; color: var(--text-muted); padding: 0; margin-bottom: 6px; }
.варианты-выдачи { display: flex; flex-direction: column; gap: 6px; }
.вариант-выдачи { display: flex; gap: 8px; align-items: flex-start; font-size: 15px; cursor: pointer; }
.вариант-выдачи input { margin-top: 3px; }
.вариант.выбран-для-выдачи { outline: 2px solid var(--цвет-редакции, var(--accent)); outline-offset: 2px; }
.выдача {
  border: 1px dashed var(--ax-color-border);
  border-radius: 8px;
  background: var(--ax-color-surface);
  padding: 18px 20px;
  text-align: center;
}
.выдача__состав { margin: 0 0 6px; font-size: 14px; color: var(--text-muted); }
.выдача__не-вошли {
  margin: 6px auto; max-width: 640px; font-size: 14px;
  color: var(--ax-color-danger);
}
.выдача__цена { margin: 8px 0 2px; font-size: 30px; line-height: 1.2; }
.выдача__цена .help-icon { vertical-align: middle; }
.выдача__разбор { margin: 0 0 12px; font-size: 15px; }
.выдача__испытания {
  margin: 12px 0; padding: 12px 14px;
  border: 2px solid var(--ax-color-accent); border-radius: 4px;
  background: var(--bg-main); font-size: 15px;
}
.выдача__форматы { margin: 4px 0 14px; font-size: 13px; color: var(--text-muted); }
.выдача__почта { max-width: 520px; margin: 0 auto 10px; text-align: left; }
.выдача__почта label { display: block; }
.выдача__подпись { display: block; font-size: 13px; color: var(--text-muted); margin-bottom: 4px; text-align: center; }
.выдача__почта input { width: 100%; box-sizing: border-box; }
/* Подсказка опечатки в адресе (выпуск 3.2.46): цветом внимания, а не
   опасности — это вопрос, а не отказ. */
.выдача__подсказка {
  margin: 8px 0 0; padding: 8px 12px; border-radius: 4px; text-align: center;
  font-size: 14px; border: 1px solid color-mix(in srgb, var(--warning) 50%, transparent);
  background: color-mix(in srgb, var(--warning) 10%, var(--ax-color-surface));
}
.выдача__подсказка p { margin: 4px 0; }
.выдача__подсказка-выбор { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.выдача__почта label + label { margin-top: 8px; }
/* Письмо со ссылкой на странице заказа (выпуск 3.2.46). */
.письмо-заказа { margin: 18px 0 0; padding-top: 12px; border-top: 1px solid var(--ax-color-border); text-align: left; }
.письмо-заказа h2 { font-size: 17px; margin: 0 0 8px; }
.письмо-заказа form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin: 8px 0; }
.письмо-заказа label { display: flex; flex-direction: column; font-size: 13px; color: var(--text-muted); }
.письмо-заказа__итог { padding: 8px 12px; border-radius: 4px; border: 1px solid color-mix(in srgb, var(--ax-color-danger) 40%, transparent); }
.письмо-заказа__итог--готово { border-color: color-mix(in srgb, var(--ax-color-success) 40%, transparent); }
.письмо-заказа__подсказка {
  padding: 8px 12px; border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--warning) 50%, transparent);
  background: color-mix(in srgb, var(--warning) 10%, var(--ax-color-surface));
}
.выдача__необязательно { margin: 4px 0 0; font-size: 13px; color: var(--text-muted); text-align: center; }
.выдача__согласие {
  display: flex; gap: 8px; align-items: flex-start; text-align: left;
  max-width: 620px; margin: 8px auto; font-size: 14px; line-height: 1.4;
}
.выдача__согласие input { margin-top: 3px; flex: none; }
/* Ссылки в тексте отметки — цветом акцента, как прочие ссылки окна. */
.выдача__согласие a { color: var(--accent); }
.выдача-условия a { color: var(--accent); }
.выдача .состав-данных { max-width: 620px; margin: 6px auto 0; text-align: left; font-size: 14px; }
.выдача__действие { margin: 16px 0 4px; }
.выдача__состояние {
  margin: 10px 0 0; padding: 10px 14px; border-radius: 4px;
  font-size: 15px; text-align: center;
  border: 1px solid var(--ax-color-border);
}
.выдача__состояние ul { margin: 6px 0 0; padding: 0; list-style: none; }
.выдача__состояние li { margin: 2px 0; }
.выдача__состояние a { color: var(--accent); }
.выдача__состояние--ход { background: color-mix(in srgb, var(--accent) 8%, var(--ax-color-surface)); }
.выдача__состояние--готово {
  background: color-mix(in srgb, var(--ax-color-success) 12%, var(--ax-color-surface));
  border-color: color-mix(in srgb, var(--ax-color-success) 40%, transparent);
}
.выдача__состояние--отказ {
  background: color-mix(in srgb, var(--ax-color-danger) 8%, var(--ax-color-surface));
  border-color: color-mix(in srgb, var(--ax-color-danger) 40%, transparent);
  color: var(--ax-color-danger);
}
.выдача-условия { max-width: 720px; margin: 18px auto 0; padding-top: 14px; border-top: 1px solid var(--ax-color-border); font-size: 14px; }
.выдача-условия h3 { font-size: 16px; margin: 0 0 8px; }
.выдача-условия ul { margin: 0; padding-left: 20px; }
.выдача-условия li { margin: 6px 0; line-height: 1.5; }
#получение { font-variant-numeric: tabular-nums; }
/* Заголовки габаритов в две строки: имя сверху, ось снизу.
   Столбец меряется по ширине числа, а не по ширине заголовка. */
.загол-верх, .загол-низ { display: block; line-height: 1.15; }
/* Ось выделяется НЕ весом: у OpenGost Type B единственное начертание, и
   всякий иной вес подставится чужой гарнитурой — буквы поедут посреди
   таблицы. Выделяем цветом, он у гарнитуры один на все веса. */
.загол-низ { color: var(--text-main); }

/* Действия над строкой спецификации: значки без рамки, чтобы не спорить с
   полями ввода в той же строке. */
.действия { white-space: nowrap; }
.значок {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  padding: 2px 5px;
  color: var(--text-muted);
}
.значок:hover { color: var(--text-main); }
/* «Дублировать» — два наложенных квадрата правилами (выпуск 3.2.34): знака
   U+29C9 нет ни в Fira Sans, ни в OpenGost. Цвет — текущий, своего оттенка
   не заводится. */
.рисунок-дубль {
  position: relative; display: inline-block;
  width: 13px; height: 13px; vertical-align: middle;
}
.рисунок-дубль::before, .рисунок-дубль::after {
  content: ""; position: absolute; width: 8px; height: 8px;
  border: 1.5px solid currentColor; border-radius: 1px;
}
.рисунок-дубль::before { left: 0; top: 4px; }
.рисунок-дубль::after { left: 4px; top: 0; background: var(--bg-panel); }
/* «×» у Fira меньше прежнего «✕» — кегль поднят, чтобы значки стояли вровень. */
.значок.убрать { font-size: 21px; }
/* Копия строки помечается: человек должен видеть, что это не отдельный
   чертёж, а дубль. */
tr.копия td:first-child { color: var(--accent); }

.подборы {
  margin: 6px 0 10px;
  font-size: 15px;
  color: var(--text-muted);
}
.нет-остатка {
  margin: 6px 0 4px;
  font-size: 15px;
  color: var(--text-muted);
}

/* --- Состояние очереди ------------------------------------------------
 *
 * Строка появляется между заданием и результатом — там, где пользователь
 * смотрит после нажатия «рассчитать». Она обязана быть заметной без крика:
 * человек уже ждёт, и мигающее пятно на минуту ожидания раздражает.
 *
 * Ровные цифры не украшение: число заданий впереди меняется при каждом
 * опросе, и строка не должна дёргаться по ширине.
 */
.ожидание {
  max-width: var(--pco-work-max);
  margin: 12px auto 0;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.ожидание-справка {
  max-width: var(--pco-work-max);
  margin: 8px auto 0;
  display: flex;
  gap: 12px;
  align-items: center;
}

/* Отказ от ожидания — второстепенное действие, и выглядеть должно
   второстепенно: оформлено как `ghost` общего листа. Золотой, как «главная»,
   оно соперничало бы с расчётом за нажатие. */
.снять:hover { border-color: var(--danger); color: var(--danger); }

/* --- Правовые страницы -------------------------------------------------
 *
 * Оферта, тарифы и реквизиты обязаны быть доступны без входа: банк проверяет
 * сайт перед заключением договора эквайринга, и отсутствие этих страниц —
 * прямое основание для отказа.
 */
.крошки { margin: 0 0 8px; font-size: 16px; color: var(--text-muted); }
.крошки a { color: var(--accent); text-decoration: none; }
.крошки a:hover { text-decoration: underline; }
.редакция { margin: 4px 0 0; font-size: 16px; color: var(--text-muted); }

.правовой { max-width: var(--pco-work-max); margin-inline: auto; }
.правовой h2 { margin: 26px 0 10px; font-size: 18px; font-weight: 600; }
.правовой h2:first-child { margin-top: 0; }
.правовой p { margin: 0 0 10px; text-align: justify; }

.реквизиты, .тарифы { margin: 8px 0 16px; }
.реквизиты th, .тарифы th, .тарифы td { vertical-align: top; }
.реквизиты th { width: 34%; }

.примечание {
  padding: 12px 14px;
  background: var(--bg-soft);
  border-radius: var(--ax-radius-base);
  font-size: 16px;
}

/* --- Подвал приложения ------------------------------------------------
 *
 * Подвал сайта (`ax-footer`) живёт в теме и сюда ещё не надет. Этот — свой, с
 * правовыми ссылками, без которых банк не заключает договор эквайринга.
 */
.подвал {
  max-width: var(--pco-work-max);
  margin: 0 auto;
  padding: 22px 0 40px;
  border-top: 1px solid var(--border);
  font-size: 16px;
  color: var(--text-muted);
}
.подвал-строка { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-bottom: 8px; }
.подвал a { color: var(--accent); text-decoration: none; }
.подвал a:hover { text-decoration: underline; }
.подвал .приглушённая { font-size: 15px; }

/* --- Исключение детали и правка набора листов (выпуск 21) -------------- */

.спец-таблица td.середина,
.раскрои-таблица td.середина { text-align: center; }

/* Исключённая деталь остаётся видимой, но приглушена: вернуть её должно быть
   так же просто, как исключить, а видно это должно быть с одного взгляда. */
.спец-таблица tr.исключена td { opacity: .45; }
.спец-таблица tr.исключена input.правка { text-decoration: line-through; }
.спец-таблица tr.исключена input.правка-участие { opacity: 1; }

/* Кнопки правки набора листов. Мелкие и без заливки: действие частое, но
   второстепенное — соперничать с «Рассчитать» им незачем. */
.лист-кнопка {
  width: 26px;
  height: 26px;
  margin: 0 2px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
  background: var(--bg-panel);
  color: var(--text-main);
  cursor: pointer;
  font: inherit;
  line-height: 1;
}
.лист-кнопка:hover { border-color: var(--accent); color: var(--accent); }
.лист-кнопка.убрать:hover { border-color: var(--danger); color: var(--danger); }

/* --- Параметрическая библиотека (выпуск 23) ---------------------------- */

.чертёж-детали {
  display: flex;
  justify-content: center;
  padding: 12px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
  min-height: 120px;
}

/* Деталь ватманом по графиту — тем же приёмом, что и карта раскроя: на
   тёмном поле видны и контур, и наложения, если они появятся. Здесь
   наложений быть не должно вовсе, но приём тот же, чтобы человек узнавал
   деталь на обеих страницах. */
/* Чертёж детали: тело, обводка, кромка отверстий.
 *
 * С поставкой 2 разметка переменилась: тело детали рисуется ОДНИМ узлом
 * `<path>` с чётно-нечётным правилом, и отверстия в нём — настоящие дыры, а
 * не пятна цвета фона. Прежние правила накрыли бы их: обводка заливалась
 * `--ax-color-bg` и ложилась поверх тела.
 *
 * Правила ниже написаны нами, а не пришли с поставкой: приложенный к ней лист
 * добавляет сетку и штриховую окружность, а `.тело` и `.кромка-отверстий` не
 * объявляет вовсе. Замерено разбором разметки: отрисовка даёт три узла,
 * лист знал об одном. Проекту библиотеки сообщено.
 *
 * `<path>` без правила заливки в SVG **чёрен по умолчанию** — то есть
 * недостающее правило дало бы не бледную деталь, а чёрное пятно.
 */
.деталь-чертёж { max-width: 100%; height: auto; }
.деталь-чертёж .тело path {
  fill: var(--bg-panel);
  stroke: none;
}
.деталь-чертёж .контур polygon {
  fill: none;
  stroke: var(--ax-color-text);
  stroke-width: 1.4;
}
.деталь-чертёж .кромка-отверстий polygon {
  fill: none;
  stroke: var(--ax-color-text);
  stroke-width: 1.1;
}
.деталь-чертёж .выноска {
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 4 3;
}
.деталь-чертёж .размер {
  font-size: 13px;
  fill: var(--text-muted);
  /* Надписи на чертеже — чертёжным шрифтом (выпуск 3.2.36, решение
   * Правообладателя от 09.10.2026). С 3.2.32 по 3.2.35 они наследовали
   * шрифт страницы — Fira Sans. */
  font-family: var(--ax-font-draw);
}

/* Отказ построения показывается ВМЕСТО чертежа: годная деталь на экране
   рядом с сообщением об ошибке читается как «ошибка не про эту деталь». */
.отказ-строка {
  margin: 12px 0 0;
  padding: 8px 12px;
  background: rgba(178, 58, 46, .10);
  border-left: 3px solid var(--danger);
  border-radius: var(--ax-radius-base);
  color: var(--danger);
}


/* ============================================================================
   ВОСПОЛНЕНИЕ ОБЩЕГО СЛОЯ — СНЯТО 23.08.2026
   ============================================================================

   Здесь лежали правила выпуска 36: объявление трёх переменных, карточка блока
   перехода, порог девиза 1322 вместо 1687, снятие наложения и разведение
   липкости.

   **Все они сняты**, потому что редакция 5 заготовки закрыла причину, а не
   следствие: применяются объявленные имена переменных, а выравнивание
   названия по середине задано самой заготовкой и потому перестало быть
   предположением.

   Держать восполнение дольше нужного нельзя — два листа, правящих одно,
   расходятся. Проверка `check_look` сторожит, что применяемые переменные
   объявлены; после переноса они объявлены в общем слое, и наше объявление
   стало бы вторым.

   ЧТО ИЗ ТОГО ВЫПУСКА ОСТАЛОСЬ И ПОЧЕМУ:

   · разведение липкости — девиз уезжает, блок перехода остаётся. Указание
     Правообладателя от 23.08.2026; в заготовке редакции 5 обе колонки
     по-прежнему липкие одним правилом. Оставлено у нас и сообщено составителю;
   · переход в библиотеку — наш, к общему облику отношения не имеет.
   ---------------------------------------------------------------------------- */

/* ============================================================================
   ВРЕМЕННЫЕ ВОСПОЛНЕНИЯ ОБЩЕГО СЛОЯ — СНЯТЫ 23.08.2026
   ============================================================================

   Здесь лежали три правила выпусков 36 и 39:

     · объявление трёх переменных оформления;
     · опора наложенного девиза и назначение ему ячейки сетки;
     · разведение липкости — девиз уезжает, блок перехода остаётся.

   **Все три вошли в общий слой**: первое редакцией 5 заготовки, второе и
   третье — редакцией 7. Держать восполнение дольше нужного нельзя: два листа,
   правящих одно, расходятся, и разойдутся молча.

   Разведение липкости было НАШЕЙ надстройкой; составитель принял её и сделал
   общей. Довод, который мы приводили, записан теперь в самой заготовке: при
   внесении следующей редакции девиз прилипнет снова, а ОТСУТСТВИЕ правила
   прочтётся как «об этом не думали».

   ЧТО ОСТАЛОСЬ НАШИМ И ПОЧЕМУ:

   · условия расчёта — вынесены из шапки в тело страницы решением
     Правообладателя от 23.08.2026. Общим их не делают: шапка называет два
     текста, а третий сделал бы шапки разными;
   · отступ `.intro` — наш, заготовка его не задаёт;
   · переход в параметрическую библиотеку — к общему облику отношения не
     имеет.
   ---------------------------------------------------------------------------- */

/* Переход в параметрическую библиотеку у поля выбора файлов. Приглушён: это
   запасной путь, а не основной, и спорить с полем он не должен. */
.к-библиотеке {
  margin: 10px 0 0;
  font-size: 15px;
  color: var(--text-muted);
}
.к-библиотеке a { color: var(--text); }

/* ПРАВКА К ОБЩЕМУ ФАЙЛУ app/static/style.css
 *
 * Библиотека, поставка 2. Дописать в конец раздела стилей библиотеки.
 * Файл общий (основная сессия), поэтому передаётся текстом, а не заменой.
 *
 * Что добавляется: сетка эскизов на шаге выбора фигуры и штриховая
 * окружность расположения отверстий на чертеже.
 */

/* --- Вкладки групп ---------------------------------------------------- */

.вкладки-групп {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.вкладка-группы {
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.вкладка-группы.выбрана {
  border-color: var(--ax-color-accent);
}

.вкладка-группы .счётчик {
  opacity: .6;
  font-size: .85em;
}

/* --- Сетка эскизов ---------------------------------------------------- */
/*
 * Ширина клетки задана НИЖНИМ пределом, а не числом клеток в ряду: сколько
 * их поместится, решает экран. Задай мы «четыре в ряд», на телефоне клетка
 * стала бы шириной в палец, и эскиз в ней перестал бы читаться — а он и есть
 * весь смысл сетки.
 */
.сетка-фигур {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
}

.клетка-фигуры {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: center;
}

.клетка-фигуры:hover,
.клетка-фигуры:focus-visible {
  border-color: var(--ax-color-accent);
}

.клетка-фигуры__эскиз svg {
  width: 100%;
  height: auto;
  max-height: 170px;
  display: block;
}

.клетка-фигуры__подпись {
  font-size: .82em;
  line-height: 1.25;
  opacity: .85;
}

.страницы {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 12px;
}

/* --- Выбранная фигура -------------------------------------------------- */

.выбранная {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.выбранная__эскиз svg {
  width: 150px;
  height: auto;
  display: block;
}

.выбранная__название {
  margin: 0 0 4px;
}

/* --- Штриховая окружность расположения отверстий ----------------------- */
/*
 * Дефект, найденный осмотром чертежа 23.08.2026: подпись «⌀M» ставилась, а
 * самой окружности не рисовалось — подпись указывала в пустоту и читалась
 * как обозначение ближайшего болтового отверстия.
 *
 * Штрих-пунктир — чертёжная норма для осевых и вспомогательных линий.
 */
.деталь-чертёж .ось-отверстий {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1;
  stroke-dasharray: 8 4 2 4;
  opacity: .7;
}

/* --- Библиотека редакции 3: поиск, редакции, перемычка (выпуск 3.2.25) - */
/*
 * Поисковая строка шире прочих полей: запрос из трёх слов («фланец
 * квадратный 100») не должен прятаться за краем окна ввода.
 */
.строка-поиска { align-items: flex-end; }
.поле-поиска { flex: 1 1 320px; }
.поле-поиска input { width: 100%; }

.ничего-не-найдено {
  margin: 8px 0;
  color: var(--text-muted);
}

.клетка-фигуры__эскиз {
  width: 100%;
  height: 150px;
  object-fit: contain;
  display: block;
}

/* Фигура вне выбранной редакции: приглушена и помечена, но видна и
 * выбирается — перечень виден всем (ТЗ AXT-PLATE-ТЗ-003, Б-2.4). */
.клетка-фигуры.недоступна .клетка-фигуры__эскиз,
.клетка-фигуры.недоступна .клетка-фигуры__подпись {
  opacity: .45;
}
.пометка-редакции {
  font-size: .8em;
  color: var(--text-muted);
}

.выбранная__эскиз img {
  width: 220px;
  height: auto;
  display: block;
}

.поля-параметров .или {
  color: var(--text-muted);
  font-size: .85em;
}

/* Припуск развёртки раздела «Вентиляция»: умолчание типовое, с нормой не
 * сверено (ТЗ AXT-PLATE-ТЗ-003, Б-5.6, Б-7.5) — сказано у самого поля. */
.поля-параметров .пометка-припуска {
  display: block;
  color: var(--text-muted);
  font-size: .8em;
}

/* Ввод из справочника ГОСТ (ТЗ AXT-PLATE-ТЗ-003, Б-7.4): поле выбора
 * типоразмера над параметрами, список строк под ним, пометки у полей. */
.поля-гост { margin: 0 0 12px; }
.выбор-гост {
  position: relative;
  margin: 0 0 10px;
  max-width: 640px;
}
.выбор-гост label { display: block; margin: 0 0 4px; }
.выбор-гост .поле-гост { width: 100%; box-sizing: border-box; }
.список-гост {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 20;
  max-height: 280px;
  overflow-y: auto;
  margin: 2px 0 0;
  padding: 0;
  list-style: none;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--ax-radius-base);
}
.список-гост li {
  padding: 4px 8px;
  cursor: pointer;
}
.список-гост li.активная { background: var(--bg-soft); }
.список-гост li.ещё {
  cursor: default;
  color: var(--text-muted);
  font-size: .85em;
}
.выбор-гост .состав-гост {
  display: block;
  color: var(--text-muted);
  font-size: .8em;
}
.поля-параметров .пометка-гост {
  display: block;
  color: var(--text-muted);
  font-size: .8em;
}
.поля-параметров .пометка-гост.не-по-гост { color: var(--warning); }

/* Строка перемычки — видна при каждом вводе (Б-6.3). */
.строка-перемычки { margin: 8px 0 0; }

.справочные { margin-top: 10px; }
.справочные__заголовок { margin: 0 0 4px; }
.справочные__таблица {
  border-collapse: collapse;
  font-size: .9em;
}
.справочные__таблица th,
.справочные__таблица td {
  padding: 2px 10px 2px 0;
  text-align: left;
  vertical-align: top;
}

/* У развёрток — пара: вид изделия и развёртка (Б-4.7). */
.пара-видов {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}
.пара-видов figure { margin: 0; flex: 1 1 200px; }
.пара-видов figcaption {
  font-size: .8em;
  color: var(--text-muted);
}
/* Чертёж детали — крупно: эскиз построителя приходит в поле 270 × 185 точек,
 * а читать на нём буквы и размеры надо с экрана, не щурясь. */
.чертёж-детали > svg { width: min(100%, 640px); height: auto; }
.пара-видов svg { width: 100%; height: auto; max-height: 420px; }

/* --- Перечень добавленного за приход ---------------------------------- */
/*
 * Что человек добавил в задание, не уходя со страницы. Ошибка в толщине
 * должна быть видна в тот миг, когда сделана, а не после перехода к расчёту.
 */
.добавленное {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.добавленное ul {
  margin: 4px 0 0;
  padding-left: 18px;
  font-size: .85em;
}

.добавленное li { line-height: 1.4; }

/* --- Эскиз детали в строке спецификации ------------------------------- */
/*
 * Клетка узкая и постоянной ширины: столбец, гуляющий по строкам, ломает
 * сверку чисел сверху вниз — а ради неё таблица и заведена.
 *
 * Разметку рисует та же `svg_детали`, что и чертёж на странице построения;
 * узлы у неё те же три, и правила ниже повторяют чертёжные, различаясь лишь
 * толщиной линий: на пятидесяти точках чертёжные 1,4 залили бы деталь
 * сплошной обводкой.
 */
.эскиз-клетка {
  width: 58px;
  padding: 2px 4px;
  text-align: center;
}
.деталь-эскиз {
  width: 50px;
  height: 50px;
  display: block;
  margin: 0 auto;
}
.деталь-эскиз .тело path {
  /* Полупрозрачный тон чернил из палитры — НЕ цвет фона.
   *
   * Дефект выпуска 45: тело заливалось `--bg-panel`, то есть тем же цветом,
   * что и панель под таблицей. Тело сливалось с фоном, отверстие прозрачно —
   * и дыра была неотличима от тела. Проступало это лишь на строке под
   * указателем, где фон меняется на `--bg-soft`.
   *
   * Заливка цветом фона — не дыра, а заплата: ровно то, за что мы правили
   * поставку библиотеки, и повторено нами же через день.
   *
   * Тон обязан отличаться от ОБОИХ фонов строки — покойного и наведённого, —
   * иначе деталь пропадает в одном из двух состояний. Полупрозрачный
   * `--ax-color-border` (чернила при 16 %) ложится поверх любого из них и
   * остаётся виден на обоих; отверстие показывает тот фон, что под ним, и
   * потому читается дырой всегда.
   */
  fill: var(--ax-color-border);
  stroke: none;
}
.деталь-эскиз .контур polygon {
  fill: none;
  stroke: var(--ax-color-text);
  stroke-width: 2.2;
}
.деталь-эскиз .кромка-отверстий polygon {
  fill: none;
  stroke: var(--ax-color-text);
  stroke-width: 1.8;
}

/* Пояснение к пометкам источника под таблицей спецификации. */
.пояснение-пометок {
  margin: 8px 0 0;
  font-size: .9em;
  color: var(--text-muted);
}
.пояснение-пометок .источник { margin-left: 0; margin-right: 2px; }

/* ===== Выпуск 3.0.7: форма по замечаниям Правообладателя от 20.09.2026 =====
 *
 * 1. Шрифт в окнах ввода — тот же ГОСТовский, что у подписей. Окна ввода,
 *    перечни и кнопки шрифта от страницы не наследуют: браузер ставит им
 *    свой (Arial у Chromium), и подпись «Зазор между деталями» стояла
 *    одним шрифтом, а «5» в окне под ней — другим. Сказано `inherit`, а не
 *    имя шрифта: имя задаёт сайт (`--ax-font-base` в ax-oblik.css), и
 *    вписанное здесь разошлось бы с ним при первой его смене. */
.карта input,
.карта select,
.карта textarea,
.карта button,
.карта input::placeholder,
.карта textarea::placeholder {
  font-family: inherit;
}

/* 2. Зазор, поля и ширина реза — одной строкой и одной ширины. Подпись
 *    «Зазор между деталями, мм» не переносится: прежние 118 пикселей рвали
 *    её на две строки, и строка выглядела ступенчатой. 250 пикселей вмещают
 *    и её, и серую надпись «ширина вашего инструмента» целиком. */
.поле.число { flex: 0 0 250px; }
.поле.число > span { white-space: nowrap; }
.поле.число input { width: 100%; box-sizing: border-box; }

/* 3. Флажок «Учитывать эквидистанту» в строке с перечнями — на одной линии
 *    с их окнами. Строка выравнивает по низу (`flex-end`); флажок получает
 *    ту же высоту окна и тот же нижний отступ, что поле, — и встаёт по
 *    середине окон, а не ниже их. Высота окна — переменной, одной на всю
 *    форму. */
.карта { --высота-окна: 38px; }
.карта .поле input:not([type="checkbox"]):not([type="file"]),
.карта .поле select { min-height: var(--высота-окна); box-sizing: border-box; }
.строка > .флажок {
  min-height: var(--высота-окна);
  margin-bottom: 12px;
  white-space: nowrap;
}

/* 4. Выбор файлов и путь в библиотеку — одной строкой. Строка `.строка`
 *    выравнивает по низу: путь в библиотеку встаёт на линию поля файлов.
 *    Поле файлов — по ширине содержимого, а не гибкое: иначе оно забирало бы
 *    всю строку и сталкивало путь в библиотеку вниз. */
.файлы-и-библиотека { align-items: center; }
.файлы-и-библиотека .поле.файлы { flex: 0 0 auto; }
/* Кнопка библиотеки встаёт ровно на одну линию с кнопкой выбора файлов:
 * две кнопки одного вида, разошедшиеся по высоте на дюжину точек, читаются
 * как две разные вещи. Замер 28.09.2026: было 468 и 480. Выпуск 3.2.32:
 * с Fira Sans высота строки подписи иная — замер 571 и 575, отступ снизу
 * 16 → 20 (сторож — `check_edition_menu`, «на одной линии»). */
.файлы-и-библиотека .к-библиотеке { margin: 0 0 12px; align-self: flex-end;
  padding-bottom: 20px; }
.пределы-файлов { display: block; margin: -6px 0 12px; font-size: 14px;
  color: var(--text-muted); }

/* Пустая строка о справочной ширине под окном ширины реза поднимала поле:
 * строка выравнивается по низу, и лишние 4 пикселя пустой строки ставили
 * окно ширины выше окон зазора и полей. Пустая — не занимает места. */
#справочная_ширина:empty { display: none; }


/* Что входит в редакции — под выбором редакции (выпуск 3.1.0). Мелко и
 * спокойно: это справка к выбору, а не второй выбор. */
.состав-редакций { margin: 0.4rem 0 0; font-size: 0.85rem; line-height: 1.4; }
.состав-редакций > div { display: flex; gap: 0.5rem; margin: 0.15rem 0; }
.состав-редакций dt { text-transform: uppercase; font-weight: 600; min-width: 5.5rem; }  /* выпуск 3.2.32: настоящий полужирный Fira Sans */
.состав-редакций dd { margin: 0; }

/* ССЫЛКА «УЗНАТЬ О ПРОГРАММЕ» — в строке назначения, за точкой.
 *
 * Решение Правообладателя от 28.09.2026. Подчёркнута и окрашена цветом
 * выделения: ссылка, не отличимая от текста, не читается как ссылка.
 * Кегль и гарнитура — те же, что у строки назначения: своих величин здесь
 * не заводится (`.intro__lead` общего облика).
 */
.intro__about {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.intro__about:hover { color: var(--accent-hover); }

/* Перечень форматов под назначением и строка ссылки ниже него (выпуск
 * 3.2.32, замечание Правообладателя от 09.10.2026). Форматы — тише
 * назначения: это справка к нему, а не второй заголовок. */
.intro__formats { margin: 6px 0 0; font-size: 17px; color: var(--text-muted); }
.intro__about-line { margin: 10px 0 0; font-size: 19px; }


/* ШАПКА САЙТА СНЯТА — ВЫСОТА ЕЁ РАВНА НУЛЮ (выпуск 3.2.4)
 *
 * Решение Правообладателя от 28.09.2026: со страниц приложения шапка сайта
 * убрана — сайт ещё не заполнен, и меню вело бы на пустые страницы.
 *
 * Величина `--ax-header-height` объявлена в ОБЩЕМ облике и равна там высоте
 * настоящей шапки сайта. Общий лист — один на оба сервиса и на сам сайт;
 * правка в нём сняла бы отступ и у соседа, у которого шапка на месте.
 * Поэтому величина переопределяется ЗДЕСЬ, в своём листе, который
 * подключается вторым: правило то же, а действует только на наших
 * страницах.
 *
 * По этой величине считаются две вещи — поправка якорей
 * (`scroll-margin-top`) и отсчёт липкого блока перехода во второй сервис.
 * Обе получают ноль, и блок встаёт под самый верх окна, отступя 24 точки,
 * как и задумано правилом общего облика.
 */
:root { --ax-header-height: 0px; }


/* СВОЁ МЕНЮ ВЫБОРА РЕДАКЦИИ (выпуск 3.2.4)
 *
 * Решение Правообладателя от 28.09.2026: описание редакции и цена стоят в
 * самом пункте меню. Браузерное меню строку не переносит и обрезает её
 * многоточием (замер: строка Lite — 1509 точек, окно — 1188). Здесь строка
 * переносится, и текст виден целиком.
 *
 * Окно и список повторяют вид полей формы: та же рамка, тот же радиус, тот
 * же кегль и ШРИФТ СТРАНИЦЫ, а не браузера, — правило `check_form_fields`
 * об окнах ввода.
 */
.выбор-редакции { position: relative; }
.выбор-редакции__окно {
  display: flex; width: 100%; gap: 10px; align-items: flex-start;
  text-align: left; padding: 7px 9px; min-height: var(--высота-окна);
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--bg-panel); color: var(--text-main);
  font: inherit; font-size: 16px; line-height: 1.35;
  box-sizing: border-box; cursor: pointer;
}
.выбор-редакции__окно:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -1px;
}
.выбор-редакции__текст { flex: 1 1 auto; }
/* Знак раскрытия рисуется двумя гранями квадрата, повёрнутого на 45°:
 * знака U+2304 в гарнитуре нет, а подставленный запасной гарнитурой встал бы
 * чужим по рисунку и по высоте. Цвет берётся текущий — своего оттенка не
 * заводится. */
.выбор-редакции__знак {
  flex: none; align-self: center;
  width: 9px; height: 9px; margin: 0 2px 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  color: var(--text-muted);
}
.выбор-редакции[data-раскрыт="да"] .выбор-редакции__знак {
  margin: 4px 2px 0; transform: rotate(225deg);
}

.выбор-редакции__список {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px; list-style: none;
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--bg-panel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  max-height: 60vh; overflow-y: auto;
}
.выбор-редакции__список[hidden] { display: none; }
.выбор-редакции__пункт {
  padding: 8px 10px; border-radius: 4px; line-height: 1.35; cursor: pointer;
}
.выбор-редакции__пункт[aria-selected="true"] { background: var(--bg-soft); }
.выбор-редакции__пункт.наведён { outline: 2px solid var(--accent);
  outline-offset: -2px; }
.выбор-редакции__пункт:hover { background: var(--bg-soft); }


/* КНОПКИ ВЫБОРА ФАЙЛОВ И БИБЛИОТЕКИ — ОДНОГО ВИДА, ОБЕ ПО-РУССКИ
 *
 * Решения Правообладателя от 28.09.2026: вид — системной кнопки; «всё
 * должно быть на одном языке».
 *
 * Браузерную кнопку выбора файлов надписывает БРАУЗЕР, а не страница: у
 * иноязычного браузера она читается «Choose Files», и перевести её со
 * страницы нельзя. Поэтому поле файлов спрятано, а нажимается своя кнопка
 * с русской надписью из `app/locales/ru.json`. Вид обеих кнопок — тот же,
 * что у браузерной, чтобы человек узнавал её с первого взгляда.
 */
/* Оттенки браузерной кнопки. Своих цветов в этом листе не заводят — это
 * ЧУЖИЕ цвета, повторяемые намеренно: кнопка обязана читаться как та самая,
 * которую браузер рисует сам. Объявлены здесь одним местом и названы в
 * палитре `check_look` с этим же доводом. */
:root {
  --кнопка-фон: #EFEFEF;
  --кнопка-фон-наведение: #E5E5E5;
  --кнопка-рамка: #767676;
  --кнопка-текст: #000000;
}
.кнопка-как-браузерная {
  display: inline-block;
  font-family: system-ui, "Segoe UI", Arial, sans-serif;
  font-size: 13.33px; line-height: normal;
  padding: 1px 6px;
  border: 1px solid var(--кнопка-рамка); border-radius: 2px;
  background: var(--кнопка-фон); color: var(--кнопка-текст);
  text-decoration: none; cursor: pointer;
}
.кнопка-как-браузерная:hover { background: var(--кнопка-фон-наведение); }
.кнопка-как-браузерная:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.файлы .поле-файлов { display: flex; align-items: baseline; gap: 8px; }
.файлы input[type="file"].спрятан,
#шаг_файлов input[type="file"].спрятан {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Надпись о выбранных файлах — тем же шрифтом и кеглем, каким её
 * писал браузер: она стоит рядом с кнопкой и читается как её часть. */
.выбрано-файлов {
  font-family: system-ui, "Segoe UI", Arial, sans-serif;
  font-size: 13.33px; color: var(--text-muted);
}

/* Разночтения источников (выпуск 3.2.19): строка-сводка и значения на
   выбор под пустым полем. */
.разночтения-сводка {
  margin: 6px 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--danger);
  background: var(--bg-soft);
}
/* Имена классов свои, не «вариант»: тот занят карточками вариантов
   раскроя, и правило отсюда перекроило бы их ряд. */
.на-выбор { display: block; margin-top: 4px; }
.на-выбор__значение {
  display: inline-block;
  margin: 2px 4px 0 0;
  padding: 1px 6px;
  font-size: 0.85em;
  border: 1px solid var(--danger);
  background: var(--bg-panel);
  cursor: pointer;
}
.на-выбор__значение:hover,
.на-выбор__значение:focus-visible { background: var(--bg-soft); }
.источник-разночтение { color: var(--danger); }
.источник-надпись { color: var(--accent); }
.источник-таблица { color: var(--accent); }

/* Таблица деталей (выпуск 3.2.20): строка о прочтении, выбор столбцов,
   свёрнутые списки несопоставленного. */
.таблица-сводка {
  margin: 6px 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: var(--bg-soft);
}
.таблица-столбцы { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.таблица-столбцы label { display: flex; flex-direction: column; }
.таблица-списки { margin-top: 6px; }
.таблица-списки ul { margin: 4px 0; padding-left: 20px; }


/* ОКНА ШАГОВ И ЦВЕТ РЕДАКЦИИ (выпуск 3.2.32)
 *
 * Замечание Правообладателя от 09.10.2026: каждый шаг — в своём окне, рамка
 * со скруглёнными углами цвета выбранной редакции, в верхней границе —
 * плашка с названием редакции; у меню выбора — знаки раскрытия по обеим
 * сторонам и полоса цвета редакции слева. Образец — страница ProfileCut
 * Optimizer (снимок Правообладателя 09.10.2026).
 *
 * Цвета редакций — те, что объявлены общим листом (`--ed-lite`,
 * `--ed-standard`, `--ed-pro`): своих оттенков не заводится. Признак
 * редакции стоит на `main` и меняется меню выбора; без признака рамка —
 * цвета обычной границы.
 */
body[data-edition="lite"],
main[data-edition="lite"]     { --цвет-редакции: var(--ed-lite); }
body[data-edition="standard"],
main[data-edition="standard"] { --цвет-редакции: var(--ed-standard); }
body[data-edition="pro"],
main[data-edition="pro"]      { --цвет-редакции: var(--ed-pro); }

/* Форма больше не рамка: рамки — у шагов внутри неё. */
form.расчёт { max-width: var(--pco-work-max); margin-inline: auto; }

.panel.окно-шага {
  position: relative;
  border: 2px solid var(--цвет-редакции, var(--border));
  border-radius: 12px;
  padding: 26px 22px 20px;
  margin-top: 30px;
  margin-bottom: 0;
}
/* Плашка садится на верхнюю границу окна посередине. Фон — цвет страницы:
 * им плашка «прорезает» рамку, как у образца. */
.плашка-редакции {
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -50%);
  padding: 1px 12px;
  background: var(--bg-main);
  border: 1px solid var(--цвет-редакции, var(--border));
  border-radius: 6px;
  color: var(--цвет-редакции, var(--text-muted));
  font-size: 14px; line-height: 1.3; width: max-content;
}
/* Заголовок шага — одной строкой текста: «Шаг 1.» и название переносятся
 * вместе, а не двумя столбцами, как у гибкого ряда на узком экране. */
.panel.окно-шага h2 { display: block; }
/* Каталог (выпуск 3.2.39): строка о редакции под заголовком — выбранная на
 * странице расчёта, цветом редакции; своего выбора у каталога нет. */
.редакция-каталога { margin: 4px 0 0; font-size: 16px; color: var(--text-muted); }
.редакция-каталога b { color: var(--цвет-редакции, var(--text-main)); }
.редакция-каталога a { color: var(--accent); text-decoration: none; }
.редакция-каталога a:hover { text-decoration: underline; }
.panel.окно-шага h2 .help-icon { vertical-align: middle; margin-left: 6px; }

/* «Шаг 1.» — словом и номером, а не кружком с цифрой. */
.panel h2 .step {
  background: none; color: var(--цвет-редакции, var(--text-main));
  width: auto; height: auto; border-radius: 0;
  display: inline; font-size: inherit; letter-spacing: 0;
}

/* Меню выбора: полоса цвета редакции слева, знаки раскрытия с обеих
 * сторон — цветом редакции. */
.выбор-редакции__окно {
  border-left: 4px solid var(--цвет-редакции, var(--border));
  align-items: center;
}
.выбор-редакции__знак { color: var(--цвет-редакции, var(--text-muted)); }


/* ТАБЛИЧНЫЕ ЦИФРЫ (выпуск 3.2.32)
 *
 * У Fira Sans цифры по умолчанию разной ширины: единица у́же нуля на 22 %
 * (письмо проекта сайта от 09.10.2026, 5.1), и столбец чисел пошёл бы
 * лестницей. Признак `tnum` есть в файле и включается только там, где числа
 * стоят друг под другом: таблицы, поля чисел, карточки вариантов и итог. В
 * обычном тексте пропорциональные цифры читаются лучше. */
table, input[type="number"], .вариант, #итог {
  font-variant-numeric: tabular-nums;
}

/* Подсказка в поле ширины реза — мельче текста поля (выпуск 3.2.32): с Fira
 * Sans строка «ширина вашего инструмента» шире поля при трёх полях в ряд и
 * обрезалась на «инструмент». Само значение — прежним кеглем. */
#ширина_реза::placeholder { font-size: 14px; }


/* ОКНО «ИДЁТ РАСЧЁТ» (выпуск 3.2.49)
 *
 * Поручение Правообладателя от 17.10.2026: заставка программы с бегунком —
 * окно появляется, как только запускается расчёт, и убирается, когда расчёт
 * закончен, до показа итогов. Расположение дорожки и строки — по образцу
 * окна раскроя профиля (те же доли рисунка 1040 × 640): нижняя левая часть
 * заставки свободна от рисунка и надписей.
 *
 * Цвета бегунка, строки и затемнения — цвета САМОГО РИСУНКА («Optimizer» —
 * от синего к бирюзовому; серый подписи форматов; тёмно-синий фона), а не
 * палитры страницы: окно — картинка, и бегунок на ней чужим цветом
 * читался бы наклейкой, а затемнение цвета фона сливается с краем рисунка.
 * Объявлены одним местом
 * — переменными `--заставка-*`; в палитре проверки облика они названы
 * поимённо (`tools/check_look.py`, ПАЛИТРА).
 *
 * Скрытие — общим `.скрыто` с !important (реестр 28.2): правило вида с
 * `display: flex` ниже его не перебивает. */
.окно-расчёта {
  --заставка-синий: #2775FF;
  --заставка-бирюза: #18D4F1;
  --заставка-сияние: #18D4F1BF;
  --заставка-дорожка: #96ACD738;
  --заставка-подпись: #949EB7;
  --заставка-затемнение: #0A101EE0;   /* фон рисунка, 88 % */
  position: fixed; inset: 0; z-index: 10000;   /* ниже пузыря подсказки (10500) */
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 16px;
  padding: 16px; box-sizing: border-box;
  background: var(--заставка-затемнение);
}
.окно-расчёта__карта {
  position: relative;
  width: min(100%, calc(78vh * 1040 / 640), 1040px);
  aspect-ratio: 1040 / 640;
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .45);
  container-type: inline-size;
}
.окно-расчёта__рисунок {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
.окно-расчёта__дорожка {
  position: absolute; left: 6.41%; right: 6.25%; top: 74.32%; height: 1.875%;
  border-radius: 999px; background: var(--заставка-дорожка); overflow: hidden;
}
.окно-расчёта__бегунок {
  position: absolute; top: 0; bottom: 0; width: 28%; border-radius: 999px;
  background: linear-gradient(90deg, var(--заставка-синий), var(--заставка-бирюза));
  box-shadow: 0 0 12px var(--заставка-сияние);
  animation: окно-расчёта-бег 1.6s ease-in-out infinite;
}
@keyframes окно-расчёта-бег { 0% { left: -28%; } 100% { left: 100%; } }
/* Кегль — доля ширины рисунка, как в образце, но не мельче 14 точек: на
 * узком экране доля дала бы восемь, а нижний порог изделия — двенадцать. */
.окно-расчёта__состояние {
  position: absolute; left: 6.41%; right: 6.25%; top: 78.6%; margin: 0;
  font-size: max(14px, 2.9cqw); font-weight: 500; letter-spacing: .01em;
  color: var(--заставка-подпись);
}
.окно-расчёта__действия {
  display: flex; align-items: center; gap: 8px;
}
.окно-расчёта__действия button.ghost,
.окно-расчёта__действия .help-icon { background: var(--ax-color-surface); }
@media (prefers-reduced-motion: reduce) {
  .окно-расчёта__бегунок { animation-duration: 3.2s; }
}

/* --- Окно распознавания растра (выпуск 3.2.51) ---------------------------
 *
 * Страница окна отдаётся только по ключу сервера (`app/растр.py`). Цвета —
 * переменные листа, своих оттенков нет: окно — страница того же сервиса.
 * Картинка изображения и распознанное — не шире колонки работы, высота — по
 * изображению: на телефоне рисунок ужимается, а не вылезает за экран. */
.очередь-растра { margin: 8px 0; padding-left: 20px; color: var(--text-muted); }
.очередь-растра .очередь-открыт { color: var(--text-main); font-weight: 600; }
.очередь-растра .очередь-отказ { color: var(--danger); }
.сведения-файла { margin: 6px 0; overflow-wrap: anywhere; }
.предупреждения-растра,
.замечания-растра { margin: 6px 0; padding-left: 20px; color: var(--warning); }
.выбор-вида { border: 0; padding: 0; margin: 8px 0; display: flex;
  flex-wrap: wrap; gap: 6px 16px; align-items: baseline; }
.выбор-вида legend { padding: 0; margin-bottom: 4px; font-weight: 600; }
.поле-группа { display: flex; flex-direction: column; gap: 4px; }
.подпись-группы { font-weight: 600; }
.значение-указания { color: var(--text-muted); overflow-wrap: anywhere; }
/* Лупа окна распознавания (выпуск 3.2.54): рамка с прокруткой, холст
 * внутри — шириной «исходный вид × доля»; ширину и высоту холста ставит
 * сценарий. */
.полоса-лупы { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 8px; }
.полоса-лупы .второстепенная { min-width: 36px; }
.лупа { overflow: auto; max-width: 100%; max-height: 80vh; margin-top: 6px;
  border: 1px solid var(--border); background: var(--bg-panel);
  overscroll-behavior: contain; }
.лупа:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.лупа.увеличено { cursor: grab; }
.лупа.ведётся { cursor: grabbing; user-select: none; }
.картинка-растра { position: relative; display: block; }
.картинка-растра img { display: block; width: 100%; height: 100%; max-width: none;
  cursor: crosshair; -webkit-user-drag: none; user-select: none;
  -webkit-user-select: none; }
/* Пока идёт указание, палец по картинке обводит, а не листает страницу
 * (выпуск 3.2.54). Вне указания страница листается как обычно. */
.картинка-растра.идёт-указание img { touch-action: none; }
.лупа.увеличено .картинка-растра img { cursor: grab; }
.лупа .картинка-растра.идёт-указание img { cursor: crosshair; }
.пометки-картинки { position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; }
.пометка-области { fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; }
.пометка-области.ведётся { stroke-dasharray: none; }
.пометка-угла { fill: var(--accent); }
.пометка-номер { fill: var(--danger); font-weight: 700; }
.распознанное-растра { margin: 0; }
.рисунок-распознанного { display: block; background: var(--bg-panel); }
.рисунок-распознанного .фон-распознанного { opacity: .55; }
.рисунок-распознанного .элемент { fill: none; stroke-width: 3;
  vector-effect: non-scaling-stroke; pointer-events: none; }
.рисунок-распознанного .элемент.наружный { stroke: var(--accent); }
.рисунок-распознанного .элемент.отверстие { stroke: var(--ax-color-success); }
.рисунок-распознанного .элемент.замыкающий { stroke-dasharray: 6 4; }
.рисунок-распознанного .элемент.выбран { stroke: var(--danger); stroke-width: 4; }
.рисунок-распознанного .цель-элемента { fill: none; stroke: transparent;
  stroke-width: 14; vector-effect: non-scaling-stroke; cursor: pointer;
  pointer-events: stroke; }
.доклад-растра pre { white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: 13px; }
.габариты-растра { margin: 6px 0; padding-left: 20px; font-weight: 600; }
.рисунок-справки { margin: 8px 0 0; }
.рисунок-справки img { display: block; max-width: 100%; height: auto; }
.рисунок-справки figcaption { margin-top: 4px; font-size: 13px;
  color: var(--text-muted); }
.источник-геометрии { font-weight: 700; color: var(--accent); }
.подпись-картинки { margin: 12px 0 0; }
/* Положение детали и масштаб по факту (выпуск 3.2.56). */
.положение-детали { margin-top: 10px; }
.мера-растра { margin-top: 10px; }
.мера-строка { align-items: flex-end; flex-wrap: wrap; }
.рисунок-распознанного .точка-меры { fill: var(--danger); }
.рисунок-распознанного .отрезок-меры { stroke: var(--danger); stroke-width: 2;
  stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; }
.лупа.идёт-мера { cursor: crosshair; }
