/* ProfileCut Optimizer — веб-интерфейс.

   Оформление подчинено сайту axtoren.ru: приложение живёт под его адресом
   (`axtoren.ru/optimizer/`) и обязано выглядеть его частью, а не чужим
   продуктом в чужой раме. Переменные и разметка шапки с подвалом взяты у
   темы сайта без правок — расхождение в оттенке или отступе читается как
   «меня перебросили на сторонний сервис», и до расчёта человек не доходит.

   ЧИСТО БЕЛОГО И ЧИСТО ЧЁРНОГО НЕТ НИГДЕ. Фон страницы — «ватман», тёплый
   бумажный оттенок; белый допустим только у поверхностей карточек.

   ЖИРНОГО НАЧЕРТАНИЯ У ШРИФТА НЕ СУЩЕСТВУЕТ. OpenGost Type B поставляется
   единственным начертанием, и `font-weight: 700` заставил бы браузер
   рисовать поддельный жирный — механически растянутые контуры, искажающие
   чертёжные пропорции. Вес набирается кеглем и межбуквенным расстоянием.
*/

@font-face {
    font-family: 'OpenGost Type B';
    /* ПОРЯДОК ИСТОЧНИКОВ ВЫБРАН НАМЕРЕННО: сначала тема, потом своя копия.
     *
     * Домен общий, тему и приложение отдаёт один nginx, поэтому обращение к
     * файлу темы попадает ровно в тот же файл, который посетитель уже
     * скачал, гуляя по сайту. Кеш браузера один, скачивание одно.
     *
     * Поставь мы своим файлом первым — получилось бы две записи в кеше и
     * двойная загрузка у всякого, кто пришёл в приложение с сайта.
     *
     * Своя копия остаётся ВТОРОЙ и нужна ровно для одного случая:
     * приложение открыто не под адресом сайта, а на отдельном поддомене
     * (`soft-pco`, местная проверка, показ без сети). Там путь `/wp-content/`
     * попадает в само приложение, где такого маршрута нет: браузер молча
     * получает 404 и рисует запасной гарнитурой. Внешне «почти то же самое»,
     * и на снимке подмену не различить — так и вышло с beta.86.
     *
     * ОБНОВЛЕНИЕ ШРИФТА. Имя файла несёт версию (`-v2`), потому что браузеры
     * кешируют шрифты годами. Меняется шрифт — меняется имя, и тогда правку
     * надо провести В ДВУХ местах: в теме и здесь. Иначе сайт уедет на новое
     * начертание, а приложение останется на прежнем, и разойдутся они молча.
     * Сумма файла записана в тесте — он же и напомнит.
     */
    src: url('/wp-content/themes/axtoren-theme/fonts/opengost-type-b-v2.woff2') format('woff2'),
         url('/wp-content/themes/axtoren-theme/fonts/opengost-type-b-v2.woff') format('woff'),
         url('fonts/opengost-type-b-v2.woff2') format('woff2'),
         url('fonts/opengost-type-b-v2.woff') format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

:root {
    /* --- палитра сайта, скопирована из темы без изменений --- */
    --ax-color-bg:         #F2EFE6;
    --ax-color-surface:    #FFFFFF;
    --ax-color-text:       #273341;
    --ax-color-text-muted: #273341B3;
    --ax-color-accent:     #DCA530;
    --ax-color-border:     #27334129;
    --ax-color-success:    #3D8B5F;
    --ax-color-danger:     #B23A2E;

    --ax-container-max: 1280px;
    --ax-gap-base: 24px;
    --ax-radius-base: 4px;

    --ax-ease-engineering: cubic-bezier(0.22, 0.61, 0.36, 1);
    --ax-duration-fast: 160ms;
    --ax-duration-base: 280ms;

    /* Запасные гарнитуры перечислены намеренно. Подстановка в браузере идёт
       ПОЗНАКОВО: буквы, которых в OpenGost нет (казахские ә, ө, ұ, китайские,
       японские, арабские), берутся из следующей гарнитуры сами. Языков в
       сервисе 25, и без запасных на половине из них были бы пустые
       прямоугольники. */
    --ax-font-base: 'OpenGost Type B', 'PT Sans', 'Noto Sans', Arial, sans-serif;

    /* --- цвета редакций: ими обводятся блоки --- */
    --ed-lite:     #1F4E8C;
    --ed-standard: #3D8B5F;
    --ed-pro:      #A8760F;
    --ed-lite-soft:     #1F4E8C14;
    --ed-standard-soft: #3D8B5F14;
    --ed-pro-soft:      #DCA53022;

    /* --- имена, которыми пользуется остальной лист --- */
    --bg-main: var(--ax-color-bg);
    --bg-panel: var(--ax-color-surface);
    --bg-header: var(--ax-color-bg);
    --bg-soft: #EAE6DA;
    --border: var(--ax-color-border);
    --text-main: var(--ax-color-text);
    --text-muted: var(--ax-color-text-muted);
    --text-on-dark: var(--ax-color-text);
    --accent: var(--ax-color-accent);
    --accent-hover: #C79322;
    --success: var(--ax-color-success);
    --warning: #B8862B;
    --danger: var(--ax-color-danger);

    --lite-bg: var(--ed-lite-soft);     --lite-fg: var(--ed-lite);
    --standard-bg: var(--ed-standard);  --standard-fg: #FFFFFF;
    --pro-bg: var(--ed-pro);            --pro-fg: #FFF6E4;
}

/* Поддельный жирный запрещён по всему приложению. Выделение — разрядкой и
   цветом: в чертёжном шрифте это и есть штатный приём. */
b, strong, th, .brand {
    font-weight: 400;
    letter-spacing: 0.04em;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--ax-font-base);
    /* 17 — как в теме сайта. Начертание узкое и высококонтрастное, при
       мелком кегле сливается. Заодно снимается вторая беда: Safari
       приближает страницу при касании поля мельче 16 px. */
    font-size: 19px;
    color: var(--text-main);
    background: var(--bg-main);
    /* Обязателен: при обычных 1.4–1.5 узкие буквы смыкаются построчно. */
    line-height: 1.65;
    letter-spacing: 0.01em;
}

/* ---- Шапка ---- */
header {
    background: var(--bg-header);
    color: var(--text-on-dark);
    padding: 10px 20px;
    display: flex;
    align-items: center;
    gap: 14px;
    position: sticky;
    top: 0;
    z-index: 20;
}
header .brand { letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ font-size: 18px; }
header .spacer { margin-left: auto; }
header select, header button {
    background: rgba(255, 255, 255, .12);
    color: var(--text-on-dark);
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: 5px;
    padding: 5px 10px;
    font-size: 15px;
    cursor: pointer;
}
header button:hover { background: rgba(255, 255, 255, .22); }

.edition-tag {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 9px; border-radius: 5px;
    font-size: 13px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ letter-spacing: .4px;
    text-transform: uppercase;
}
.edition-tag.lite     { background: var(--lite-bg);     color: var(--lite-fg); }
.edition-tag.standard { background: var(--standard-bg); color: var(--standard-fg); }
.edition-tag.pro      { background: var(--pro-bg);      color: var(--pro-fg); }

/* ---- Раскладка ---- */
/* ШИРИНА РАБОЧЕЙ ОБЛАСТИ ОБЪЯВЛЕНА ОДИН РАЗ.
 *
 * Прежде 1080 и 20 стояли здесь, а те же числа — в расчёте вылета панели
 * спецификации (`#p-spec` ниже). Две части считали одну величину порознь, и
 * поправь кто-нибудь ширину здесь — вылет посчитался бы от прежней. Молча:
 * панель просто встала бы не по месту.
 *
 * Правило проекта «Сайт Axtoren», выведенное из трёх наших отказов подряд:
 * если две части считают одну величину порознь, они разойдутся — не оттого,
 * что кто-то ошибётся, а оттого, что у них нет способа узнать об изменении
 * друг у друга. Лечение одно: передать число явно.
 */
:root {
    --pco-work-max: 1080px;
    --pco-work-pad: 20px;
}
main {
    /* ШИРИНА СЧИТАЕТСЯ ОТ КОЛОНКИ, А НЕ ОТ ОКНА.
     *
     * Прежде `main` ограничивался 1080, а панель спецификации выходила за него
     * отрицательными полями, считая свободную ширину от `100vw`. Это ошибалось
     * дважды: сперва не знало про боковые колонки (исправлено в 1.34.9), затем
     * не знало, что сама обёртка ограничена 1920 — и на широком экране панель
     * снова легла поверх боковых блоков.
     *
     * Оба раза — один класс: расчёт от окна там, где элемент живёт в колонке
     * уже окна. Лечится не третьим слагаемым, а отказом от `vw` вовсе:
     * `main` занимает всю колонку, ограничение переносится на панели, и всё
     * считается в процентах от того, что есть.
     */
    width: 100%;
    padding: var(--pco-work-pad);
    box-sizing: border-box;
}

/* Панели держат прежнюю ширину и центрируются в колонке. */
.panel {
    max-width: var(--pco-work-max);
    margin-inline: auto;
}

.panel {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 18px 20px;
    margin-bottom: 16px;
}
.panel h2 {
    margin: 0 0 14px;
    font-size: 18px;
    letter-spacing: .04em;   /* вместо веса: жирного начертания нет */
    display: flex; align-items: center; gap: 8px;
}
.panel h2 .step {
    background: var(--accent); color: #fff;
    width: 22px; height: 22px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ flex: none;
}
.panel.done h2 .step { background: var(--success); }
.hint { color: var(--text-muted); font-size: 15px; margin: 4px 0 12px; }

/* ---- Формы ---- */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
label { display: block; font-size: 14px; color: var(--text-muted); margin-bottom: 3px; }
input[type=text], input[type=number], input[type=email], input[type=password], select {
    width: 100%; padding: 7px 9px;
    border: 1px solid var(--border); border-radius: 5px;
    font-size: 16px; background: #fff; color: var(--text-main);
}
input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

button.primary {
    background: var(--accent); color: #fff; border: none;
    padding: 9px 18px; border-radius: 6px;
    font-size: 16px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ cursor: pointer;
}
button.primary:hover { background: var(--accent-hover); }
button.primary:disabled { background: #9aa5b5; cursor: not-allowed; }
button.ghost {
    background: transparent; color: var(--accent);
    border: 1px solid var(--border); padding: 7px 14px;
    border-radius: 6px; font-size: 15px; cursor: pointer;
}
button.ghost:hover { background: var(--bg-soft); }

/* ---- Таблица спецификации ---- */
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th {
    text-align: left; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ color: var(--text-muted);
    font-size: 14px; padding: 6px 8px; border-bottom: 2px solid var(--border);
}
td { padding: 3px 4px; border-bottom: 1px solid var(--bg-soft); }
td input { padding: 5px 7px; font-size: 15px; }
tr.over-limit td { background: #fef2f2; }

.row-counter { font-size: 15px; color: var(--text-muted); }
.row-counter.exceeded { color: var(--danger); letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ }

/* ---- Флаги с гейтом редакции ---- */
.flags { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px; }
.flag { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
.flag.locked { opacity: .55; }
.flag .lock-badge {
    font-size: 12px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ text-transform: uppercase;
    padding: 1px 6px; border-radius: 4px; letter-spacing: .3px;
}
.flag .lock-badge.standard { background: var(--standard-bg); color: #fff; }
.flag .lock-badge.pro      { background: var(--pro-bg); color: var(--pro-fg); }

/* ---- Результат ---- */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.metric {
    background: var(--bg-soft); border-radius: 7px; padding: 12px 14px;
}
.metric .value { font-size: 26px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ line-height: 1.15; }
.metric .label { font-size: 14px; color: var(--text-muted); margin-top: 2px; }
.metric.good .value { color: var(--success); }
.metric.warn .value { color: var(--warning); }

.free-badge {
    display: inline-block; background: #dcfce7; color: #14532d;
    font-size: 13px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ padding: 2px 8px;
    border-radius: 4px; text-transform: uppercase; letter-spacing: .3px;
}

/* ---- Сравнение редакций ---- */
.compare { width: 100%; }
.compare th, .compare td { padding: 8px; text-align: center; }
.compare th:first-child, .compare td:first-child { text-align: left; }
.compare tr.best { background: #f0f9ff; }
.compare .gain { color: var(--success); letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ }

/* ---- Оплата отчёта ---- */
.paywall {
    border: 2px dashed var(--border);
    border-radius: 8px; padding: 18px; text-align: center;
    background: linear-gradient(180deg, #fff, var(--bg-soft));
}
.paywall .price { font-size: 28px; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ margin: 6px 0; }
.paywall .what { color: var(--text-muted); font-size: 15px; margin-bottom: 12px; }

/* ---- Состояния ---- */
.notice { padding: 10px 14px; border-radius: 6px; font-size: 15px; margin: 10px 0; }
.notice.error { background: #fef2f2; color: #7f1d1d; border: 1px solid #fecaca; }
.notice.ok    { background: #f0fdf4; color: #14532d; border: 1px solid #bbf7d0; }
.notice.info  { background: #eff6ff; color: #1e3a8a; border: 1px solid #bfdbfe; }

.spinner {
    display: inline-block; width: 15px; height: 15px;
    border: 2px solid var(--border); border-top-color: var(--accent);
    border-radius: 50%; animation: spin .8s linear infinite;
    vertical-align: -2px; margin-right: 7px;
}
@keyframes spin { to { transform: rotate(360deg); } }

.hidden { display: none !important; }

/* Атрибут `hidden` — тоже способ скрыть, и он обязан работать так же.
   Браузер задаёт для него `display: none` своим листом стилей, а любое
   КЛАССОВОЕ правило с `display` его перебивает — по старшинству, без
   предупреждения. Так и вышло с запасной надписью логотипа: скрипт ставил
   `hidden`, разметка несла `hidden` изначально, а правило
   `.ax-header__logo-fallback { display: flex }` возвращало её на экран, и
   рядом с загруженным знаком стояло «AX Axtoren». Дважды чинили скрипт —
   причина была здесь.

   Правило общее, а не для одного узла: сегодня совпадение случилось с
   логотипом, завтра случится с полем загрузки файлов, и искать будут снова
   в скрипте. */
[hidden] { display: none !important; }

/* ---- Модальное окно (кабинет) ---- */
.modal-back {
    position: fixed; inset: 0; background: rgba(15, 23, 42, .55);
    display: flex; align-items: center; justify-content: center; z-index: 50;
}
.modal {
    background: var(--bg-panel); border-radius: 10px;
    padding: 22px; width: min(420px, 92vw);
}
.modal h3 { margin: 0 0 14px; font-size: 18px; }
.modal .row { margin-bottom: 12px; }
.modal .actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px; }

/* ---- Подвал ---- */
footer {
    text-align: center; color: var(--text-muted);
    font-size: 14px; padding: 18px; border-top: 1px solid var(--border);
    margin-top: 24px;
}

@media (max-width: 640px) {
    main { padding: 12px; }
    .panel { padding: 14px; }
    header .brand { font-size: 16px; }
}

/* Перечень замечаний по загруженным файлам. Показывается пофайлово: при
   сотне файлов сообщение «часть не разобрана» без перечня бесполезно. */
.import-issues {
    margin: 8px 0 0;
    padding-left: 18px;
    font-size: 15px;
    color: #8a6d3b;
    max-height: 180px;
    overflow-y: auto;
}
.import-issues li { margin: 2px 0; }


/* ── Личный кабинет ──────────────────────────────────────────────────────
   Ступени пополнения показываются плитками, а не выпадающим списком:
   надбавка — довод к покупке, и её надо видеть, не открывая список. */
.tiers { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 4px; }
.tier {
    flex: 1 1 120px; padding: 10px 12px; border: 1px solid #d8dde4;
    border-radius: 8px; background: #fff; cursor: pointer; text-align: center;
    font: inherit;
}
.tier:hover { border-color: var(--accent, #DCA530); }
.tier .pay { display: block; letter-spacing: .04em;   /* вместо веса: жирного начертания нет */ }
.tier .bonus { display: block; font-size: 14px; color: #2e7d32; margin-top: 2px; }
.tier .flat { display: block; font-size: 14px; color: #6B7480; margin-top: 2px; }

.acc-tabs { display: flex; gap: 4px; margin: 14px 0 8px;
            border-bottom: 1px solid #e3e7ec; }
.acc-tabs .tab {
    padding: 6px 10px; border: none; background: none; cursor: pointer;
    font: inherit; color: #6B7480; border-bottom: 2px solid transparent;
}
.acc-tabs .tab.active { color: #273341; border-bottom-color: #DCA530; }
.acc-tab { max-height: 260px; overflow-y: auto; font-size: 15px; }
.acc-row {
    display: flex; justify-content: space-between; gap: 8px;
    padding: 6px 0; border-bottom: 1px solid #f0f2f5;
}
.acc-row .muted { color: #6B7480; }
.acc-row .plus { color: #2e7d32; }
.acc-row .minus { color: #b3261e; }
.acc-empty { color: #6B7480; padding: 10px 0; }


/* ── Сообщить о проблеме ─────────────────────────────────────────────────
   Кнопка плавающая: проблема случается на любом экране, и искать для неё
   пункт меню — лишний шаг там, где человек уже раздражён. */
/* ── Значок подсказки «?» ────────────────────────────────────────────────

   Оформления у него в веб-версии НЕ БЫЛО ВООБЩЕ: модуль подсказок перенесли
   из настольной программы, а его правила остались в `frontend/css/main.css`.
   Браузер рисовал значок как обычную кнопку — системной гарнитурой 13,3 px с
   рамкой и отступами, — а заголовок столбца набран чертёжным шрифтом в 12 px.
   Знак вопроса выходил заметнее того, что он поясняет: в таблице он читался
   как главное, а названия столбцов — как мелочь.

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

   Жирного начертания у гарнитуры нет — вес не задаётся нигде (см. проверку
   test_поддельный_жирный_запрещён). */
.help-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px; height: 18px;
    margin-left: 5px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 12px;
    line-height: 1;
    vertical-align: middle;
    cursor: pointer;
    flex: none;
}
.help-icon:hover, .help-icon:focus {
    background: var(--ax-color-accent);
    border-color: var(--ax-color-accent);
    color: var(--ax-color-text);
    outline: none;
}

/* В шапке таблицы столбцов много, и каждый лишний пиксель отступа множится
   на двадцать. Значок ужимается, но не меняет кегля: разнобой заметнее. */
.spec-table th .help-icon { margin-left: 3px; width: 17px; height: 17px; }

/* Значок у плавающей кнопки сообщения о проблеме. Сама кнопка привязана к
   углу окна, а значок стоит за ней в потоке страницы — без этого правила он
   оказывался где-то в конце документа, вне всякой связи с кнопкой. */
.fab + .help-icon {
    position: fixed; right: 32px; bottom: 66px; z-index: 40;
    background: #fff;
}

/* ── Пузырёк подсказки ────────────────────────────────────────────────────

   Оформления у него, как и у значка, в веб-версии НЕ БЫЛО: правила остались
   в настольном листе стилей. Без `position: fixed` вычисленные координаты ни
   на что не влияют — блок ложится обычным текстом в самый низ страницы, ниже
   подвала, без фона. Нажатие на «?» при этом не меняет на экране ничего, и
   выглядит это как «справка не работает».

   Тёмная плашка, а не светлая: подсказка обязана читаться поверх любого
   блока, включая залитые карточки редакций. */
/* Двухсоставная подсказка.
 *
 * Верх — краткое пояснение «что это», низ — расширенное «как пользоваться».
 * Между ними видимый разрыв: слитые в один поток, они читаются простынёй, и
 * краткая часть перестаёт выполнять свою работу.
 *
 * Ширина у составной подсказки больше: расширенная часть в колонке 340 точек
 * превращается в лестницу из двух-трёх слов в строке. */
.help-bubble--wide { max-width: 460px; }

/* Краткая часть отделяется РАЗМЕРОМ, а не насыщенностью. Полужирного
   начертания у гарнитуры нет: браузер подделал бы его растягиванием контуров
   и исказил чертёжные пропорции — это в проекте запрещено и стережётся
   проверкой. */
.help-short { font-size: 15px; line-height: 1.4; }

/* Черта между краткой и расширенной частью подсказки.
 *
 * Требование 1.1.2 Стандарта: черта ВИДИМА. Прежде она была задана прозрачностью
 * .28 на тёмном фоне пузырька — то есть формально была, а на экране не читалась,
 * и подсказка выглядела сплошной простынёй.
 *
 * Смысл черты в том, ради чего она вводилась: человеку, которому нужно одно
 * предложение, видно, где кончается ответ на его вопрос. Невидимая черта эту
 * работу не делает, а требование при этом считается исполненным — проверка
 * смотрела на наличие элемента, а не на его заметность.
 *
 * Цвет — акцентный: он и на тёмном фоне читается, и связывает черту с прочими
 * выделениями страницы. */
.help-sep {
    border: 0;
    border-top: 2px solid var(--ax-color-accent);
    opacity: .75;
    margin: 11px 0;
}

.help-ext p { margin: 0 0 7px; }
.help-ext p:last-child { margin-bottom: 0; }

/* Ссылка на материал библиотеки — СТРОКА ДЕЙСТВИЯ, а не подпись внизу.
 *
 * Прежде она была набрана вровень с текстом и отличалась только цветом: на
 * тёмном поле пузырька, после четырёх абзацев разбора, глаз до неё не доходил.
 * А это единственное место, ради которого затевалась связь программы с
 * сайтом.
 *
 * Поэтому у неё теперь своя подложка, рамка слева и увеличенный кегль: она
 * читается как отдельный ход, а не как продолжение абзаца. Насыщенность не
 * применяется — у гарнитуры нет полужирного начертания. */
.help-links {
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.help-links a {
    display: block;
    padding: 9px 12px;
    background: rgba(220, 165, 48, .16);
    border-left: 3px solid var(--ax-color-accent);
    border-radius: 4px;
    color: var(--ax-color-accent);
    font-size: 16px;
    letter-spacing: .03em;
    text-decoration: none;
}
.help-links a:hover { background: rgba(220, 165, 48, .28); }

/* Стрелка показывает, что переход уводит со страницы, — иначе человек
   нажимает, не ожидая новой вкладки. */
.help-links a::before { content: "→ "; }

.help-bubble {
    position: fixed;
    z-index: 10500;          /* выше окон, ниже сообщений об ошибках */
    max-width: 340px;
    padding: 9px 12px;
    border-radius: 6px;
    background: var(--ax-color-text);
    color: var(--ax-color-bg);
    font-size: 14px;
    line-height: 1.45;
    text-align: left;
    box-shadow: 0 8px 24px rgba(39, 51, 65, .28);
    user-select: text;
}

/* ── Согласие и условия продажи ───────────────────────────────────────────

   Отметка согласия крупнее обычного флага и не жмётся к краю: по ней человек
   принимает на себя условия, и мелкая незаметная отметка выглядит уловкой —
   а в споре о возврате именно так её и назовут. */
.consent {
    display: flex; align-items: flex-start; gap: 10px;
    max-width: 640px; margin: 0 auto 14px;
    text-align: left; font-size: 15px; line-height: 1.5;
    color: var(--text-muted); cursor: pointer;
}
.consent input { margin-top: 3px; flex: none; width: 16px; height: 16px; }
.consent a { color: var(--ax-color-accent); }

.terms {
    max-width: 720px; margin: 18px auto 0; padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 15px; line-height: 1.6; color: var(--text-muted);
    text-align: left;
}
.terms h3 { font-size: 16px; margin: 0 0 8px; color: var(--ax-color-text); }
.terms ul { margin: 0; padding-left: 18px; }
.terms li { margin-bottom: 6px; }

/* Реквизиты продавца в подвале — отдельной строкой во всю ширину. */
/* ── Строка реквизитов продавца ──────────────────────────────────────────
 *
 * ФОРМА — ИНИЦИАЛЫ, а не полное имя. Указание правообладателя, переданное
 * проектом сайта 21.08.2026. «Корнильцев А. В.» — та же правовая
 * определённость при вдвое меньшей длине строки.
 *
 * КЕГЛЬ 10 — указание правообладателя от 21.08.2026, данное после того, как
 * ему было доложено о нижнем пороге 12. Реквизиты обязаны БЫТЬ на странице, но
 * не обязаны спорить за внимание с тем, ради чего человек пришёл.
 *
 * ЭТО ЕДИНСТВЕННОЕ МЕСТО НИЖЕ ПОРОГА, и оно названо в проверке поимённо.
 * Порог 12 заведён при подъёме всех кеглей на два: у станка читают дальше и
 * при худшем свете, чем за рабочим столом. Правовая строка — не то, что читают
 * у станка, и потому исключение обосновано; но именно поэтому оно должно быть
 * ОДНО и видимое, а не понижением порога для всех.
 *
 * ПОЧЕМУ СТРОКА ВСЁ ЕЩЁ ЗДЕСЬ, А НЕ В ОБЩЕМ ПОДВАЛЕ САЙТА. Проект сайта
 * предложил перенести её в `/shell/footer/`, чтобы источник был один: две
 * копии правового текста расходятся молча — поправят ФИО в одном месте, забудут
 * в другом, а расхождение в реквизитах перед банком выглядит хуже их
 * отсутствия. Предложение принято, но перенос за ними и ещё не сделан.
 *
 * Убрать свою копию ДО того, как общий подвал начнёт её отдавать, нельзя:
 * страница останется без реквизитов продавца. По статье 9 закона о защите прав
 * потребителей это нарушение, а для банка-эквайера — основание приостановить
 * приём платежей. Порядок только такой: сперва появилось там, потом убрано
 * здесь, и не наоборот.
 *
 * Решение правообладателя 21.08.2026: оставить у себя пока.
 */
.ax-footer__req {
    display: block;
    margin-bottom: 6px;
    font-size: 10px;
}

/* ── Кнопка «сообщить о неполадке» ────────────────────────────────────────

   Была бледной: белый кружок с тонким знаком, теряющийся на светлом фоне
   страницы. А это единственный способ посетителя сказать нам, что не так, —
   и от того, заметят её или нет, зависит вся польза от испытаний.

   Заметность даётся ЗАЛИВКОЙ и РАЗМЕРОМ, а не толщиной знака: жирного
   начертания у чертёжной гарнитуры нет, и подделывать его нельзя (см.
   проверку `test_поддельный_жирный_запрещён`). Знак набирается системным
   шрифтом, у которого начертания есть, и потому выглядит плотным без обмана.

   Цвет — не тревожный красный на белом, а спокойная тёмная плашка цвета
   бренда: кнопка должна звать написать, а не пугать поломкой. */
.fab {
    position: fixed; right: 20px; bottom: 20px; z-index: 40;
    display: flex; align-items: center; justify-content: center;
    width: 52px; height: 52px; border-radius: 50%;
    cursor: pointer;
    /* Золото на тёмном знаке, а не тёмное на золотом.
       Кнопка привязана к углу окна и проплывает НАД всей страницей: над
       светлым полем расчёта и над ТЁМНЫМ подвалом. Прежняя тёмная заливка
       совпадала с подвалом и кнопка в нём исчезала — а именно внизу страницы
       человек и оказывается, дочитав до конца и решив написать.
       Золотой цвет различим на обоих фонах; светлая обводка отделяет кнопку
       от тёмного подвала, тень — от светлого поля. */
    background: var(--ax-color-accent); color: var(--ax-color-text);
    border: 2px solid var(--ax-color-bg);
    font: 26px/1 Arial, sans-serif;
    box-shadow: 0 4px 16px rgba(39, 51, 65, .45);
    transition: transform .12s ease, box-shadow .12s ease;
}
.fab:hover, .fab:focus {
    background: var(--ax-color-text); color: var(--ax-color-accent);
    border-color: var(--ax-color-accent);
    box-shadow: 0 6px 20px rgba(39, 51, 65, .5);
    transform: translateY(-1px);
    outline: none;
}
/* Подпись у кнопки: знак вопроса объясняет себя сам, восклицательный — нет.
   На узком экране прячется, чтобы не наезжать на содержимое. */
.fab-label {
    position: fixed; right: 84px; bottom: 33px; z-index: 40;
    padding: 5px 10px; border-radius: 6px;
    /* Та же беда, что и у кнопки: тёмная плашка тонула в тёмном подвале. */
    background: var(--ax-color-accent); color: var(--ax-color-text);
    border: 1px solid var(--ax-color-bg);
    font-size: 14px; line-height: 1.2; white-space: nowrap;
    box-shadow: 0 4px 14px rgba(39, 51, 65, .35);
    pointer-events: none;
}
@media (max-width: 860px) { .fab-label { display: none; } }
#problem-text { width: 100%; font: inherit; padding: 8px;
                border: 1px solid #d8dde4; border-radius: 6px; }


/* ── Мобильная вёрстка ───────────────────────────────────────────────────

   Спецификация — семь столбцов. На экране 360 пикселей они не помещаются
   никогда: сжимать нечего, «Марка стали» и «Длина, мм» короче не станут.
   Горизонтальная прокрутка тоже не выход — заказчик заполняет строку слева
   направо и на середине теряет из вида, какое поле правит.

   Поэтому на узком экране строка разворачивается в карточку: каждое поле
   с подписью, друг под другом. Подписи берутся из заголовков таблицы через
   data-label — иначе пришлось бы держать две разметки и следить, чтобы не
   разошлись. */
@media (max-width: 720px) {
    .spec-table thead { display: none; }

    .spec-table, .spec-table tbody, .spec-table tr, .spec-table td {
        display: block;
        width: 100%;
    }

    .spec-table tr {
        border: 1px solid #d8dde4;
        border-radius: 8px;
        padding: 10px 12px 8px;
        margin-bottom: 10px;
        background: #fff;
        position: relative;
    }

    .spec-table td {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 4px 0;
        border: none;
    }

    .spec-table td::before {
        content: attr(data-label);
        flex: 0 0 42%;
        font-size: 14px;
        color: #6B7480;
    }

    .spec-table td input,
    .spec-table td select { flex: 1 1 auto; min-width: 0; }

    /* Номер строки — заголовком карточки, а не полем. */
    .spec-table td.col-num {
        letter-spacing: .04em;   /* вместо веса: жирного начертания нет */
        border-bottom: 1px solid #f0f2f5;
        margin-bottom: 4px;
        padding-bottom: 6px;
    }
    .spec-table td.col-num::before { content: "№ "; flex: none; }

    /* Удаление — в правый верхний угол карточки. */
    .spec-table td.col-del {
        position: absolute;
        top: 6px; right: 8px;
        width: auto; padding: 0;
    }
    .spec-table td.col-del::before { content: none; }

    /* Поля ввода на телефоне: 16 пикселей, иначе Safari приближает страницу
       при касании и обратно её не отдаляет. */
    input, select, textarea { font-size: 18px; }

    .row { flex-direction: column; align-items: stretch; }
    .actions { flex-wrap: wrap; }
    .tier { flex: 1 1 100%; }
    .acc-tabs { overflow-x: auto; }
}


/* Переключатель редакций — только на время испытаний. */
#trial-edition {
    margin-left: 8px; padding: 2px 6px; font-size: 14px;
    border-radius: 4px; border: 1px solid rgba(255,255,255,.35);
    background: rgba(255,255,255,.12); color: #fff;
}

/* Выбор языка не должен занимать всю ширину: это вспомогательный элемент,
   а не главное действие на странице. */
#lang-select { width: auto; min-width: 162px; max-width: 254px; }


/* Выбор «посмотреть как». Узкий: это служебный переключатель, а не главный
   орган управления — он не должен спорить за внимание с расчётом. */
.view-as {
    max-width: 173px; font-size: 14px; padding: 2px 6px;
    border: 1px solid #4a5561; border-radius: 6px;
    background: #fff; color: #273341;
}
.view-as.lowered { border-color: #DCA530; background: #fff8e8; }


/* Знак вопроса у режима — как в настольной версии: пояснение по нажатию,
   а не всплывающая подсказка. Всплывающие не работают на телефоне и не
   переводятся. */
.help-dot {
    width: 16px; height: 16px; margin-left: 4px; padding: 0;
    border: 1px solid #b9c0c9; border-radius: 50%; background: #fff;
    color: #6B7480; font: 11px/1 Arial, sans-serif; cursor: pointer;
}
.help-dot:hover { border-color: #DCA530; color: #273341; }
/* Закрытый режим виден и отвечает на нажатие — иначе о нём не узнают. */
.flag.locked label { cursor: help; }
.flag.locked input { cursor: help; }


/* Показ пароля. Пароль набирают вслепую и ошибаются, а отказ входа выглядит
   так же, как неверный пароль: человек не понимает, ошибся он или сломался
   вход. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 32px; }
.pw-eye {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 22px; height: 22px; padding: 0; border: none; background: none;
    color: #6B7480; font-size: 17px; line-height: 1; cursor: pointer;
}
.pw-eye:hover { color: #273341; }


/* Перечень отличий редакции. Мельче цены, но читаемо: это довод, а не сноска. */
td.adds { font-size: 14px; color: #4a5561; line-height: 1.4; max-width: 380px; }

/* Выпадающие списки в тёмной шапке. Без явного цвета содержимое списка
   наследует цвет шапки и становится нечитаемым: видна только строка под
   указателем. */
.topbar select, .topbar select option,
#view-as, #view-as option, #lang-select, #lang-select option {
    color: #273341; background: #fff;
}


/* ═══════════════════════════════════════════════════════════════════════
   ШАПКА И ПОДВАЛ САЙТА
   Разметка и размеры взяты у темы axtoren.ru. Вес надписей набирается
   разрядкой, а не жирностью: жирного начертания у гарнитуры нет.
   ═══════════════════════════════════════════════════════════════════════ */

.ax-container {
    max-width: var(--ax-container-max);
    margin: 0 auto;
    padding-inline: var(--ax-gap-base);
}

.ax-header {
    /* sticky выбрасывать нельзя: от него зависит поправка scroll-margin-top
       у якорей ниже. */
    position: sticky; top: 0; z-index: 100;
    background-color: var(--ax-color-bg);
    border-bottom: 1px solid var(--ax-color-border);
}
.ax-header__inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ax-gap-base);
    padding-block: 16px;
}
.ax-header__logo { display: flex; align-items: center; }
/* Высота фиксирована, ширина auto — как в теме. Задать обе жёстко нельзя:
   собственное соотношение знака 785:501 (1,567), а размеры в разметке темы
   дают 1,563 — знак сплющился бы. Разница крохотная, но на логотипе такое
   замечают, не понимая, что именно не так. */
.ax-header__logo-img { height: 52px; width: auto; display: block; }
@media (min-width: 768px) {
    .ax-header__logo-img { height: 62px; }
}
/* Замена логотипа надписью, когда изображение темы недоступно —
   то есть пока приложение живёт на отдельном поддомене. */
.ax-header__logo-fallback { display: flex; align-items: center; gap: 8px; }
.ax-header__logo-mark { font-size: 26px; letter-spacing: .04em; }
.ax-header__logo-name { font-size: 15px; letter-spacing: .12em; }

/* Меню скрыто по умолчанию и открывается на широком экране — так в теме.
   Показанное всегда, оно переносилось на вторую строку, и шапка приложения
   становилась вдвое выше сайтовой. */
/* Меню занимает всё свободное место между знаком и правой группой и стоит
   в нём по центру — как на сайте. При `space-between` оно прижималось к
   правой группе, и на переходе с сайта в приложение это заметно: строка та
   же, а расстановка другая. */
.ax-header__nav { display: none; }
.ax-header__nav-list {
    display: flex; gap: 32px; list-style: none; margin: 0; padding: 0;
}
/* Прописные и разрядка 0.04em — это и есть замена Bold. `font-weight: 400`
   проставлен явно, чтобы случайная правка не включила поддельный жирный. */
.ax-header__nav-link {
    font-size: 19px; font-weight: 400; letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ax-color-text); text-decoration: none;
    transition: color var(--ax-duration-fast) var(--ax-ease-engineering);
}
.ax-header__nav-link:hover,
.ax-header__nav-link:focus-visible { color: var(--ax-color-accent); }

.ax-header__actions { display: flex; align-items: center; gap: 12px; }
/* Правило `.ax-header__version` СНЯТО 23.08.2026 вместе с самой надписью:
   номер редакции переехал к названию программы (`.intro__version`), потому что
   шапка сайта одна на сайт и два приложения, а номер у каждого свой.
   Оставленное правило без своего элемента лжёт так же, как мёртвое умолчание:
   следующий читатель решит, что номер в шапке есть, просто скрыт. */
.ax-header select, .ax-header button {
    background: var(--ax-color-surface);
    color: var(--ax-color-text);
    border: 1px solid var(--ax-color-border);
    border-radius: var(--ax-radius-base);
    padding: 5px 10px; font: inherit; font-size: 16px; cursor: pointer;
    white-space: nowrap;
}
.ax-header select:hover, .ax-header button:hover {
    border-color: var(--ax-color-accent);
}
.ax-header__burger {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    background: none; border: 1px solid var(--ax-color-border);
    border-radius: var(--ax-radius-base);
    color: var(--ax-color-text); font-size: 22px; padding: 0;
}
@media (min-width: 1024px) {
    .ax-header__nav { display: flex; flex: 1 1 auto; justify-content: center; }
    .ax-header__burger { display: none; }
}

.ax-header__mobile-nav {
    display: none; flex-direction: column; gap: 4px;
    padding-block: 16px; border-top: 1px solid var(--ax-color-border);
}
.ax-header__mobile-nav.is-open { display: flex; }
.ax-header__mobile-nav-link {
    display: block; padding: 12px 8px;
    font-size: 18px; font-weight: 400; letter-spacing: 0.02em;
    color: var(--ax-color-text); text-decoration: none;
}
@media (min-width: 1024px) {
    .ax-header__mobile-nav { display: none !important; }
}

/* Липкая шапка перекрывает верх страницы при переходе по якорю. Без этой
   поправки заголовок целевого раздела уезжает под неё — а в приложении с
   шестью длинными блоками переходы по якорям есть. */
:target, [id] { scroll-margin-top: 96px; }

#balance-box { font-size: 16px; color: var(--ax-color-text-muted); }

.ax-footer {
    background: var(--ax-color-text);
    color: #F2EFE6C0;
    margin-top: 40px;
    padding-block: 40px 24px;
    font-size: 16px;
}
.ax-footer__grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--ax-gap-base);
}
.ax-footer__heading {
    font-size: 16px; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ax-color-accent); margin: 0 0 12px; font-weight: 400;
}
.ax-footer__list { list-style: none; margin: 0; padding: 0; }
.ax-footer__list-item { margin-bottom: 6px; }
.ax-footer__link { color: #F2EFE6C0; text-decoration: none; }
.ax-footer__link:hover { color: var(--ax-color-accent); }
.ax-footer__bottom {
    margin-top: 28px; padding-top: 18px;
    border-top: 1px solid #F2EFE633;
    display: grid; gap: 8px; font-size: 14px; color: #F2EFE699;
}


/* ═══════════════════════════════════════════════════════════════════════
   НУЛЕВОЙ БЛОК
   ═══════════════════════════════════════════════════════════════════════ */

/* Отступ сверху был 32 пункта поверх двадцати у `main` — над заголовком
   получалась полоса в полсотни точек ни для чего. Верх страницы — самое
   дорогое место: заказчик решает за один экран, туда ли он попал. */
.intro { text-align: center; padding: 8px 0 8px; }
.intro__title {
    margin: 0; font-weight: 400;
    font-size: clamp(26px, 4vw, 40px); letter-spacing: .015em;
}
/*
 * НОМЕР РЕДАКЦИИ ПРИ НАЗВАНИИ ПРОГРАММЫ.
 *
 * Заготовка общего облика, редакция 7 от 23.08.2026, раздел «ШАПКА
 * ПРИЛОЖЕНИЯ». Числа её: кегль 15, отступ 4 сверху, приглушённый цвет.
 *
 * ЧТО СЛОМАЕТСЯ, ЕСЛИ ВЕРНУТЬ В ШАПКУ САЙТА. Шапка сайта одна на сайт и два
 * приложения; номер у каждого приложения свой. Посетитель прочтёт номер
 * соседнего приложения и сообщит замечание не по тому адресу — а разбирать
 * замечание начнут с номера.
 */
.intro__version {
    margin: 4px 0 0;
    font-size: 15px;
    letter-spacing: 0.04em;
    color: rgba(39, 51, 65, 0.6);
    white-space: nowrap;
}

.intro__lead {
    margin: 4px 0 0; font-size: clamp(18px, 2.6vw, 26px); letter-spacing: .015em;
}
.intro__kinds {
    margin: 6px auto 0; max-width: 62ch;
    font-size: 17px; color: var(--ax-color-text-muted);
}
.intro__choose {
    margin: 26px 0 14px; font-weight: 400;
    font-size: 24px; letter-spacing: .03em; color: var(--ax-color-accent);
}
.intro__how { margin: 6px 0; font-size: 18px; letter-spacing: .01em; }
.intro__anon { margin: 14px 0 0; font-size: 16px; color: var(--ax-color-text-muted); }

/* Три кнопки выбора редакции. Именно кнопки, а не карточки-описания:
   нажатие меняет и доступные режимы, и цену отчёта. */
.editions {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: 16px; margin: 0 auto; max-width: 1100px; text-align: center;
}
.ed-card {
    display: flex; flex-direction: column; gap: 8px;
    padding: 16px 16px 18px;
    background: var(--ax-color-surface);
    border: 3px solid var(--ax-color-border);
    border-radius: 10px;
    font: inherit; color: inherit; cursor: pointer; text-align: center;
    transition: border-color var(--ax-duration-fast) var(--ax-ease-engineering),
                background var(--ax-duration-fast) var(--ax-ease-engineering);
}
.ed-card:hover { border-color: var(--ax-color-accent); }
.ed-card__name { font-size: 23px; letter-spacing: .03em; }
/* Редакция-основание: строка «Редакция Lite +» под названием. Цветом своей
   ступени и меньшим кеглем, чтобы не спорить с названием карточки, но и не
   теряться — без неё перечень читается как прибавка к самой карточке. */
.ed-card__base { font-size: 17px; letter-spacing: .02em; }
.ed-card.standard .ed-card__base { color: var(--ed-standard); }
.ed-card.pro      .ed-card__base { color: var(--ed-pro); }
.ed-card__adds { font-size: 16px; line-height: 1.5; }
.ed-card__limit {
    font-size: 16px; padding-top: 8px;
    border-top: 1px solid var(--ax-color-border);
}
.ed-card__price { font-size: 16px; color: var(--ax-color-text-muted); }
.ed-card__price b { color: var(--ax-color-text); }

.ed-card.lite     { border-color: var(--ed-lite); }
.ed-card.standard { border-color: var(--ed-standard); }
.ed-card.pro      { border-color: var(--ed-pro); }
.ed-card.lite     .ed-card__name { color: var(--ed-lite); }
.ed-card.standard .ed-card__name { color: var(--ed-standard); }
.ed-card.pro      .ed-card__name { color: var(--ed-pro); }
/* Выбранная — залита своим цветом: на телефоне рамка одна под другой не
   читается как «выбрано», а заливка читается. */
.ed-card.chosen.lite     { background: var(--ed-lite-soft); }
.ed-card.chosen.standard { background: var(--ed-standard-soft); }
.ed-card.chosen.pro      { background: var(--ed-pro-soft); }
.ed-card.chosen { box-shadow: inset 0 0 0 1px currentColor; }
/* Отметка «выбрать» / «выбрана».
 *
 * ПОЧЕМУ ЭТО НЕ ПРОСТО НАДПИСЬ. Правообладатель сообщил 18.08.2026, что под
 * карточкой Lite «нет кнопки выбрать». Надпись там была и рисуется без всяких
 * условий — но при кегле 13, серым приглушённым цветом и без единого признака
 * управляющего элемента она читалась как примечание к цене, а не как то, что
 * можно нажать. Сообщение «нет кнопки» точно описывает увиденное: кнопки
 * действительно не было, была надпись.
 *
 * Усугублялось это тем, что у ВЫБРАННОЙ карточки состояние передано заливкой и
 * потому очевидно, а у невыбранных единственным призывом к действию служил
 * самый бледный элемент карточки. То есть хуже всего выглядело ровно то, ради
 * чего карточку показывают.
 *
 * Насыщенность НЕ применяется: у гарнитуры нет полужирного начертания, и
 * браузер подделал бы его растягиванием контуров — это в проекте запрещено и
 * стережётся проверкой. Приметность даётся рамкой, полем вокруг текста и
 * цветом своей ступени. */
.ed-card__mark {
    margin-top: auto;
    align-self: center;
    padding: 8px 22px;
    border: 2px solid currentColor;
    border-radius: 6px;
    font-size: 16px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ax-color-accent);
    transition: background var(--ax-duration-fast) var(--ax-ease-engineering),
                color var(--ax-duration-fast) var(--ax-ease-engineering);
}
.ed-card.lite     .ed-card__mark { color: var(--ed-lite); }
.ed-card.standard .ed-card__mark { color: var(--ed-standard); }
.ed-card.pro      .ed-card__mark { color: var(--ed-pro); }
/* Наведение на карточку заливает отметку: подтверждает, что нажатие
   относится ко всей карточке, а не только к самой надписи. */
.ed-card:hover .ed-card__mark {
    background: currentColor;
    color: var(--ax-color-surface);
}
/* Выбранная: рамки нет, приглушена. Кнопкой она больше не является —
   нажимать её незачем, и вид не должен звать. */
.ed-card.chosen .ed-card__mark {
    border-color: transparent;
    padding: 8px 0;
    color: var(--ax-color-text-muted);
}
.ed-card.chosen:hover .ed-card__mark {
    background: none;
    color: var(--ax-color-text-muted);
}

/* Полоса испытаний. Цены на витрине висят, а денег не берут — без пометки
   посетитель решит, что с него их возьмут, и уйдёт. */
/* Полоса «идут испытания».
 *
 * Прежде она была почти невидима, и причина не в толщине рамки: фоном служил
 * `--ed-pro-soft` — тот же цвет, которым залита ВЫБРАННАЯ карточка редакции.
 * Полоса сливалась с карточкой над ней, а рамка в один пиксель тем же
 * акцентным цветом теряла последний контраст.
 *
 * Отсюда три правки, и первая важнее прочих:
 *
 * 1. Фон белый — «поверхность», а не заливка редакции. Полоса перестаёт
 *    зависеть от того, какая редакция выбрана: при Lite и Standard она прежде
 *    оставалась бежевой, то есть окрашенной в чужой цвет.
 * 2. Рамка втрое толще, 3 пикселя.
 * 3. Кегль 16 вместо 14 — вровень с текстом страницы.
 *
 * Насыщенность НЕ применяется: у гарнитуры нет полужирного начертания, и
 * браузер подделал бы его растягиванием контуров. Это в проекте запрещено и
 * стережётся проверкой. */
.trial-strip {
    margin: 16px auto 0; max-width: 1100px;
    padding: 12px 16px; border-radius: var(--ax-radius-base);
    background: var(--ax-color-surface);
    border: 3px solid var(--ax-color-accent);
    color: var(--ax-color-text);
    font-size: 18px; line-height: 1.45;
}


/* ═══════════════════════════════════════════════════════════════════════
   ОБВОДКА БЛОКОВ ПО ВЫБРАННОЙ РЕДАКЦИИ
   Цвет и подпись меняются на ВСЕХ блоках сразу: человек должен видеть, в
   какой редакции он сейчас работает, не поднимаясь к нулевому блоку.
   ═══════════════════════════════════════════════════════════════════════ */

.panel { position: relative; border-width: 2px; }
.panel-edition {
    position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
    padding: 0 12px; background: var(--ax-color-bg);
    font-size: 17px; letter-spacing: .04em; white-space: nowrap;
}
body.ed-lite     .panel { border-color: var(--ed-lite); }
body.ed-standard .panel { border-color: var(--ed-standard); }
body.ed-pro      .panel { border-color: var(--ed-pro); }
body.ed-lite     .panel-edition { color: var(--ed-lite); }
body.ed-standard .panel-edition { color: var(--ed-standard); }
body.ed-pro      .panel-edition { color: var(--ed-pro); }
body.ed-lite     .panel h2 .step { background: var(--ed-lite); color: #fff; }
body.ed-standard .panel h2 .step { background: var(--ed-standard); color: #fff; }
body.ed-pro      .panel h2 .step { background: var(--ed-pro); color: #fff; }


/* ═══════════════════════════════════════════════════════════════════════
   ОКНО ПОНИЖЕНИЯ РЕДАКЦИИ
   ═══════════════════════════════════════════════════════════════════════ */

#downgrade-modal .modal { width: min(560px, 94vw); }
.dg-list { margin: 10px 0; padding-left: 20px; font-size: 17px; }
.dg-list li { margin: 6px 0; }
.dg-list .need {
    font-size: 14px; letter-spacing: .05em; text-transform: uppercase;
    padding: 1px 6px; border-radius: var(--ax-radius-base); margin-left: 6px;
}
.dg-list .need.standard { background: var(--ed-standard); color: #fff; }
.dg-list .need.pro { background: var(--ed-pro); color: #fff; }
/* Три действия — в столбец: в строку они наползают друг на друга при
   длинных подписях, а на телефоне не помещаются вовсе. Выбор из трёх
   должен читаться сверху вниз, а не угадываться по обрезанным словам. */
.dg-actions { flex-direction: column; align-items: stretch; }
.dg-actions button { width: 100%; }
button.ghost.danger { color: var(--ax-color-danger); }

.acc-forgot { margin-top: -4px; }
button.linkish {
    background: none; border: none; padding: 0; font: inherit;
    font-size: 16px; color: var(--ax-color-accent); cursor: pointer;
    text-decoration: underline;
}


/* ═══════════════════════════════════════════════════════════════════════
   ТЕЛЕФОН
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
    /* Три кнопки редакций в ряд на телефоне — это три нечитаемых столбца
       по 110 пикселей. Ставим друг под друга: выбор всё равно делается
       один раз. */
    .editions { grid-template-columns: 1fr; }
    .intro { padding-top: 6px; }
    .ax-container { padding-inline: 14px; }
}


/* Колонки стыковки открываются вместе с режимом — как в настольной версии.
   Показывать их всегда значило бы предлагать заполнять поля, которые ни на
   что не влияют, пока режим выключен. */
body:not(.splice-on) .col-splice { display: none; }
@media (max-width: 860px) {
    body:not(.splice-on) td.col-splice { display: none; }
}

/* Производные размеры и эскиз — не поля ввода: их считает служба. Поле
   означало бы, что их можно задать руками, и заказчик задал бы. */
.col-calc { color: var(--ax-color-text-muted); text-align: right; }
td.c-sketch { text-align: center; color: var(--ax-color-text); }
td.c-sketch svg { vertical-align: middle; }


/* ═══════════════════════════════════════════════════════════════════════
   ЗНАКИ, КОТОРЫХ В ЧЕРТЁЖНОМ ШРИФТЕ НЕТ
   ═══════════════════════════════════════════════════════════════════════

   OpenGost Type B — шрифт 2011 года, знака рубля в нём нет: ₽ утверждён
   позже. Нет также стрелки, крестика и трёх черт, которыми размечены кнопки.

   Подстановка в браузере идёт познаково, так что рисоваться они будут
   запасной гарнитурой — но БЕЗ ЭТОГО ПРАВИЛА подставится первая попавшаяся
   системная, и в строке «180,00 ₽» рубль окажется другой ширины, другого
   веса и с другой базовой линией. Прямо в цене, то есть в самом заметном
   месте страницы.

   Задаём подстановку сами и одной гарнитурой на все такие знаки: тогда
   разнобой хотя бы один и тот же везде.
*/
@font-face {
    font-family: 'OpenGost Type B';
    src: local('PT Sans'), local('DejaVu Sans'), local('Arial');
    /* Только те знаки, которых в основном файле нет. Браузер возьмёт их
       отсюда, всё остальное — из чертёжного начертания. */
    unicode-range: U+20BD,          /* ₽ рубль */
                   U+2190-21FF,     /* стрелки */
                   U+2713-2717,     /* галочки и крестики */
                   U+2630,          /* ☰ три черты */
                   U+25A0-25FF;     /* геометрические знаки */
    font-weight: 400;
    font-display: swap;
}


/* ═══════════════════════════════════════════════════════════════════════
   ТАБЛИЦА СПЕЦИФИКАЦИИ: ДВАДЦАТЬ СТОЛБЦОВ В ОКНО НЕ ВХОДЯТ
   ═══════════════════════════════════════════════════════════════════════

   Ширина рабочей колонки — 1080 точек. Двадцать столбцов дают по 52 точки
   на каждый: в поле «Запрет от нач., мм» видна ОДНА цифра, и заполнить
   таблицу нельзя вообще. Заказчик уходит, не начав.

   Лечится тремя мерами сразу, поодиночке ни одна не спасает:
   1) блок спецификации выходит на всю ширину окна, а не в общую колонку;
   2) уточняющие столбцы по умолчанию скрыты — их восемь из двадцати;
   3) остаток при нехватке места прокручивается вбок, а первые столбцы
      остаются на виду: без них строка теряется на середине.
*/

/* 1. Блок спецификации шире прочих: у него иное содержимое и иные нужды.
 *
 * ВЫЛЕТ СЧИТАЕТСЯ ОТ СВОБОДНОЙ ШИРИНЫ, А НЕ ОТ ШИРИНЫ ОКНА.
 *
 * Правило раздвигает блок за пределы колонки в 1080 точек отрицательными
 * полями. Пока страница занимала всё окно, `100vw` и была свободной шириной.
 * С появлением боковых блоков это перестало быть верным: 608 точек окна заняты
 * колонками, и блок выехал на них — накрыл девиз слева и подлез под переход
 * справа.
 *
 * Отказа при этом нет никакого: страница работает, данные грузятся, просто
 * три части наложились друг на друга. Видно только глазами.
 *
 * `--ax-sides` объявлена на обёртке боковых блоков и обнуляется тем же
 * медиазапросом, что убирает колонки. Запасное значение `0px` восстанавливает
 * прежнее поведение там, где обёртки нет вовсе, — в настольном изделии и на
 * страницах без блоков.
 */
#p-spec {
    /* Шире прочих панелей, но не шире колонки: `100%` — это ширина `main`,
     * то есть колонки за вычетом её отступов. Ни `vw`, ни знания о боковых
     * блоках больше не требуется. */
    max-width: min(1800px, 100%);
}
@media (max-width: 1120px) {
    #p-spec { max-width: none; margin-inline: 0; }
}

/* 2. Уточняющие столбцы скрыты, пока не попросят. */
body:not(.cols-all) .col-extra { display: none; }

.spec-toolbar {
    display: flex; align-items: center; gap: 12px;
    margin: 4px 0 10px;
}
.spec-toolbar .hint { margin: 0; }
/* Скрытые столбцы — не мелкое уточнение, а объяснение, почему таблица не
   такая, как в настольной версии. Поэтому цвет отказа и разрядка.
   ЖИРНОГО НАЧЕРТАНИЯ У ШРИФТА НЕТ: `font-weight` дал бы поддельный жирный —
   браузер размазывает знаки, — а их мы выпалывали по всему листу в beta.89.
   Разрядка и цвет заменяют вес, как в шапке сайта. */
.spec-toolbar .cols-note {
    color: var(--danger);
    letter-spacing: .03em;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* 3. Прокрутка вбок с закреплёнными первыми столбцами. */
.table-scroll { overflow-x: auto; overflow-y: visible; }
.spec-table { min-width: 100%; }
.spec-table th, .spec-table td { white-space: nowrap; }

/* Первые два столбца не уезжают: по ним человек находит свою строку. */
.spec-table th:nth-child(1), .spec-table td:nth-child(1),
.spec-table th:nth-child(2), .spec-table td:nth-child(2) {
    position: sticky; z-index: 2;
    background: var(--bg-panel);
}
.spec-table th:nth-child(1), .spec-table td:nth-child(1) { left: 0; width: 40px; }
.spec-table th:nth-child(2), .spec-table td:nth-child(2) { left: 40px; }

/* Ширины по назначению столбца, а не поровну: в поле длины нужно пять
   знаков, в поле угла три, а в поле стали — слово целиком. */
.spec-table td input[type="number"] { width: 100%; min-width: 72px; }
.spec-table td input[type="text"]   { width: 100%; min-width: 106px; }
.spec-table td select               { width: 100%; min-width: 111px; }
.spec-table td input[type="checkbox"] { min-width: 0; }
.spec-table .c-length, .spec-table .c-fstart, .spec-table .c-fend { min-width: 90px; }
.spec-table .c-a1, .spec-table .c-a2, .spec-table .c-qty { min-width: 65px; }
.spec-table .c-profile { min-width: 173px; }
.spec-table .c-section { min-width: 127px; }

/* Кегль в таблице ниже общего: здесь важнее уместить строку, чем читать её
   с расстояния. Ниже 13 не опускаемся — чертёжный шрифт узкий и сливается. */
.spec-table { font-size: 15px; }
.spec-table td input, .spec-table td select { font-size: 15px; padding: 4px 6px; }
/* Заголовок столбца был 11 px — мельче данных, которые он называет, и мельче
   всего остального на странице. Название столбца читают чаще, чем значение:
   по нему находят, куда вводить. 12 px с разрядкой — тот же приём, что и в
   прочих подписях: у гарнитуры нет жирного начертания, и вес заменяется
   разрядкой. */
.spec-table th {
    font-size: 14px; padding: 6px 6px;
    letter-spacing: .03em;
    color: var(--ax-color-text);
}
.spec-table td { padding: 2px 3px; }

@media (max-width: 860px) {
    /* На телефоне строка разворачивается карточкой, прокрутка не нужна,
       а поля должны быть 16: мельче Safari приближает страницу при касании. */
    .table-scroll { overflow: visible; }
    .spec-table th:nth-child(1), .spec-table td:nth-child(1),
    .spec-table th:nth-child(2), .spec-table td:nth-child(2) { position: static; }
    .spec-table td input, .spec-table td select { font-size: 18px; }
    body:not(.cols-all) .col-extra { display: none; }
}

/* ── Деловые остатки ──────────────────────────────────────────────────────
   Таблица небольшая: три-пять строк, вводится руками. Поэтому она не
   растягивается на всю ширину — узкие поля читаются как «сюда немного», и
   человек не ищет, что ещё заполнить. */
.remnants { margin-top: 18px; }
.remnants__head {
    display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
}
.remnants__head h3 { font-size: 16px; margin: 0; }
.remnants__tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.remnants__tools a { font-size: 14px; color: var(--ax-color-accent); }
.remnants__table { border-collapse: collapse; margin-top: 8px; }
.remnants__table th {
    font-size: 14px; letter-spacing: .03em; padding: 6px 8px;
    text-align: left; color: var(--ax-color-text);
    border-bottom: 1px solid var(--border);
}
.remnants__table td { padding: 3px 4px; }
.remnants__table input { font-size: 15px; padding: 4px 6px; }
.remnants__table .r-length, .remnants__table .r-qty { width: 90px; }
.remnants__table .r-profile { width: 170px; }
.remnants__table .r-section, .remnants__table .r-grade { width: 120px; }
.remnants__table .r-del {
    padding: 2px 8px; font-size: 17px; line-height: 1; color: var(--text-muted);
}

/* Погашенный режим. Гасим, а не прячем: спрятанный орган заставляет искать,
   куда он делся, погашенный с подписью объясняет сам себя. */
.flag--off { opacity: .5; }
.flag--off input { cursor: not-allowed; }

/* ── Сечение вне справочника ──────────────────────────────────────────────
   Не запрещаем: прокат бывает нестандартный, и запрет остановил бы работу.
   Но и молчать нельзя — опечатка «80x80x50» иначе пройдёт как размер, и
   ошибка обнаружится на станке. */
.spec-table .c-section.off-standard { border-color: var(--ax-color-accent); }
.section-note {
    display: block; margin-top: 2px;
    font-size: 13px; color: var(--ax-color-accent); white-space: nowrap;
}

/* Строка ожидания в очереди. Приглушена намеренно: это служебное
   сообщение о ходе работы, а не результат. */
#calc-wait { color: #6B7480; margin-top: 8px; min-height: 1.2em; }


/* ==========================================================================
   БОКОВЫЕ БЛОКИ. Заготовка проекта «Сайт Axtoren», редакция от 16.08.2026.

   Вставлено без правок: девиз и переход между сервисами — часть облика
   марки, и расхождение вида между двумя приложениями недопустимо.
   Замечания по существу вносятся у составителя, а не здесь: правка на
   месте разошлась бы с раскроем листа молча.

   Гарнитура наследуется у страницы — своего @font-face в заготовке нет.
   `--ax-sides` приходит отсюда же: она говорит приложению, сколько ширины
   окна забрали колонки, чтобы блок, нарочно выходящий за рабочую колонку,
   считал свободную ширину верно.

   ВНИМАНИЕ. Наше приложение ею БОЛЬШЕ НЕ ПОЛЬЗУЕТСЯ: панель спецификации,
   ради которой величина заводилась, перешла на `max-width: min(1800px,
   100%)` и о боковых блоках знать перестала. Величина оставлена намеренно —
   она часть общего слоя и нужна приложениям, у которых такой блок есть.
   Здесь записано затем, чтобы «объявлено и не применяется» не выглядело
   недосмотром и чтобы её не сняли как лишнюю.
   ========================================================================== */
.ax-shell {
	--ax-text: #273341;
	--ax-accent: #DCA530;
	--ax-paper: #F2EFE6;
	--ax-side: 240px;
	--ax-gap: 32px;

	/*
	 * Сколько ширины окна забрали колонки.
	 *
	 * Приложению эта величина нужна, если какой-то его блок нарочно выходит
	 * за рабочую колонку — так сделано, например, с таблицей спецификации на
	 * двадцать столбцов. Без неё блок считает свободной шириной всё окно,
	 * включая занятое колонками, и обязан ошибиться ровно на это число.
	 *
	 * Считать так:
	 *     свободно = calc(100vw - ваши отступы - var(--ax-sides, 0px))
	 *
	 * Запасное значение 0px существенно: там, где обёртки нет — в настольном
	 * изделии, на страницах без блоков, — расчёт вернётся к прежнему.
	 */
	--ax-sides: calc(var(--ax-side) * 2 + var(--ax-gap) * 4);

	/*
	 * Гарнитура наследуется у страницы, а не объявляется здесь.
	 *
	 * Своё объявление дало бы два имени одного семейства на одной
	 * странице: двойную загрузку в лучшем случае, подмену шрифта
	 * в одном блоке при исправном виде остальных — в худшем. Второе
	 * читается как небрежность вёрстки, а не как отказ, и потому
	 * не чинится.
	 */
	font-family: inherit;
	display: grid;
	/*
	 * ОПОРА ДЛЯ НАЛОЖЕННОГО ДЕВИЗА.
	 *
	 * Строчный девиз при ширине от 1100 становится `position: absolute` и
	 * встаёт по `left: 0` — предполагалось, что от левого края рабочей
	 * области. Ниже стояло `.ax-shell__work { position: relative }` именно
	 * ради этого, и оно НЕ РАБОТАЛО: девиз — не потомок рабочей области, а
	 * её СОСЕД по сетке. Опорой ему оказывалась не она, а начальный блок
	 * страницы, и девиз уходил в левый верхний угол окна, где обрезался
	 * шапкой сайта.
	 *
	 * Отказа при этом не было никакого: страница цела, ошибок нет, видно
	 * только глазами — и увидел это правообладатель на снимке экрана, а не
	 * проверка. Найдено 23.08.2026 по письму проекта PlateCut Optimizer.
	 *
	 * Опора здесь. Наложенному ребёнку сетки опорой служит ЕГО ЯЧЕЙКА, если
	 * позиционирована сама сетка, — то есть ровно рабочая колонка, как и
	 * задумывалось: `grid-column`/`grid-row` девиза названы явно в каждой
	 * полосе ширин.
	 */
	position: relative;
	grid-template-columns: var(--ax-side) minmax(0, 1fr) var(--ax-side);
	gap: var(--ax-gap);
	align-items: start;
	max-width: 1920px;
	margin-inline: auto;
	padding-inline: var(--ax-gap);
}

/*
 * РАСКЛАДКА НАЗЫВАЕТСЯ ЯВНО, А НЕ СКЛАДЫВАЕТСЯ ИЗ ПОРЯДКА ДЕТЕЙ.
 *
 * Детей у обёртки ЧЕТЫРЕ — строчный девиз, левая полоса, рабочая область,
 * правая полоса, — а колонок объявлено три. Пока строчный девиз погашен, всё
 * сходится случайно: три видимых ребёнка на три колонки.
 *
 * Стоит девизу показаться — он занимает первую колонку, рабочая область
 * получает 170 точек, а блок перехода уезжает на следующую строку. Ошибки при
 * этом нет никакой: сетка разложила ровно то, что ей дали.
 *
 * Обнаружено проектом сайта 19.08.2026 при наложении новой раскладки: первая
 * же проба развалила страницу. Добавит кто-нибудь пятого ребёнка — вёрстка
 * съедет так же беззвучно, поэтому столбец и строка называются каждому.
 */
.ax-shell > .ax-shell__motto-inline { grid-column: 2; grid-row: 2; }
.ax-shell > .ax-shell__side:has(.ax-motto) { grid-column: 1; grid-row: 1 / span 2; }
.ax-shell > .ax-shell__work { grid-column: 2; grid-row: 2; }
.ax-shell > .ax-shell__side:has(.ax-cross) { grid-column: 3; grid-row: 1 / span 2; }

/*
 * ЛИПКОСТЬ РАЗВЕДЕНА: переход остаётся, девиз уезжает.
 *
 * Указание правообладателя от 23.08.2026, переданное проектом PlateCut
 * Optimizer. Довод их, и он верный: блок перехода — единственный путь из
 * сервиса в сервис, терять его при прокрутке нельзя. Девиз не открывает
 * ничего, а висящая надпись у длинной ведомости мешает.
 *
 * НАЙДЕНО ИХ ПИСЬМОМ, А НЕ НАМИ. Выпуск 1.34.21 записал: «не липкий, уезжает
 * с заголовком; липким остался только блок перехода» — но относилось это к
 * СТРОЧНОМУ девизу, который липким и не был. Боковая колонка с девизом
 * оставалась липкой, и пояснение над правилом прямо говорило «обе колонки».
 * Запись о сделанном и сделанное разошлись на два дня.
 *
 * sticky, а не fixed: fixed вынимает блок из потока и он перекрывает
 * содержимое на коротких страницах и при увеличении масштаба. sticky
 * держится в границах своей колонки и ведёт себя предсказуемо.
 */
.ax-shell__side:has(.ax-cross) {
	position: sticky;
	top: 24px;
	/*
	 * Без этого элемент растягивается на всю высоту строки сетки, и липкость
	 * не срабатывает: липнуть нечему — блок и так занимает всю строку.
	 * Из заготовки проекта сайта, редакция 2.
	 */
	align-self: start;
}

/*
 * Колонка девиза объявлена НЕЛИПКОЙ явно, а не оставлена без правила.
 *
 * Заготовка задаёт липкость всем боковым колонкам одним правилом. Внеси её
 * следующую редакцию — и девиз снова прилипнет, а отсутствие нашего правила
 * прочтётся как «об этом не думали». Явное `static` говорит, что думали.
 */
.ax-shell__side:has(.ax-motto) {
	position: static;
	align-self: start;
}

/* --------------------------------------------------------------------------
   Скрытие на узких экранах
   -------------------------------------------------------------------------- */

/*
 * Ниже 1400 точек боковые колонки убираются, и рабочая область получает всю
 * ширину. Это не уступка мелким экранам, а условие работы: карта раскроя —
 * чертёж, и отнимать у неё 480 точек ради девиза значит мешать тому, ради
 * чего человек пришёл.
 *
 * Девиз при этом не пропадает совсем — переезжает под шапку строкой.
 */
/*
 * Порядок правил здесь существен.
 *
 * Медиазапрос веса правилу не добавляет: избирательность у обоих одна —
 * один класс. При равном весе побеждает то, что стоит ниже. Поставь
 * display: none после медиазапроса — и девиз не покажется ни при какой
 * ширине, причём беззвучно: ошибки нет, страница цела, элемента просто
 * не видно.
 *
 * Поэтому скрытие объявлено первым, показ — вторым.
 */
.ax-shell__motto-inline {
	display: none;
	margin: 0 0 20px;
	/*
	 * ГРАФИТ, А НЕ ЗОЛОТО. Золото на ватмане даёт отношение яркостей 1,93
	 * при норме 4,5 для текста этого кегля — строка не просто выглядит
	 * иначе, она плохо читается, и хуже всего там, где ею и будут
	 * пользоваться: яркий свет, дешёвый монитор, цех. Графит даёт 11,16.
	 *
	 * В БОКОВОМ виде золото остаётся: там кегль 46 и золотом набрано одно
	 * слово из трёх — как украшение оно работает.
	 */
	color: var(--ax-text);
	/*
	 * Кегль и разрядка — как у подзаголовка «для расчёта линейного (1D)
	 * раскроя материала». Прежние 22 точки с разрядкой 0,16 и прописными
	 * давали вид отдельной надписи, спорящей с заголовком; одинаковый
	 * кегль ставит девиз в один ряд с подзаголовком, где ему и место.
	 */
	font-size: clamp(18px, 2.6vw, 26px);
	letter-spacing: 0.015em;
	/*
	 * ПРОПИСНЫЕ СНЯТЫ — заготовка проекта сайта, редакция 2 от 20.08.2026,
	 * правка 2. Прописные вместе с разрядкой 0.16em давали вид отдельной
	 * надписи, спорящей с названием программы. Разрядку мы убавили сразу,
	 * а прописные оставили по недосмотру: правка была наполовину.
	 */
	text-transform: none;
	/*
	 * НЕ ЛИПКИЙ — в отличие от блока перехода. Тот нужен в любой момент,
	 * девиз нет: он довод при выборе редакции, а не средство управления.
	 * Уезжает вверх вместе с названием программы.
	 */
	margin: 0;
	max-width: var(--ax-side, 170px);
	z-index: 1;
}

/*
 * РУБЕЖ НАЛОЖЕНИЯ — 1100 px. Заготовка проекта сайта, редакция 3 от
 * 21.08.2026.
 *
 * Наложение держится, пока слева от названия остаётся место. Место кончается —
 * и девиз наезжает на название. Ни у нас, ни у сайта рубежа не было: устройство
 * наложения взяли наше, а предел ему поставили они.
 *
 * Число сложено по метрикам гарнитуры для самого длинного названия —
 * «Онлайн-сервис ProfileCut Optimizer», 528 px при кегле 41:
 *
 *     ширина   слева от названия   девиз   зазор
 *       1366                 298     214      84
 *       1200                 304     214      90
 *       1100                 254     214      40
 *       1050                 229     209      20
 *       1000                 210     199      12
 *
 * Зазор падает ниже 24 px при 1060; рубеж 1100 взят с запасом.
 *
 * У PlateCut Optimizer порог столкновения ниже — название короче. Рубеж один
 * на оба приложения, по худшему случаю. ПОЯВИТСЯ ПРИЛОЖЕНИЕ С БОЛЕЕ ДЛИННЫМ
 * НАЗВАНИЕМ — рубеж пересчитать.
 */
@media (min-width: 1100px) {
	.ax-shell__motto-inline {
		position: absolute;
		left: 0;
		top: 8px;                   /* padding-top у .intro */
		pointer-events: none;       /* не перехватывает нажатия у заголовка */
	}
}

/*
 * ПОЛОЖЕНИЕ ДЕВИЗА: у левого края рабочей области, на высоте названия
 * программы. Требование правообладателя, переданное проектом сайта 21.08.2026.
 *
 * ЗАЧЕМ ИМЕННО ТАК. При этой постановке девиз оказывается рядом с выбором
 * редакции. «Время дороже денег» рядом с ценами — не украшение, а довод в
 * пользу платного расчёта, поставленный там, где человек решает. Прежнее
 * положение над шапкой сайта этого не давало: строка читалась как заголовок
 * всего сайта, а не как довод этой страницы.
 *
 * ПОЧЕМУ НАЛОЖЕНИЕМ, А НЕ СТРОКОЙ В ПОТОКЕ. Заголовок выровнен по центру
 * рабочей области; поставить девиз слева на той же высоте, не наложив одно на
 * другое, нельзя. Наложение безопасно: проект сайта проверил запас по метрикам
 * гарнитуры — на самой узкой ходовой ширине 1366 свободного места слева от
 * заголовка 304 точки против 199 у девиза, запас 105. Кегль заголовка при этом
 * уже упёрся в потолок `clamp` (40 px) и шире не станет.
 *
 * `pointer-events: none` — чтобы наложенный блок не перехватывал нажатия,
 * предназначенные заголовку. Текст девиза нажимать не на что.
 */
/*
 * Прежде здесь стояло `.ax-shell__work { position: relative }` — как опора для
 * наложенного девиза. Опорой оно ему не было: девиз рабочей области не
 * потомок, а сосед по сетке. Опора перенесена на `.ax-shell` (см. там), а это
 * правило снято, чтобы не выглядело действующим: правило, объявленное ради
 * цели, которой не достигает, лжёт так же, как мёртвое умолчание.
 */

/*
 * Предел 1688 выведен из устройства страницы приложения, а не взят на глаз:
 *
 *     1080 рабочая область + 480 две колонки + 64 промежутки + 64 отступы
 *
 * Выше него колонки занимают место, которое рабочей области и так не нужно.
 * Ниже — отнимают у ввода спецификации. Если предел рабочей области
 * изменится, это число пересчитывается тем же сложением.
 *
 * ВНИМАНИЕ. Слагаемое 480 + 64 + 64 = 608 — это и есть --ax-sides выше.
 * Правила для медиазапросов переменных не понимают, поэтому число здесь
 * записано отдельно. Меняя --ax-side или --ax-gap, пересчитайте и порог:
 * переменная пересчитается сама, а это число — нет, и они разойдутся молча.
 */
/*
 * СРЕДНЯЯ ПОЛОСА ШИРИН: одна колонка вместо двух — асимметрично.
 *
 * ЗАЧЕМ АСИММЕТРИЯ. У девиза запасной вид ЕСТЬ — он переезжает в строку. У
 * блока перехода запасного вида НЕТ НИКАКОГО. Убирая обе колонки разом, мы
 * теряем не украшение, а единственный путь из этого приложения в соседнее, и
 * теряем молча.
 *
 * ЗАЧЕМ ВООБЩЕ. Прежний порог 1687 оставлял без блока перехода 1536 (это
 * 1920 при масштабе системы 125 %), 1440 и 1366 — то есть большинство рабочих
 * машин. Одна колонка занимает 242 точки против 608, и порог падает до 1321:
 * блок перехода виден на всех ходовых ширинах, кроме 1280 и уже.
 *
 * Предложено и проверено наложением проектом сайта 19.08.2026 на пяти
 * ширинах: липкость сохраняется, таблица спецификации целиком в границах.
 */
@media (max-width: 1687px) and (min-width: 1322px) {
	.ax-shell {
		--ax-side: 170px;
		--ax-gap: 24px;
		/* Одна колонка: 170 + промежуток + два поля по 24. */
		--ax-sides: calc(var(--ax-side) + var(--ax-gap) * 3);
		grid-template-columns: minmax(0, 1fr) var(--ax-side);
	}

	.ax-shell > .ax-shell__motto-inline { display: block; grid-column: 1; grid-row: 2; }
	.ax-shell > .ax-shell__work         { grid-column: 1; grid-row: 2; }
	.ax-shell > .ax-shell__side:has(.ax-cross) {
		display: block; grid-column: 2; grid-row: 1 / span 2;
	}
	.ax-shell > .ax-shell__side:has(.ax-motto) { display: none; }
}

/*
 * УЗКИЕ ШИРИНЫ: колонок нет вовсе, девиз строкой.
 *
 * Ниже 1322 даже одна колонка отнимает у рабочей области больше, чем та может
 * отдать: карта раскроя — чертёж, и место ей нужнее, чем связи между
 * приложениями.
 */
@media (max-width: 1321px) {
	.ax-shell {
		grid-template-columns: minmax(0, 1fr);

		/*
		 * Обнуляется ТЕМ ЖЕ медиазапросом, что убирает колонки.
		 *
		 * Обнулись она в другом месте — ниже порога блок приложения
		 * недосчитался бы точек, которых никто не занял. Ошибки при этом
		 * не будет: просто содержимое окажется уже, чем могло бы.
		 */
		--ax-sides: 0px;
	}

	.ax-shell__side {
		display: none;
	}

	.ax-shell > .ax-shell__motto-inline {
		display: block;
		grid-column: 1;
		grid-row: 2;
	}

	.ax-shell > .ax-shell__work { grid-column: 1; grid-row: 2; }
}


/* --------------------------------------------------------------------------
   Левый блок: девиз
   -------------------------------------------------------------------------- */

.ax-motto {
	line-height: 1.05;
	color: var(--ax-text);
}

.ax-motto__line {
	display: block;
	font-size: clamp(30px, 2.6vw, 46px);
	letter-spacing: 0.02em;
}

/*
 * Выделение размером и разрядкой, а не насыщенностью.
 *
 * У этой гарнитуры одно начертание — полужирного нет вовсе. Браузер, получив
 * font-weight: bold, подделает его утолщением контура, и на тонком чертёжном
 * шрифте это расплывается. Разрядка даёт тот же смысловой вес и не портит
 * рисунок буквы.
 */
.ax-motto__line--accent {
	color: var(--ax-accent);
	letter-spacing: 0.08em;
}

.ax-motto__rule {
	width: 56px;
	height: 2px;
	margin: 20px 0 0;
	background: var(--ax-accent);
	border: 0;
}

/* --------------------------------------------------------------------------
   Правый блок: переход в соседний сервис
   -------------------------------------------------------------------------- */

.ax-cross {
	padding: 22px 20px;
	border: 1px solid rgba(39, 51, 65, 0.18);
	border-left: 3px solid var(--ax-accent);
	border-radius: 3px;
	background: var(--ax-paper);
	color: var(--ax-text);
}

.ax-cross__label {
	margin: 0 0 10px;
	font-size: 15px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: rgba(39, 51, 65, 0.6);
}

.ax-cross__title {
	margin: 0 0 10px;
	/*
	 * 22, а не 23. Уточнение правообладателя от 21.08.2026: всё, кроме
	 * заголовков, поднимается на два; заголовки — на один. Прежнее толкование
	 * «всё на два» дало 23.
	 */
	font-size: 22px;
	line-height: 1.3;
}

.ax-cross__note {
	margin: 0 0 18px;
	font-size: 17px;
	line-height: 1.5;
	color: rgba(39, 51, 65, 0.78);
}

.ax-cross__link {
	display: inline-block;
	padding: 10px 18px;
	font-size: 17px;
	color: var(--ax-paper);
	background: var(--ax-text);
	border-radius: 3px;
	text-decoration: none;
	transition: background 0.15s ease;
}

.ax-cross__link:hover,
.ax-cross__link:focus-visible {
	background: var(--ax-accent);
	color: var(--ax-text);
}

/* --------------------------------------------------------------------------
   Перекрёстное переключение
   -------------------------------------------------------------------------- */

/*
 * Оба варианта лежат в разметке, показывается противоположный текущему
 * сервису. Сценариев не требуется, и подстановка не может опоздать к
 * отрисовке.
 *
 * ПРАВИЛО ВЫВЕРНУТО 21.08.2026 по заготовке проекта сайта, редакция 2.
 *
 * Прежде гасился блок, ведущий на ТЕКУЩИЙ сервис. При верном значении
 * `data-ax-service` итог тот же, но отказы разные:
 *
 *   было:  значение потеряно или написано с опиской → видны ОБА блока,
 *          включая ведущий на самого себя. Посетитель нажимает «второй
 *          сервис — раскрой профиля», попадает на ту же страницу и решает,
 *          что программа сломана;
 *   стало: значение потеряно → не виден НИ ОДИН. Потеря связи заметна нам
 *          и не выглядит поломкой для посетителя.
 *
 * Показывать ссылку на самого себя хуже, чем не показывать ничего.
 */
.ax-cross--to-sheet,
.ax-cross--to-profile {
	display: none;
}

.ax-shell[data-ax-service="profile"] .ax-cross--to-sheet,
.ax-shell[data-ax-service="sheet"] .ax-cross--to-profile {
	display: block;
}

/* Уважение к настройке системы: убирать движение, если так задано. */
@media (prefers-reduced-motion: reduce) {
	.ax-cross__link {
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Момент показа правого блока: всегда, кроме времени счёта
   --------------------------------------------------------------------------

   Правило одно на оба сервиса: блок скрыт от нажатия «рассчитать» до
   получения результата, в остальное время виден.

   Почему не «всегда». В раскрое листа счёт идёт минутами. Всё это время на
   виду висело бы предложение уйти в другое приложение — при долгом ожидании
   оно читается как приглашение бросить начатое. Ушедший теряет результат, а
   занятое его расчётом ядро расходуется впустую.

   Почему не «только после расчёта». Тогда блок не увидит тот, кто зашёл
   впервые и ещё ничего не считал, — а ему знание о втором сервисе нужнее
   всех.

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

   Способ: приложение добавляет класс ax-shell--busy на обёртку при отправке
   задания и снимает по получении ответа — в том числе при отказе, иначе блок
   останется скрытым до перезагрузки страницы.
   -------------------------------------------------------------------------- */

.ax-shell--busy .ax-cross {
	display: none;
}

.ax-shell__work { min-width: 0; }

/* Сколько ширины окна забрали боковые блоки.
 *
 * ВЫЧИСЛЯЕМАЯ, А НЕ ЧИСЛОМ. Своё объявление здесь стояло числом 608; проект
 * «Сайт Axtoren» внёс переменную в саму заготовку и записал её через ширину
 * колонки и промежутка. Число 608 разошлось бы с ними молча при первой же
 * правке ширины колонки.
 *
 * Объявление снято отсюда: оно теперь приходит с заготовкой, и два места,
 * задающие одну величину, разъехались бы — ровно то, от чего заготовка и
 * заводилась. */
