/* ОБЩИЙ ОБЛИК ПРИЛОЖЕНИЙ AXTOREN
 * ==============================================================
 *
 * Два приложения одного правообладателя обязаны выглядеть одним изделием.
 * Образцом назначен ProfileCut Optimizer — не по старшинству, а потому что у
 * темы сайта нет стилей форм, а у него они есть и проверены работой.
 *
 * Источник: `app.css` ProfileCut Optimizer, выпуск 1.34.21, документ
 * «Облик ProfileCut Optimizer: образец для приведения к общему виду»
 * от 19.08.2026.
 *
 * ## ЧИСЛА ЗДЕСЬ НЕ ПЕРЕПЕЧАТАНЫ, А ИЗВЛЕЧЕНЫ
 *
 * Куски ниже перенесены из файла образца построчно, без правки значений.
 * Требование составителя: «берите из файла, а не переписывайте из текста —
 * цифры в тексте устаревают, файл нет». Всякая правка облика вносится У
 * СОСТАВИТЕЛЯ и приходит сюда переносом; правка на месте разошлась бы с
 * раскроем профиля молча, а расхождение вида читается как «меня перебросили
 * на сторонний сервис».
 *
 * Названия переменных сохранены как в образце, включая приставку `pco-`:
 * переименование оборвало бы сверку с образцом при следующем переносе.
 *
 * ## ЧЕГО ЗДЕСЬ НЕТ И ПОЧЕМУ
 *
 * **Временного правила, скрывающего блок перехода.** У образца он скрыт
 * распоряжением от 19.08.2026: приложение нестинга сырое, и вести в него
 * посетителей рано. У нас блок ведёт В ОБРАТНУЮ сторону — в работающий раскрой
 * профиля, — и скрывать его незачем. Взять правило вместе с прочим значило бы
 * погасить единственную связь между сервисами, причём молча.
 *
 * **Частностей раскроя профиля** — плавающей кнопки, окна кабинета, вылета
 * таблицы на двадцать столбцов. Их разметки у нас нет, и мёртвые правила лишь
 * мешали бы сверке.
 *
  * **Шапка и подвал сайта перенесены 20.08.2026** — прежде их здесь не было:
 * разметка жила в теме, и правила ничего не оформляли. Проект сайта отдал её
 * источником (`/shell/header/`, `/shell/footer/`), и правила понадобились.
 *
 * Пропуск был виден глазами и только глазами: страница отдавала логотип без
 * размера, меню простым списком и ссылку «Перейти к основному содержимому»
 * посреди экрана. Ни одна проверка этого не сказала — они сторожили наличие
 * разметки и зависимостей, а не то, что разметка оформлена.
 */



/* ==== ЧЕРТЁЖНЫЙ ШРИФТ — AXTOREN DRAFT B (выпуск 3.2.37) ====
 *
 * Прежде здесь стояло объявление образца: 'OpenGost Type B', файлы сперва
 * у темы сайта, своя копия вторым источником. Файл темы — ИЗМЕНЁННАЯ версия
 * OpenGost Type B TT (достроены буквы с диакритикой), а исходный шрифт
 * объявляет «OpenGost Type B» зарезервированным именем: по пункту 3 SIL
 * OFL 1.1 изменённой версии его носить нельзя (письмо проекта сайта
 * AXT-SITE-ИСХ-004). Решение Правообладателя от 09.10.2026 — переименовать.
 *
 * С выпуска 3.2.38 тема переименовала свой файл тем же именем (письмо
 * AXT-SITE-ИСХ-005, выпуск темы 10.16; общее имя — решение
 * Правообладателя от 10.10.2026), и ПОРЯДОК ИСТОЧНИКОВ — снова как в
 * образце: сначала файлы темы (домен общий, кеш браузера один), потом своя
 * копия — для показа не под адресом сайта, где путь `/wp-content/` попадает
 * в само приложение и отвечает 404. Своя копия — тот же файл темы байт в
 * байт (`axtoren-draft-b-ax1.woff`, свёртку сверяет `check_look`). */
@font-face {
    font-family: 'Axtoren Draft B';
    src: url('/wp-content/themes/axtoren-theme/fonts/axtoren-draft-b-ax1.woff2') format('woff2'),
         url('/wp-content/themes/axtoren-theme/fonts/axtoren-draft-b-ax1.woff') format('woff'),
         url('fonts/axtoren-draft-b-ax1.woff') format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* ГАРНИТУРА ИНТЕРФЕЙСА — FIRA SANS (выпуск 3.2.32).
 *
 * Письмо проекта «Сайт Axtoren» от 09.10.2026, ред. 1: для сайта и
 * приложений утверждён Fira Sans; OpenGost Type B уходит из интерфейса, но
 * остаётся в чертежах: эскизы каталога (`sketch.css`), чертёж детали,
 * карты раскроя SVG и карты в отчёте PDF (решение Правообладателя от
 * 09.10.2026: «Я бы предпочёл, чтобы в чертежах использовался чертёжный
 * шрифт»; выпуск 3.2.36 — в 3.2.35 чертежи были переведены на Fira).
 * Текст отчёта PDF — Fira Sans. Причина смены —
 * у OpenGost одно начертание, и вес заголовков изображался разрядкой.
 *
 * Файлы — из репозитория Google Fonts (`ofl/firasans/`), версия 4.203,
 * без переделки: те же байты, что у сайта (свёртки — в `check_look`).
 * Лицензия SIL OFL 1.1 — `fonts/OFL-FiraSans.txt` рядом со шрифтом.
 *
 * Своя копия — единственный источник: путь к файлам Fira в теме сайта нам
 * не назван, а угаданный путь на поддомене дал бы молчаливую подмену
 * запасной гарнитурой (случай beta.86, описан выше). */
@font-face {
    font-family: 'Fira Sans';
    src: url('fonts/FiraSans-Regular.ttf') format('truetype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Fira Sans';
    src: url('fonts/FiraSans-Medium.ttf') format('truetype');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Fira Sans';
    src: url('fonts/FiraSans-SemiBold.ttf') format('truetype');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Fira Sans';
    src: url('fonts/FiraSans-Bold.ttf') format('truetype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* Знак диаметра ⌀ U+2300. В Fira его нет ни в одном начертании (письмо
 * сайта, 5.2; проверено обходом файла). Для одного этого кода объявлена
 * подстановка из OpenGost Type B — так же, как на сайте, — с поправкой
 * высоты: прописные у OpenGost 0,5882 em против 0,6890 у Fira, и без
 * поправки знак стоял бы на 15 % ниже соседних букв. */
@font-face {
    /* Выпуск 3.2.37: из переименованного чертёжного шрифта (прежде —
     * 'OpenGost Диаметр' из файла под зарезервированным именем). */
    font-family: 'Axtoren Draft B Знаки';
    src: url('/wp-content/themes/axtoren-theme/fonts/axtoren-draft-b-ax1.woff2') format('woff2'),
         url('/wp-content/themes/axtoren-theme/fonts/axtoren-draft-b-ax1.woff') format('woff'),
         url('fonts/axtoren-draft-b-ax1.woff') format('woff');
    /* ⟂ U+27C2 — с выпуска 3.2.34: знак правил каталога («ось конуса ⟂
       оси магистрали»), в Fira его нет, в OpenGost есть. */
    unicode-range: U+2300, U+27C2;
    size-adjust: 117%;
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* ==== ИЗ ОБРАЗЦА, строки 51–103 ====
   Палитра, переменные и запасные гарнитуры — из темы сайта без изменений. */

: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;
    /* ВЫСОТА ЛИПКОЙ ШАПКИ САЙТА — ОДНА ВЕЛИЧИНА НА ВЕСЬ ЛИСТ.
       Поля 16 пунктов сверху и снизу, знак 62 и черта 1 дают 95; берём 96.
       Прежде число стояло в поправке якорей само по себе, а липкий боковой
       блок отсчитывался от верха окна и уходил под шапку: его заголовок
       срезался при прокрутке (замечание Правообладателя от 28.09.2026).
       Две величины об одном разошлись бы и впредь. */
    --ax-header-height: 96px;
    --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, и без запасных на половине из них были бы пустые
       прямоугольники. */
    /* Выпуск 3.2.32: Fira Sans; первой — подстановка знака диаметра. */
    --ax-font-base: 'Axtoren Draft B Знаки', 'Fira Sans', 'PT Sans', 'Noto Sans', Arial, sans-serif;
    /* Чертёжный шрифт — для надписей на чертежах (выпуск 3.2.36, решение
     * Правообладателя от 09.10.2026). Имя — здесь, рядом с основным, чтобы
     * свой лист его не вписывал. */
    --ax-font-draw: 'Axtoren Draft B', 'Fira Sans', 'PT Sans', 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;
}

/* ==== ИЗ ОБРАЗЦА, строки 105–126 ====
   Запрет поддельного жирного, основа страницы. */

/* Выделение — настоящим полужирным (выпуск 3.2.32): у Fira Sans есть
   начертания 400, 500, 600 и 700. Прежде, при OpenGost с одним
   начертанием, вес изображался разрядкой, и поддельный жирный был
   запрещён; запрет теперь — на вес, которого нет в поставке
   (`check_look`). */
b, strong, th, .brand {
    font-weight: 600;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--ax-font-base);
    /* 17 — как в теме сайта (выпуск 3.2.32). 19 стояло ради узкого
       OpenGost, сливавшегося при мелком кегле; Fira шире и при 17 читается.
       Не мельче 16: Safari приближает страницу при касании поля мельче. */
    font-size: 17px;
    color: var(--text-main);
    background: var(--bg-main);
    line-height: 1.55;
}

/* ==== ИЗ ОБРАЗЦА, строки 163–197 ====
   Ширина рабочей области объявлена ОДИН РАЗ. */

/* ---- Раскладка ---- */
/* ШИРИНА РАБОЧЕЙ ОБЛАСТИ ОБЪЯВЛЕНА ОДИН РАЗ.
 *
 * Прежде 1080 и 20 стояли здесь, а те же числа — в расчёте вылета панели
 * спецификации (`#p-spec` ниже). Две части считали одну величину порознь, и
 * поправь кто-нибудь ширину здесь — вылет посчитался бы от прежней. Молча:
 * панель просто встала бы не по месту.
 *
 * Правило проекта «Сайт Axtoren», выведенное из трёх наших отказов подряд:
 * если две части считают одну величину порознь, они разойдутся — не оттого,
 * что кто-то ошибётся, а оттого, что у них нет способа узнать об изменении
 * друг у друга. Лечение одно: передать число явно.
 */
:root {
    /* Ширина рабочей полосы. 1080 → 1300 выпуском 108 по решению
       Правообладателя от 13.09.2026: примерно на пятую часть шире.

       Карта раскроя вписывается в эту ширину, и на листе 1500 × 3000
       прибавка идёт прямо в разборчивость: деталь на экране становится
       крупнее без всякого увеличения. */
    --pco-work-max: 1300px;
    --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;
}

/* ==== ИЗ ОБРАЗЦА, строки 198–262 ====
   Панели, поля, кнопки, таблицы. */


/* Панели держат прежнюю ширину и центрируются в колонке. */
.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;
    font-weight: 600;
    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; font-weight: 600; 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; font-weight: 600; 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; font-weight: 600; 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); font-weight: 600; }

/* ==== ИЗ ОБРАЗЦА, строки 306–336 ====
   Состояния, скрытие. */


/* ---- Состояния ---- */
.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; }


/* ==== ИЗ ОБРАЗЦА, строки 411–559 ====
   Справка: значок, пузырь, черта, ссылка в библиотеку. */

/* ── Значок подсказки «?» ────────────────────────────────────────────────

   Оформления у него в веб-версии НЕ БЫЛО ВООБЩЕ: модуль подсказок перенесли
   из настольной программы, а его правила остались в `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;
}

/* ==== ЗАГОТОВКА БОКОВЫХ БЛОКОВ И ШАПКИ ПРИЛОЖЕНИЯ, РЕДАКЦИЯ 7 ====
   Источник: `ax-sidebars-red7.css`, проект «Сайт Axtoren», 23.08.2026,
   приложение к письму `ПИСЬМО_сайта_zagotovka_red7.md`.
   Заменяет редакцию 5 целиком.

   SHA-256 внесённого файла:
   c3a4a85dc52fb266d31b771da4e74260d91d6f54333cefa3072eecb7c47ef1d6

   ВНИМАНИЕ: файлов редакции 7 пришло ДВА, под одним именем и с разными
   свёртками. Первый (`7885733b…`, 519 строк) пришёл отдельно, второй
   (`c3a4a85d…`, 529 строк) — приложением к письму. Различие только в
   пояснении: второй несёт решение Правообладателя от 23.08.2026 о том, что
   условия оплаты в шапку не входят.

   Внесён ВТОРОЙ — последний по времени, по указанию Правообладателя. Первый
   не вносился.

   Вставлено БЕЗ ПРАВОК, целиком, включая пояснения источника.

   ЧТО ЗАКРЫЛА ЭТА РЕДАКЦИЯ:

   1. ОПОРА НАЛОЖЕНИЯ перенесена на `.ax-shell`; лживое правило у
      `.ax-shell__work` снято, а не оставлено. Найдено ProfileCut 23.08.2026.

   2. ЯЧЕЙКА ДЕВИЗУ НАЗНАЧЕНА. Найдено нами: правки редакции 6 было мало —
      «ячейка служит опорой только если она назначена».

      Причина названа составителем прямо: назначение стояло в редакции 3 и
      было обронено при перестройке начала файла в редакции 5. Второй такой
      случай в этой же заготовке — в редакции 2 так же выпало правило
      `.ax-shell--busy`, и нашли его тоже мы. Перестройка куска теряет
      содержимое без следа.

   3. ЛИПКОСТЬ РАЗВЕДЕНА: девиз уезжает, блок перехода остаётся. Наша
      надстройка принята и стала общей.

   4. УСЛОВИЯ ОПЛАТЫ В ШАПКУ НЕ ВХОДЯТ — решение Правообладателя. Класс
      `.intro__terms` из шапки убран; текст со страницы не убран, перенесён
      в тело.

   Все правки, лежавшие у нас временными восполнениями в `style.css`, СНЯТЫ
   этим же выпуском.
   ==== */

/* ============================================================================
   БОКОВЫЕ БЛОКИ И ШАПКА ПРИЛОЖЕНИЯ — заготовка проекта «Сайт Axtoren»,
   редакция 7 от 23.08.2026

   Заменяет редакцию 6 того же дня целиком.

   ПРАВОК ДВЕ, А НЕ ОДНА. Редакция 6 перенесла опору наложения на сетку — и
   этого мало: наложенному ребёнку опорой служит его ЯЧЕЙКА, а ячейка у него
   должна быть назначена. Строчному девизу она назначена не была.

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

   Найдено проектом PlateCut Optimizer 23.08.2026.

   ПРИЧИНА У НАС. Назначение стояло в редакции 3 и было обронено при
   перестройке начала файла в редакции 5 — когда добавлялся раздел шапки.
   Второй случай в этой же заготовке: в редакции 2 так же выпало правило
   .ax-shell--busy. Перестройка куска теряет содержимое без следа.

   ГЛАВНАЯ ПРАВКА РЕДАКЦИИ 6: ОПОРА НАЛОЖЕНИЯ БЫЛА НЕ ТА.

   Редакции 3–5 ставили position: relative у рабочей области и пояснением
   утверждали, что это опора наложенному девизу. ОПОРОЙ ОНО НЕ БЫЛО: девиз
   рабочей области не потомок, а сосед по сетке — оба прямые дети .ax-shell,
   назначенные в одну ячейку. position: relative у соседа на наложенный
   элемент не влияет никак.

   Опорой оказывался начальный блок страницы, и девиз уходил в левый верхний
   угол окна, где его обрезала шапка сайта: «ВРЕМЯ ДОРОЖ…» и «ДЕ».

   Найдено проектом ProfileCut Optimizer 23.08.2026, выпуск 1.34.33.

   ИСПРАВЛЕНО: опора перенесена на .ax-shell. Наложенному ребёнку сетки опорой
   служит его ячейка, если позиционирована САМА СЕТКА. Столбец и строка девизу
   названы явно, потому ячейка у него ровно рабочая колонка.

   Правило у .ax-shell__work СНЯТО, а не оставлено. Правило, объявленное ради
   цели, которой не достигает, лжёт так же, как мёртвое умолчание.

   ЧТО ДОБАВЛЕНО В РЕДАКЦИИ 5: раздел «ШАПКА ПРИЛОЖЕНИЯ».

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

   До этой редакции наложение девиза опиралось на выравнивание названия по
   середине — и опиралось КАК НА ПРЕДПОЛОЖЕНИЕ. У PlateCut Optimizer название
   выровнено по левому краю, места слева не остаётся, и девиз ложился прямо
   под него. Найдено проектом PlateCut 23.08.2026.

   Теперь выравнивание задаётся здесь же и является УСЛОВИЕМ, а не догадкой.

   ГЛАВНАЯ ПРАВКА: ТРИ ПЕРЕМЕННЫЕ ПРИМЕНЯЛИСЬ И НИГДЕ НЕ ОБЪЯВЛЯЛИСЬ.

   Редакции 1–3 обращались к --ax-text, --ax-paper и --ax-accent (восемь мест).
   Объявлены же и в теме сайта, и в общем облике другие имена:
   --ax-color-text, --ax-color-surface, --ax-color-accent.

   Браузер на неизвестную переменную НЕ РУГАЕТСЯ — он молча отбрасывает
   свойство целиком. Отсюда: кнопка перехода без заливки, «дороже» без золота,
   черта под девизом не рисуется. Ни ошибки, ни следа в журнале.

   Найдено проектом PlateCut Optimizer 23.08.2026 и подтверждено сверкой
   применяемых имён с объявленными.

   ПРИЧИНА. Заготовка собиралась извлечением правил из листа ProfileCut. Взятые
   правила ссылались на короткие имена; в их листе они, по-видимому, объявлены,
   а в отданном куске — нет. Часть вырезана без проверки того, на что она
   опирается.

   ПРАВИЛО, ОТСЮДА СЛЕДУЮЩЕЕ: заготовка обязана либо объявлять всё, что
   применяет, либо применять только то, что объявлено в принимающем листе.
   Проверяется сверкой двух перечней, а не чтением.

   ЧТО ИЗМЕНИЛОСЬ ПРОТИВ РЕДАКЦИИ 2 — четыре правки, три из них по находкам
   приложений.

   1. ВОЗВРАЩЕНО правило .ax-shell--busy .ax-cross (найдено PlateCut).
      В редакции 2 оно пропало: собирая её из вашего листа, проект сайта взял
      выборку окном фиксированной длины, и правило в окно не попало. Отказ был
      бы беззвучным — признак ax-shell--busy приложение ставит по-прежнему, а
      правила, которым он пользуется, не стало бы.

   2. ДЕВИЗ СТАВИТСЯ НАЛОЖЕНИЕМ (найдено ProfileCut).
      Редакция 2 обещала пояснением «у левого края на высоте названия» и
      приводила замеры свободного места слева, а правилами ставила девиз в
      ОТДЕЛЬНУЮ строку сетки — то есть над названием, где никакого «слева» нет.
      Замеры относились к раскладке, которой в файле не было.
      Устройство взято у ProfileCut, доведено рубежом — см. ниже.

   3. КЕГЛИ ПОДНЯТЫ по распоряжению Правообладателя от 18.08.2026:
      всё, кроме заголовков, — на два; заголовки — на один.

   4. ВВЕДЁН РУБЕЖ НАЛОЖЕНИЯ 1100px. Ниже него девиз возвращается в свою
      строку: наложенный, он наезжает на название.
   ============================================================================ */


/* ----------------------------------------------------------------------------
   ШАПКА ПРИЛОЖЕНИЯ

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

   ЗАЧЕМ ЭТО ЗДЕСЬ, А НЕ У КАЖДОГО СВОЁ. Наложение девиза (см. ниже) держится
   на том, что название выровнено по середине и слева от него остаётся место.
   Пока выравнивание задавал каждый у себя, это было предположением заготовки —
   и у одного из приложений оно не выполнялось.

   ПРАВИЛО, ОТСЮДА СЛЕДУЮЩЕЕ: правило вёрстки, работающее при условии, обязано
   переноситься вместе с условием, а условие — задаваться, а не подразумеваться.

   СОСТАВ ШАПКИ — три строки, в этом порядке, и БОЛЬШЕ НИЧЕГО:

     .intro__title    название программы            «PlateCut Optimizer»
     .intro__version  номер редакции                «0.36»
     .intro__lead     назначение, одной строкой     «Раскрой листового металла»

   УСЛОВИЯ ОПЛАТЫ В ШАПКУ НЕ ВХОДЯТ. Решение Правообладателя от 23.08.2026.

   Строка вида «Расчёт бесплатно, платите за результат» говорит об условиях, а
   не о назначении, и место ей в теле страницы — там, где её держит ProfileCut
   Optimizer. Класса .intro__terms в общем облике нет и не заводится.

   Довод: указание «шапка одинакова, различаются название и назначение»
   называет два текста. Третий делает шапки разными — у одного приложения он
   есть, у другого нет.

   НОМЕР РЕДАКЦИИ СТОИТ ЗДЕСЬ, А НЕ В ШАПКЕ САЙТА.

   Фрагмент /shell/header/ номера не содержит и содержать не будет: шапка сайта
   одна на сайт и два приложения, а номер у каждого приложения свой. Вставлять
   его в полученную разметку значит править источник у себя — то самое, чего
   мы избегаем оболочкой.
   ---------------------------------------------------------------------------- */

.intro {
    text-align: center;
}

/*
 * Кегль заголовка поднят на ОДИН по распоряжению от 18.08.2026: заголовкам
 * полагается один, всему прочему два.
 */
.intro__title {
    margin: 0;
    font-weight: 400;
    font-size: clamp(27px, 4vw, 41px);
    letter-spacing: 0.015em;
    color: var(--ax-color-text);
}

.intro__version {
    margin: 4px 0 0;
    font-size: 15px;
    letter-spacing: 0.04em;
    color: rgba(39, 51, 65, 0.6);
}

/*
 * Назначение программы. К этому кеглю ОТНОСИТЕЛЬНО привязан строчный девиз —
 * см. раздел «ДЕВИЗ В СТРОКЕ». Меняя здесь, помните, что меняете и там.
 */
.intro__lead {
    margin: 4px 0 0;
    font-size: clamp(20px, 2.6vw, 28px);
    letter-spacing: 0.015em;
    color: var(--ax-color-text);
}


/* ----------------------------------------------------------------------------
   ОБОЛОЧКА
   ---------------------------------------------------------------------------- */

.ax-shell {
    --ax-side: 240px;
    --ax-gap: 32px;
    --ax-sides: calc(var(--ax-side) * 2 + var(--ax-gap) * 4);

    display: grid;
    grid-template-columns: var(--ax-side) minmax(0, 1fr) var(--ax-side);
    gap: var(--ax-gap);
    padding-inline: var(--ax-gap);
    max-width: 1920px;
    margin-inline: auto;

    /*
     * ОПОРА НАЛОЖЕННОГО ДЕВИЗА. Не декорация.
     *
     * Девиз — прямой ребёнок сетки, назначенный в ту же ячейку, что рабочая
     * область. Опорой наложению служит ближайший позиционированный предок;
     * у ребёнка сетки это САМА СЕТКА, а не сосед по ячейке.
     *
     * Убрать — и девиз отсчитается от начального блока страницы, то есть
     * уйдёт в левый верхний угол окна и обрежется шапкой сайта. Отказа при
     * этом не будет: страница цела, в разборе пусто.
     */
    position: relative;
}

/*
 * Столбец и строка названы КАЖДОМУ ребёнку явно.
 *
 * Прямых детей у оболочки четыре, а колонок три. Пока строчный девиз погашен,
 * раскладка сходится случайно — по порядку следования. Проверено опытом
 * 19.08.2026: стоило его показать, и он занял первую колонку, работа получила
 * ширину боковой полосы, а переход уехал на следующую строку. Ошибки при этом
 * никакой — страница цела.
 */
.ax-shell__side:has(.ax-motto) { grid-column: 1; grid-row: 1; }
.ax-shell__work                { grid-column: 2; grid-row: 1; }
.ax-shell__side:has(.ax-cross) { grid-column: 3; grid-row: 1; }

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

@media (max-width: 1687px) {
    .ax-shell > .ax-shell__motto-inline { grid-column: 1; grid-row: 1; }
}


/*
 * ЛИПКОСТЬ РАЗВЕДЕНА — указание Правообладателя от 23.08.2026: девиз
 * скрывается при прокрутке, кнопка перехода остаётся.
 *
 * Довод: блок перехода — единственный путь из сервиса в сервис, и терять его
 * при прокрутке нельзя. Девиз не открывает ничего, а висящая надпись у
 * длинной ведомости мешает.
 *
 * Внесено по представлению проекта PlateCut Optimizer от 23.08.2026, где
 * разведение уже сделано.
 */
.ax-shell__side { align-self: start; }

.ax-shell__side:has(.ax-motto) { position: static; }

.ax-shell__side:has(.ax-cross) {
    position: sticky;
    /* Отсчёт НИЖЕ ШАПКИ, а не от верха окна: шапка липкая и перекрывает
       собою верх страницы. Без поправки заголовок блока перехода срезался
       при прокрутке (замечание Правообладателя от 28.09.2026). */
    top: calc(var(--ax-header-height) + 24px);
}

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

.ax-shell__motto-inline { display: none; }


/* ----------------------------------------------------------------------------
   ПОРОГИ

   ДВА, а не один. Ни один не отменён.

       1687  уходит ОДНА колонка — левая, с девизом
       1321  уходят обе

   ЧИСЛО 1321 СЛОЖЕНО, А НЕ ПОДОБРАНО:

       1079  предел рабочей области
     +  170  одна боковая колонка
     +   24  промежуток
     + 2×24  поля оболочки
     ------
       1321      (в правиле стоит min-width: 1322 — начало, а не предел)

   ВНИМАНИЕ. Числа в медиазапросах НЕ МОГУТ быть переменными — правила
   медиазапросов переменных не понимают. Меняя --ax-side или --ax-gap,
   пересчитайте оба порога: переменные пересчитаются сами, а числа нет.

   ПОЧЕМУ УБИРАЕТСЯ ОДНА КОЛОНКА, А НЕ ОБЕ. У девиза запасной вид есть — он
   переезжает в строку. У блока перехода запасного вида нет никакого, а он
   единственный путь из одного сервиса в другой.

   Прежнее устройство оставляло без перехода области просмотра 1536, 1440 и
   1366 — самые ходовые. Экран 1920 при масштабе системы 125% даёт ровно 1536.
   ---------------------------------------------------------------------------- */

@media (max-width: 1687px) and (min-width: 1322px) {
    .ax-shell {
        --ax-side: 170px;
        --ax-gap: 24px;
        --ax-sides: calc(var(--ax-side) + var(--ax-gap) * 3);
        grid-template-columns: minmax(0, 1fr) var(--ax-side);
    }

    .ax-shell__side:has(.ax-motto) { display: none; }

    .ax-shell__work                { grid-column: 1; grid-row: 1; }
    .ax-shell__side:has(.ax-cross) { grid-column: 2; grid-row: 1; }
    .ax-shell__motto-inline        { display: block; }
}

@media (max-width: 1321px) {
    .ax-shell {
        grid-template-columns: minmax(0, 1fr);
        --ax-sides: 0px;
    }

    .ax-shell__side         { display: none; }
    .ax-shell__work         { grid-column: 1; grid-row: 1; }
    .ax-shell__motto-inline { display: block; }
}


/* ----------------------------------------------------------------------------
   ДЕВИЗ В КОЛОНКЕ

   Выделение размером и разрядкой, а не насыщенностью: у гарнитуры одно
   начертание, полужирного нет вовсе (usWeightClass 400, бит Bold снят).
   font-weight: bold браузер подделает утолщением контура, и на тонком
   чертёжном шрифте выйдет рыхло.

   КЕГЛЬ ЗДЕСЬ НЕ ПОДНЯТ. Распоряжение от 18.08 писано ради читаемости у
   станка; текст от 30px и выше в этом не нуждается, а поднятие сдвинуло бы
   «ДОРОЖЕ» к краю колонки 170px (132.4px при 46, 135.3px при 47).

   Просим Правообладателя подтвердить или поправить это толкование.
   ---------------------------------------------------------------------------- */

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

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

.ax-motto__line--accent {
    color: var(--ax-color-accent);
    letter-spacing: 0.08em;
}

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


/* ----------------------------------------------------------------------------
   ДЕВИЗ В СТРОКЕ

   ЦВЕТ: графит, не золото. Золото на ватмане даёт контраст 1.93 при норме 4.5
   для текста. Строка не просто выглядит иначе — она плохо читается, и хуже
   всего там, где этим пользуются. Графит даёт 11.16.

   КЕГЛЬ: тот же, что у подзаголовка приложения (.intro__lead).

   Требование ОТНОСИТЕЛЬНОЕ, а не числовое: подзаголовок изменится — девиз
   обязан измениться вместе с ним. Числа ниже приведены в предположении, что
   .intro__lead поднят на два по распоряжению от 18.08. Если у вас иначе —
   ставьте своё значение .intro__lead, а не эти числа.

   ПРОПИСНЫЕ И РАЗРЯДКА 0.16em СНЯТЫ вместе, а не порознь: вместе они давали
   вид отдельной надписи, спорящей с названием программы.
   ---------------------------------------------------------------------------- */

.ax-shell__motto-inline {
    margin: 0;
    font-size: clamp(20px, 2.6vw, 28px);   /* = .intro__lead */
    letter-spacing: 0.015em;
    line-height: 1.2;
    color: var(--ax-color-text);
    text-transform: none;
}


/* ----------------------------------------------------------------------------
   НАЛОЖЕНИЕ ДЕВИЗА НА ВЫСОТЕ НАЗВАНИЯ

   Устройство взято у ProfileCut Optimizer, редакция листа от 21.08.2026.

   Девиз ложится в ту же ячейку сетки, что рабочая область, и прижимается к её
   левому краю. Название программы выровнено по середине, поэтому слева от
   него остаётся место — туда девиз и встаёт.

   pointer-events: none ОБЯЗАТЕЛЕН. Без него наложенный блок перехватывает
   нажатия у названия — а такое находят пальцем, не глазом.

   РУБЕЖ 1100px. Ниже него наложение снимается, девиз возвращается в свою
   строку над рабочей областью.

   Число сложено по метрикам гарнитуры для самого длинного названия —
   «Онлайн-сервис ProfileCut Optimizer», 528px при кегле 41:

       ширина   рабочая   слева от названия   девиз   зазор
         1366      1124                 298     214      84
         1200      1136                 304     214      90
         1100      1036                 254     214      40
         1050       986                 229     209      20
         1000       936                 210     199      12

   Зазор падает ниже 24px при 1060. Рубеж 1100 взят с запасом.

   ЕСЛИ ПОЯВИТСЯ ПРИЛОЖЕНИЕ С БОЛЕЕ ДЛИННЫМ НАЗВАНИЕМ — рубеж пересчитать.
   Просьба проекта сайта: завести проверку, сверяющую, что при рубеже зазор
   между девизом и названием не меньше 24px. Без неё расхождение вернётся
   молча, как вернулось в редакции 2.
   ---------------------------------------------------------------------------- */

/* НАЛОЖЕНИЕ — ТОЛЬКО ТАМ, ГДЕ НАЗВАНИЕ ВЫРОВНЕНО ПО СЕРЕДИНЕ.
 *
 * Устройство рассчитано на страницу расчёта: название стоит по середине, и
 * слева от него пусто — туда девиз и встаёт. На странице библиотеки
 * содержимое прижато влево, и наложенный девиз лёг прямо на строку перехода
 * («Расчёт раскроя · Библиотека деталей») и на заголовок: замер 28.09.2026 —
 * девиз x=24, y=8; крошки x=24, y=14.
 *
 * Условие — наличие шапки приложения (`.intro`) в рабочей области: она и
 * есть то самое выровненное по середине название. Нет её — девиз остаётся в
 * потоке, своей строкой над содержимым, как ниже рубежа 1100.
 */
@media (min-width: 1100px) {
    .ax-shell:has(.intro) .ax-shell__motto-inline {
        position: absolute;
        left: 0;
        top: 8px;
        pointer-events: none;
    }
}

/* Девиз в потоке — СВОЕЙ СТРОКОЙ СЕТКИ, а не в одной ячейке с работой.
 *
 * Снять наложение мало: девиз назначен в ту же ячейку, что рабочая область
 * (`grid-column: 1; grid-row: 1`), и, оставшись в потоке, он растянулся бы на
 * всю её высоту и всё равно лёг бы поверх. Ему отводится первая строка,
 * работе — вторая, а боковым блокам — обе. */
.ax-shell:not(:has(.intro)) {
    grid-template-rows: auto minmax(0, 1fr);
}
.ax-shell:not(:has(.intro)) > .ax-shell__motto-inline {
    grid-row: 1;
    margin-bottom: 12px;
}
.ax-shell:not(:has(.intro)) > .ax-shell__work { grid-row: 2; }
.ax-shell:not(:has(.intro)) > .ax-shell__side { grid-row: 1 / span 2; }


/* ----------------------------------------------------------------------------
   БЛОК ПЕРЕХОДА В СОСЕДНИЙ СЕРВИС

   КЕГЛИ ПОДНЯТЫ на два по распоряжению Правообладателя от 18.08.2026 —
   программой пользуются у станка, где до экрана дальше, а свет хуже.
   Заголовок блока поднят на один: заголовкам полагается один, а не два.
   ---------------------------------------------------------------------------- */

.ax-cross { padding: 22px 20px; }

.ax-cross__label {
    margin: 0 0 10px;
    font-size: 15px;                 /* было 13, +2 */
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(39, 51, 65, 0.6);
}

.ax-cross__title {
    margin: 0 0 10px;
    font-size: 22px;                 /* было 21, +1 как заголовку */
    line-height: 1.3;
}

.ax-cross__note {
    margin: 0 0 18px;
    font-size: 17px;                 /* было 15, +2 */
    line-height: 1.5;
    color: rgba(39, 51, 65, 0.78);
}

/*
 * Кнопка перехода ГРАФИТОВАЯ, а не золотая.
 *
 * Золотая на экране одна — та, что запускает оплачиваемую работу. Переход в
 * соседний сервис работы не запускает.
 *
 * Правило проверяемое: сосчитать золотые кнопки на отданной странице; больше
 * одной — нарушение.
 */
.ax-cross__link {
    display: inline-block;
    padding: 10px 18px;
    font-size: 17px;                 /* было 15, +2 */
    color: var(--ax-color-surface);
    background: var(--ax-color-text);
    border-radius: 3px;
    text-decoration: none;
    transition: background 0.15s ease;
}

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

@media (prefers-reduced-motion: reduce) {
    .ax-cross__link { transition: none; }
}


/* ----------------------------------------------------------------------------
   СКРЫТИЕ БЛОКА ПЕРЕХОДА НА ВРЕМЯ СЧЁТА

   ВОЗВРАЩЕНО В РЕДАКЦИИ 3. В редакции 2 правило пропало по недосмотру проекта
   сайта, и пропажу нашёл PlateCut Optimizer.

   Довод прежний: при долгом ожидании предложение уйти в другое приложение
   читается как приглашение бросить начатое.

   Признак ax-shell--busy ставит приложение при отправке задания и снимает по
   ответу. ПРОВЕРЯТЬ надо не только наличие этого правила, но и то, что
   признак снимается на ВСЕХ путях — включая отказ, обрыв и истечение времени.
   Иначе блок останется скрытым до перезагрузки страницы.
   ---------------------------------------------------------------------------- */

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


/* ----------------------------------------------------------------------------
   ПЕРЕКРЁСТНОЕ ПЕРЕКЛЮЧЕНИЕ

   Оба варианта лежат в разметке, показывается один — ведущий к соседу.
   Признак стороны задаёт приложение: data-ax-service="profile" или "sheet".

   ОБА СКРЫТЫ ПО УМОЛЧАНИЮ, показывается встречный. Способ выбран не по вкусу:
   при потерянном или описанном признаке прежнее устройство показывало ОБА
   блока, включая ведущий на самого себя. Посетитель нажимает «второй сервис»,
   попадает на ту же страницу и решает, что программа сломана.

   Показывать ссылку на самого себя хуже, чем не показывать ничего.

   Имена классов говорят о НАПРАВЛЕНИИ, а не о принадлежности.
   ---------------------------------------------------------------------------- */

.ax-cross--to-sheet,
.ax-cross--to-profile { display: none; }

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

/* ==== ИЗ ОБРАЗЦА, строки 778–914 ====
   Шапка и подвал сайта. Разметку отдаёт сам сайт (`/shell/header/`,
   `/shell/footer/`), правила — отсюда. Перенесены 20.08.2026, когда
   разметка пришла: до того оформлять было нечего. */

/* ═══════════════════════════════════════════════════════════════════════
   ШАПКА И ПОДВАЛ САЙТА
   Разметка и размеры взяты у темы 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 {
    font-size: 14px; letter-spacing: .06em;
    color: var(--ax-color-text-muted); white-space: nowrap;
}
.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: var(--ax-header-height); }

#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;
}

