/*
 * Стили внутренних страниц сайта: блог, новости, статья.
 *
 * ⚠️ Ни одного внешнего шрифта и ни одной чужой библиотеки — как и на главной.
 * Сайт открывают с телефона, часто в машине, и каждый лишний запрос это
 * ушедший человек.
 *
 * ⚠️ Вид шапки должен совпадать с главной до мелочей. Разъехавшиеся отступы и
 * другой оттенок синего читаются как «меня перекинуло на чужой сайт».
 */

:root {
    --ink: #0B1220;
    --dim: #4E5768;
    --line: #E6E9F0;
    --bg: #F6F7FB;
    --card: #FFFFFF;
    /*
     * ⚠️ Синий — производная от синего на знаке (#00A6FF), затемнённая до
     * читаемости: 6,96 на белом при норме 4,5. Сам цвет знака в тексте даёт
     * 2,66 и не годится ни буквами, ни заливкой под белые буквы.
     */
    --blue: #0B5E90;
    /*
     * ⛔ Синяя ПЛАШКА и текст на ней — отдельные цвета, не тот же --blue.
     *
     * --blue это цвет ссылки, и в тёмной теме он светлеет до #6EC6FF. Девять
     * мест брали его фоном под белый текст, и в темноте их было не прочесть:
     * контраст 1,88 при нужных 4,5. Одно из девяти однажды починили отдельной
     * заплатой — остальные восемь остались.
     */
    --blue-fill: #0B5E90;
    --on-blue: #fff;
    --blue2: #0E76B3;
    --soft: #EAF4FB;
    /*
     * Цвета знака — ТОЛЬКО для фигур: полоски, значки, рамка выбора. Текстом
     * их брать нельзя (2,28–2,66 на белом), и это не вкусовщина, а замер.
     */
    --brand-orange: #FF7A00;
    --brand-blue: #00A6FF;
    --brand-green: #00C721;
    /* Оранжевый, пригодный для букв: 5,94 на белом. */
    --brand-ink: #A34A00;
    /* ⚠️ Тёмнее, чем «красиво»: прежние #0E9F6E и #B45309 не добирали
       контраста на светлых подложках — зелёный давал 3.02:1 на --soft и
       3.39:1 на белом при норме 4.5. Этим зелёным был набран ответ «Скорее
       да» на /cars/ — то самое слово, ради которого страницу открывают.
       Lighthouse его не показывал: без года ответ скрыт, и проверка видела
       только исходное состояние страницы. */
    --good: #0A6B4A;
    --warn: #8A3F07;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    /*
     * ⚠️ hidden объявлен ПЕРВЫМ как запасной путь для старых браузеров, а
     * clip — вторым и побеждает там, где его понимают.
     *
     * Разница не косметическая: hidden делает body прокручиваемым ящиком, и
     * position:sticky у шапки начинает считаться относительно НЕГО — то есть
     * шапка уезжает вверх при прокрутке. clip обрезает так же, но ящика не
     * создаёт. Шапка была объявлена липкой и не липла именно из-за этой
     * строки.
     */
    overflow-x: hidden;
    overflow-x: clip;
    font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; }

.wrap { width: min(1120px, calc(100% - 40px)); margin: 0 auto; }

/*
 * ⚠️ Скрытое должно быть скрыто.
 *
 * Браузер прячет [hidden] правилом display:none, но у него та же
 * специфичность, что у обычного класса, — и любой наш `.codeitem{display:flex}`
 * его перебивает. Поиск по кодам и датчикам исправно проставлял hidden и
 * честно считал совпадения («4 / 155»), а список при этом оставался полным:
 * человек вводил запрос и видел, что ничего не изменилось.
 *
 * ⚠️ Проверка этого не поймала, потому что считала строки по атрибуту —
 * то есть спрашивала разметку, а не смотрела глазами. Теперь она меряет
 * настоящую видимость.
 */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------- шапка */

.top {
    position: sticky;
    top: 0;
    z-index: 40;
    /* ⚠️ Сплошной фон, а не полупрозрачный: сквозь размытие просвечивал
       контент и шапка выглядела грязной. */
    background: var(--card);
    border-bottom: 1px solid var(--line);
}
.top .wrap { display: flex; align-items: center; gap: 18px; height: 62px; }

.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 19px;
    letter-spacing: -.02em;
    color: var(--ink);
}
.brand:hover { text-decoration: none; }
/* ⚠️ Имя — один элемент. Полоса с gap разносит КАЖДЫЙ узел внутри себя, и
   «Car» со «Scan» разъезжались на восемь точек: получалось «Car Scan». */
.brand .name { font-weight: 700; letter-spacing: -.02em; }
.brand .name span { color: var(--blue); }

/* Знак Смайла тихо поворачивается — «живой» логотип без гифки. */
.mark { animation: spin 9s linear infinite; transform-origin: 50% 50%; }
@keyframes spin { to { transform: rotate(360deg); } }

.top nav { margin-left: auto; display: flex; align-items: center; gap: 22px; }

/*
 * ⚠️ Значок пункта меню оформляем ЗДЕСЬ, а не только внутри мобильного
 * медиа-запроса. Без этих строк на широком экране SVG показывался в свой
 * полный рост и чёрной заливкой: шапка превращалась в ряд огромных чёрных
 * фигур. Правило вида, заданное только под телефон, ломает всё остальное.
 *
 * На широком экране значки не нужны: пункты стоят в строку, и картинки рядом
 * с ними только теснят текст.
 */
/*
 * ⛔ Все органы управления наследуют шрифт страницы.
 *
 * Браузер даёт кнопке, полю и списку СВОЙ шрифт — Arial, — и класс, написанный
 * под конкретный вид, об этом не знает. Так было у .btn (замер показал Arial и
 * рамку 2px outset black), а после его починки проверка нашла ещё три: кнопку
 * микрофона, кнопку поиска в шапке и стрелки карусели. Чинить по классам
 * бессмысленно: следующая новая кнопка придёт с тем же Arial.
 *
 * ⚠️ Наследуем только СЕМЕЙСТВО, а не font целиком: font: inherit сбросил бы и
 * размер, а у кнопок со значком вместо текста своего размера нет — они
 * получили бы размер окружающего текста и раздулись.
 */
button, select, textarea, input, optgroup {
    font-family: inherit;
}

.mi {
    display: none; width: 22px; height: 22px; flex: none;
    fill: none; stroke: var(--blue); stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}

/*
 * Значок прочерчивается, когда появляется.
 *
 * ⛔ Свойства пунктира живут ТОЛЬКО в кадрах анимации. Поставь их в обычное
 * правило .mi path — и любой сбой (анимация не запустилась, браузер не понял,
 * стиль пришёл без keyframes) оставил бы человека с пустыми значками. Худший
 * случай теперь — значок не прочерчен, а не исчез.
 *
 * ⚠️ Длина контура нормирована в разметке: pathLength="1" у самого пути. Иначе
 * пришлось бы подбирать stroke-dasharray каждому из двадцати двух рисунков.
 */
@keyframes midraw {
    from { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: .3; }
    to   { stroke-dasharray: 1; stroke-dashoffset: 0; opacity: 1; }
}

/* Наведение на пункт: контур чуть плотнее и значок делает шаг к тексту. */
.top nav .gdrop .lnk .mi,
.me .mi {
    transition: transform .14s cubic-bezier(.2, .7, .3, 1), stroke-width .14s;
}
.top nav .gdrop .lnk:hover .mi {
    transform: translateX(2px); stroke-width: 2.1;
}

/*
 * ⚠️ Переключатель языка в разметке идёт первым — так он оказывается сверху
 * в мобильной панели, где его и ищут. На широком экране его место справа,
 * после пунктов: слева от меню он читается как первый раздел сайта.
 */
.navtop { order: 2; margin-left: 18px; }

/*
 * Поиск в шапке.
 *
 * ⚠️ На широком экране поле узкое и расширяется при наборе: меню и так плотное,
 * и постоянное широкое поле вытеснило бы разделы на вторую строку — беда, из-за
 * которой мы уже поднимали порог мобильного меню.
 */
.navfind { order: 1; display: flex; align-items: center; gap: 4px; margin-left: 8px; }
.navfind input {
    width: 132px; font: inherit; font-size: 14px; color: var(--ink);
    background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
    padding: 7px 12px; outline: none;
    transition: width .2s cubic-bezier(.2, .7, .3, 1), border-color .2s, box-shadow .2s;
}
.navfind input:focus {
    width: 210px; border-color: var(--blue2);
    box-shadow: 0 0 0 3px rgba(76, 111, 216, .12);
}
.navfind button {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0; border: 0; border-radius: 999px;
    background: none; color: var(--dim); cursor: pointer;
}
.navfind button:hover { color: var(--blue); background: var(--soft); }
.navfind .mi { display: block; width: 18px; height: 18px; }

/*
 * Группы меню с выпадающими списками — на широком экране.
 *
 * ⚠️ Раскрываются наведением И фокусом (:focus-within). Только наведение
 * означает, что с клавиатуры до списка не добраться вовсе, а Tab по сайту —
 * это не редкость, а единственный способ у части людей.
 */
.grp { position: relative; order: 1; }
.gtop {
    display: inline-flex; align-items: center; gap: 5px;
    color: var(--dim); font-size: 15px; user-select: none;
    padding: 6px 0;
    /*
     * ⛔ Рука, а не обычный курсор. Сперва я нарочно оставил default — «это
     * полка, а не страница». Но наведение РАСКРЫВАЕТ список, то есть действие
     * есть, и обычный курсор о нём врёт. Указатель обещает не переход, а
     * действие — здесь оно и происходит.
     */
    cursor: pointer;
    /*
     * ⚠️ Сброс кнопочных умолчаний. Заголовок группы стал <button>, чтобы
     * список раскрывался и с клавиатуры, — а браузер даёт кнопке свой шрифт,
     * фон, рамку и внутренние отступы, и без сброса шапка разъезжается.
     * Сброс стоит ЗДЕСЬ, рядом с правилом, а не в общем начале файла: здесь
     * его и будут искать, если однажды заголовок снова изменится.
     */
    background: none; border: 0; margin: 0; font: inherit; font-size: 15px;
    text-align: left;
}
/* ⚠️ Видимый след фокуса обязателен: человек, идущий клавишами, должен видеть,
   где он стоит. Стандартный след браузер убирает вместе со сбросом. */
.gtop:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 8px; }
.grp:hover .gtop, .grp:focus-within .gtop { color: var(--ink); }
/*
 * ⚠️ Группа, внутри которой открытый раздел, выделяется вместе с ним. Без
 * этого человек на странице кодов видел в шапке «Справочники» обычным серым
 * и не понимал, где находится: подсветка была спрятана внутри закрытого
 * списка. Работает без JavaScript — :has() поддерживают все нынешние браузеры,
 * а там, где нет, просто не будет подсветки: содержимое от этого не страдает.
 */
.grp:has(.lnk.on) .gtop { color: var(--ink); font-weight: 600; }
.gtop .chev {
    width: 14px; height: 14px; fill: none; stroke: currentColor;
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
    transition: transform .18s;
}
.grp:hover .gtop .chev, .grp:focus-within .gtop .chev { transform: rotate(180deg); }
.gdrop {
    position: absolute; top: 100%; left: -14px; z-index: 80;
    min-width: 208px; padding: 6px; margin-top: 6px;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 18px 44px rgba(16, 26, 51, .14);
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: opacity .16s, transform .16s, visibility .16s;
}
.grp:hover .gdrop, .grp:focus-within .gdrop {
    opacity: 1; visibility: visible; transform: none;
}
/*
 * ⚠️ Мостик над списком: между заголовком и выпавшим списком есть зазор в
 * 6 точек, и курсор, идущий вниз, успевал его пересечь — список закрывался
 * прямо под рукой. Невидимая полоса держит наведение.
 */
.gdrop::before {
    content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px;
}
.top nav .gdrop .lnk {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: 10px; color: var(--ink); font-size: 15px;
}
.top nav .gdrop .lnk:hover { background: var(--soft); text-decoration: none; }
.top nav .gdrop .lnk.on { font-weight: 600; }
/* В выпавшем списке значок уместен: он помогает найти строку взглядом. */
.top nav .gdrop .mi { display: block; width: 18px; height: 18px; }
/*
 * ⚠️ Прочерчиваем по очереди, а не все разом: одновременное движение шести
 * значков читается как рябь, а по очереди — как список, который раскрывается.
 * Шаг мелкий (35 мс): при большем последний значок доедет, когда человек уже
 * выбрал первый.
 */
.grp:hover .gdrop .mi path,
.grp:focus-within .gdrop .mi path {
    animation: midraw .42s cubic-bezier(.3, .8, .3, 1) backwards;
    animation-delay: calc(var(--i, 0) * .035s + .04s);
}

/*
 * Кабинет и Telegram стоят особняком от разделов сайта: показываем их значком
 * со скрытой подписью, чтобы взгляд отделял их от «Блога» и «Датчиков».
 *
 * ⚠️ Подпись не удаляем, а прячем визуально: удалённую читалка экрана не
 * прочтёт, и ссылка останется для незрячего человека безымянной.
 */
.top nav a.lnk.solo { order: 1; gap: 0; }
.top nav a.lnk.solo .mi { display: block; }
.top nav a.lnk.solo span {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Вошедший: имя и список разделов. */
.me {
    order: 1; display: flex; align-items: center; gap: 7px; cursor: pointer;
    padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px;
    background: var(--card); font-size: 14px; color: var(--ink);
    /* ⚠️ Кнопка не тянется и не переносится: длинное имя распирало шапку, и
       разделы сайта переносились на вторую строку. */
    flex: none; max-width: 170px; white-space: nowrap;
}
.me > span { overflow: hidden; text-overflow: ellipsis; }
.me .mi { display: block; width: 18px; height: 18px; }
.me .chev {
    width: 14px; height: 14px; fill: none; stroke: var(--dim);
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
    transition: transform .18s;
}
#metoggle:checked ~ .me .chev { transform: rotate(180deg); }
/* Обёртка задаёт точку отсчёта: список висит под кнопкой, а не у края шапки. */
.mebox { order: 1; position: relative; display: flex; align-items: center; }
.medrop {
    display: none; position: absolute; top: calc(100% + 8px); right: 0; z-index: 80;
    min-width: 200px; padding: 6px; background: var(--card);
    border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 18px 44px rgba(16, 26, 51, .14);
}
#metoggle:checked ~ .medrop { display: block; }
.medrop a {
    display: block; padding: 10px 12px; border-radius: 10px;
    color: var(--ink); font-size: 15px;
}
.medrop a:hover { background: var(--soft); text-decoration: none; }
/* ⚠️ Выход отделён чертой: нажать его случайно вместо «Поддержки» — значит
   потерять место, на котором человек остановился. */
.medrop a.out { border-top: 1px solid var(--line); border-radius: 0 0 10px 10px; color: var(--warn); }
.top nav .lnk { order: 1; }
/* ⚠️ Подпись пункта не разрывается посреди: «Что умеет» вставало в две
   строки и раздувало шапку вдвое. Лучше показать бутерброд, чем ломать
   слова. */
.lnk { color: var(--dim); font-size: 15px; white-space: nowrap; }
.lnk:hover, .lnk.on { color: var(--ink); text-decoration: none; }
.lnk.on { font-weight: 600; }

.langs { display: flex; gap: 4px; align-items: center; }
.langs a {
    display: flex; align-items: center; gap: 5px;
    padding: 4px 8px; border-radius: 999px;
    font-size: 12px; font-weight: 600; color: var(--dim);
    border: 1px solid transparent;
}
.langs a.on { background: var(--card); border-color: var(--line); color: var(--ink); }
.langs a:hover { text-decoration: none; }
.langs svg { border-radius: 2px; display: block; }

.burger { display: none; }

/* ------------------------------------------------------------- крошки */

.crumbs {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 18px 0 0; font-size: 13px; color: var(--dim);
}
.crumbs a { color: var(--dim); }
.crumbs a:hover { color: var(--ink); }
.crumbs i { font-style: normal; opacity: .5; }
.crumbs span { color: var(--ink); }

/* ------------------------------------------------------------ страница */

.page { padding: 26px 0 70px; }
.page h1 {
    font-size: clamp(30px, 4.4vw, 46px);
    line-height: 1.1;
    letter-spacing: -.03em;
    margin: 14px 0 10px;
}
.lead { color: var(--dim); font-size: 18px; max-width: 720px; margin: 0 0 6px; }
.meta { color: var(--dim); font-size: 13px; display: flex; gap: 14px; flex-wrap: wrap; }
.meta b { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------- список записей */

.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 26px; }
/*
 * ⛔ Отступ у карточки задан ЗДЕСЬ, а не на каждой странице отдельно.
 *
 * Беда, которую владелец показал дважды 08.09.2026: текст стоял в одном
 * пикселе от рамки. Причина — один класс значил РАЗНОЕ: в home.css у .card
 * отступ 26 пт, а здесь, для всего остального сайта, никакого. На главной
 * всё выглядело правильно, а на страницах VIN, машин и разбора кодов текст
 * лежал на рамке. Обход tools/check_padding.mjs нашёл девять таких видов.
 *
 * ⚠️ Исключение ровно одно и названо: карточка с обложкой во всю ширину
 * (.card.flush). Там картинка обязана доходить до края, а отступ текста даёт
 * внутренний .cbody.
 */
.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 18px;
    overflow: hidden;
    padding: 20px 22px;
    display: flex;
    flex-direction: column;
    transition: transform .25s cubic-bezier(.2, .7, .3, 1), box-shadow .25s;
}
.card.flush { padding: 0; }
/* ⚠️ Первый и последний ребёнок теряют внешние отступы: иначе к отступу
   карточки прибавляется margin заголовка сверху и списка снизу, и симметрия
   рассыпается — под ответом зияло тридцать семь точек при двадцати сверху. */
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }
@media (max-width: 700px) {
    .card { padding: 16px; }
}
.card:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(16, 26, 51, .09); }
.card a { color: inherit; }
.card a:hover { text-decoration: none; }
.cover {
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, var(--soft), #DCE6FA);
    display: flex; align-items: center; justify-content: center;
}
.cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover .mark { animation: none; opacity: .55; }
.cbody { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.ctitle { font-weight: 650; font-size: 17px; letter-spacing: -.01em; line-height: 1.35; }
.cdescr { color: var(--dim); font-size: 14px; flex: 1; }
.cfoot { color: var(--dim); font-size: 12px; display: flex; gap: 12px; align-items: center; }

.tag {
    display: inline-block; padding: 2px 9px; border-radius: 999px;
    background: var(--soft); color: var(--blue); font-size: 12px; font-weight: 600;
}

.empty {
    margin-top: 30px; padding: 40px 24px; text-align: center;
    background: var(--card); border: 1px solid var(--line); border-radius: 18px; color: var(--dim);
}

/* ------------------------------------------------------------- статья */

.article { max-width: 760px; }
.article h2 { font-size: 26px; letter-spacing: -.02em; margin: 34px 0 10px; }
.article h3 { font-size: 20px; letter-spacing: -.01em; margin: 26px 0 8px; }
.article p { margin: 0 0 16px; }
.article ul, .article ol { margin: 0 0 16px; padding-left: 22px; }
.article li { margin: 6px 0; }
.article code {
    background: var(--soft); border-radius: 6px; padding: 1px 6px;
    font: 14px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.article blockquote {
    margin: 20px 0; padding: 12px 18px;
    border-left: 3px solid var(--blue2); background: var(--card); border-radius: 0 12px 12px 0;
    color: var(--dim);
}
.article .warn {
    margin: 20px 0; padding: 14px 18px;
    background: #FFF7ED; border: 1px solid #FDE1C0; border-radius: 14px; color: var(--warn);
}
.article figure { margin: 24px 0; }
.article figure img { border-radius: 16px; border: 1px solid var(--line); display: block; }
.article figcaption { color: var(--dim); font-size: 13px; margin-top: 8px; text-align: center; }

.hero-cover {
    margin: 22px 0 8px; border-radius: 22px; overflow: hidden;
    border: 1px solid var(--line); background: var(--card);
}
/* ⚠️ Соотношение сторон держит место под картинку с первой отрисовки —
   даже если атрибуты размеров когда-нибудь потеряются при правке. */
.hero-cover img { width: 100%; height: auto; aspect-ratio: 16 / 9; display: block; }

/* Полоса прочитанного — видно, сколько осталось. */
.progress {
    position: fixed; top: 0; left: 0; height: 3px; width: 0;
    background: linear-gradient(90deg, var(--blue2), var(--good));
    z-index: 60; transition: width .1s linear;
}

/* --------------------------------------------------------- дальше читать */

.next { margin-top: 60px; padding-top: 34px; border-top: 1px solid var(--line); }
.next h2 { font-size: 22px; margin: 0 0 18px; }

.pager { display: flex; gap: 10px; justify-content: center; margin-top: 34px; }
.pager a, .pager span {
    min-width: 38px; text-align: center; padding: 7px 12px; border-radius: 10px;
    border: 1px solid var(--line); background: var(--card); color: var(--dim); font-size: 14px;
}
.pager .on { border-color: var(--blue2); color: var(--ink); font-weight: 600; }
.pager a:hover { text-decoration: none; color: var(--ink); }

/* ------------------------------------------------------------- подвал */

footer { border-top: 1px solid var(--line); padding: 26px 0 40px; color: var(--dim); font-size: 14px; }
.frow { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
footer a { color: var(--dim); }
footer a:hover { color: var(--ink); }
.auto { margin-left: auto; }

/* -------------------------------------------------------- появление */

/* ⚠️ Без прозрачности: полупрозрачный текст в середине анимации теряет
   контраст и доли секунды нечитаем. Движения достаточно. */
.reveal { transform: translateY(14px); transition: transform .6s cubic-bezier(.2, .7, .3, 1); }
.reveal.in { transform: none; }

/* ---------------------------------------------------------- телефон */

@media (max-width: 900px) {
    .cards { grid-template-columns: repeat(2, 1fr); }
}

/* Карточки в один столбец — только на телефоне. */
@media (max-width: 700px) { .cards { grid-template-columns: 1fr; } }

/*
 * ⚠️ Меню прячется под кнопку уже с 900 точек, а не с 700. На планшете
 * (768) девять пунктов в строку не помещались и переносились на вторую
 * строку: шапка распухала вдвое, а пункты рвались посередине слова.
 */
@media (max-width: 1120px) {

    /*
     * ⚠️ Размытие подложки снимаем именно на телефоне. backdrop-filter делает
     * шапку системой координат для всего, что внутри неё закреплено намертво:
     * выезжающая панель получала высоту шапки, а не экрана, и показывала
     * первый пункт наполовину, обрезав остальные.
     */
    .top { backdrop-filter: none; background: var(--card); }

    /*
     * Кнопка меню. Полоски считаем от центра (top: 50%), а не подбираем
     * числами: при подборе они разъезжаются, стоит поменять размер кнопки —
     * и значок выглядит сломанным, а не нарисованным.
     */
    .burger {
        display: flex; margin-left: auto; width: 40px; height: 40px;
        border: 1px solid var(--line); border-radius: 12px; background: var(--card);
        position: relative; cursor: pointer; flex: none;
    }
    .burger i, .burger i::before, .burger i::after {
        position: absolute; left: 50%; top: 50%; width: 18px; height: 2px;
        margin-left: -9px; background: var(--ink); border-radius: 2px; content: "";
        transition: transform .22s cubic-bezier(.2, .7, .3, 1), background-color .15s;
    }
    .burger i::before { top: -6px; margin-left: 0; left: 0; }
    .burger i::after { top: 6px; margin-left: 0; left: 0; }
    /* Открытое меню: три полоски складываются в крестик. */
    #navtoggle:checked ~ .burger i { background: transparent; }
    #navtoggle:checked ~ .burger i::before { transform: translateY(6px) rotate(45deg); }
    #navtoggle:checked ~ .burger i::after { transform: translateY(-6px) rotate(-45deg); }

    /* Затемнение: по нему закрывают меню касанием мимо панели. */
    .navshade {
        position: fixed; inset: 0; background: rgba(11, 18, 32, .34);
        opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 60;
    }
    #navtoggle:checked ~ .navshade { opacity: 1; pointer-events: auto; }

    /*
     * ⚠️ Панель выезжает сбоку — так же, как на главной. Раньше здесь было
     * выпадающее меню под шапкой, и человек видел на одном сайте два разных
     * меню, смотря на какую страницу зашёл.
     *
     * ⚠️ Закрытие быстрее открытия (.2 против .28): при закрытии человек уже
     * знает, чего хочет, и ждать анимацию ему незачем.
     */
    .top nav {
        position: fixed; top: 0; right: 0; height: 100vh;
        width: min(320px, 86vw); display: flex;
        flex-direction: column; align-items: stretch; gap: 2px;
        padding: 18px 20px 28px; background: var(--card);
        border-left: 1px solid var(--line); box-shadow: -24px 0 60px rgba(16, 26, 51, .14);
        transform: translateX(100%); visibility: hidden; z-index: 70;
        overflow-y: auto; -webkit-overflow-scrolling: touch;
        transition: transform .2s cubic-bezier(.4, 0, 1, 1), visibility .2s;
    }
    #navtoggle:checked ~ nav {
        transform: none; visibility: visible;
        transition: transform .28s cubic-bezier(.2, .7, .3, 1), visibility 0s;
    }
    /* ⚠️ Спрятанная за краем панель расширяла бы страницу на свою ширину.
       clip вместо hidden — hidden ломает липкую шапку (см. body выше). */
    html { overflow-x: hidden; overflow-x: clip; }

    /* ⚠️ В выехавшей панели прятать подписи незачем: места хватает, а
       значок без слова человек читает дольше, чем слово со значком. */
    .top nav a.lnk.solo { gap: 12px; }
    .top nav a.lnk.solo span {
        position: static; width: auto; height: auto; margin: 0;
        overflow: visible; clip: auto;
    }
    /*
     * ⚠️ Порядок в панели: язык, затем имя со своим списком, и только потом
     * разделы сайта. Без явного порядка список кабинета вставал ВЫШЕ пунктов
     * сайта — человек открывал меню и первым делом видел «Выйти».
     */
    .mebox { order: -1; display: block; width: 100%; position: static; }
    .me { margin: 0 0 8px; border-radius: 12px; justify-content: flex-start;
          max-width: none; width: 100%; }
    .medrop { order: -1; position: static; box-shadow: none; border: 0;
              padding: 0 0 8px; min-width: 0; margin-bottom: 4px;
              border-bottom: 1px solid var(--line); }
    .medrop a { padding: 12px 6px; border-bottom: 1px solid var(--line); border-radius: 0; }
    /*
     * ⚠️ На телефоне выпадающих списков нет: панель и так во всю высоту,
     * прятать нечего. Заголовок группы становится подписью раздела, а её
     * пункты видны сразу — иначе до «Датчиков» пришлось бы делать два
     * касания вместо одного.
     */
    .grp { position: static; display: block; width: 100%; }
    .gtop {
        display: block; padding: 14px 6px 6px; font-size: 13px;
        text-transform: uppercase; letter-spacing: .04em; color: var(--dim);
    }
    .gtop .chev { display: none; }
    .gdrop {
        position: static; opacity: 1; visibility: visible; transform: none;
        min-width: 0; padding: 0; margin: 0; border: 0; box-shadow: none;
        background: none; transition: none;
    }
    .gdrop::before { display: none; }
    .top nav .gdrop .lnk {
        padding: 13px 6px; font-size: 17px; border-radius: 0;
        border-bottom: 1px solid var(--line);
    }
    /* ⚠️ На телефоне поле во всю ширину и сразу под языком: в панели место
       есть, а искать с телефона хотят чаще, чем с монитора. */
    .navfind { order: -1; margin: 0 0 10px; width: 100%; }
    .navfind input { width: 100%; font-size: 16px; padding: 12px 14px; }
    .navfind input:focus { width: 100%; }
    .navtop { order: -2; margin-left: 0; padding: 4px 0 12px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }
    .navtop .langs { margin: 0; justify-content: flex-start; }

    .top nav a.lnk {
        display: flex; align-items: center; gap: 12px;
        padding: 13px 6px; font-size: 17px; color: var(--ink);
        border-bottom: 1px solid var(--line);
    }
    .top nav a.lnk:last-child { border-bottom: 0; }
    .top nav a.lnk.on { font-weight: 600; }
    .top nav a.lnk.tg { color: var(--blue); margin-top: 6px; }

    /*
     * Значок: контур прочерчивается, когда пункт въезжает.
     *
     * ⚠️ Этот комментарий стоял здесь и раньше, а прочерчивания не было —
     * въезжала только строка. Комментарий, обещающий несделанное, хуже
     * отсутствующего: по нему потом судят, что тут уже разобрались.
     */
    .mi { display: block; }
    #navtoggle:checked ~ nav a.lnk {
        animation: navin .26s cubic-bezier(.2, .7, .3, 1) backwards;
        animation-delay: calc(var(--i, 0) * .035s + .06s);
    }
    #navtoggle:checked ~ nav a.lnk .mi path {
        /* На четверть дольше строки: контур должен доехать вместе с ней, а не
           закончиться раньше — иначе движение выглядит рваным. */
        animation: midraw .34s cubic-bezier(.3, .8, .3, 1) backwards;
        animation-delay: calc(var(--i, 0) * .035s + .1s);
    }
    @keyframes navin {
        from { opacity: 0; transform: translateX(14px); }
    }
}

@media (prefers-reduced-motion: reduce) {
    .reveal { transform: none; }
    .mark { animation: none !important; }
    html { scroll-behavior: auto; }
    /* Меню: показываем сразу, без въезда пунктов и плавного выезда панели. */
    #navtoggle:checked ~ nav a.lnk { animation: none; }
    /*
     * ⛔ И значки — целыми, а не прочерчивающимися. Просто «animation: none»
     * здесь достаточно именно потому, что пунктир задан ТОЛЬКО в кадрах:
     * отменяя анимацию, мы возвращаем целый контур, а не пустоту.
     */
    #navtoggle:checked ~ nav a.lnk .mi path,
    .grp:hover .gdrop .mi path,
    .grp:focus-within .gdrop .mi path,
    .lamphead .lampicon path,
    .symhead .symico path { animation: none; }
    .top nav .gdrop .lnk .mi, .me .mi { transition: none; }
    .top nav .gdrop .lnk:hover .mi { transform: none; }
    .top nav, .navshade, .burger i, .burger i::before, .burger i::after { transition: none; }
}

/* ------------------------------------------------- справочник кодов */

.codesearch { display: flex; align-items: center; gap: 14px; margin: 26px 0 10px; }
.codesearch input {
    flex: 1; max-width: 520px; padding: 13px 18px; font-size: 16px;
    border: 1px solid var(--line); border-radius: 14px; background: var(--card);
    color: var(--ink); outline: none; transition: border-color .2s, box-shadow .2s;
}
.codesearch input:focus {
    border-color: var(--blue2); box-shadow: 0 0 0 4px rgba(76, 111, 216, .12);
}
.codesearch .found { color: var(--dim); font-size: 14px; }

.codegroup { margin-top: 34px; }
.codegroup h2 { font-size: 22px; margin: 0 0 14px; }
.codegroup h2 .small { color: var(--dim); font-weight: 400; font-size: 15px; }

.codelist { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
/*
 * ⛔ Строка находки годится и для КОДА, и для ЗАГОЛОВКА статьи.
 *
 * Беда, которую показал владелец: в поиске статья выводится тем же .codeitem,
 * что и код, а у <b> стояло «flex: none» — под короткий номер «P0336». Длинный
 * заголовок статьи не сжимался, забирал всю ширину, и описание вставало в
 * колонку шириной в одно слово: «Код, / при / котором / двигатель».
 *
 * ⚠️ Чиню СТИЛЕМ, а не разбором в PHP. Вывод один на все группы, и решать по
 * длине строки («если длиннее сорока знаков — другая вёрстка») значит завести
 * порог, который однажды соврёт на среднем случае.
 *
 * Как работает: описание получает МИНИМАЛЬНУЮ ширину и право переноса. Рядом с
 * коротким кодом оно помещается в ту же строку; рядом с длинным заголовком не
 * помещается — и уходит на вторую строку во всю ширину, как и должно быть у
 * находки-статьи.
 */
.codeitem {
    display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
    padding: 12px 16px; border: 1px solid var(--line); border-radius: 14px;
    background: var(--card); color: var(--ink);
    transition: transform .18s cubic-bezier(.2,.7,.3,1), border-color .18s, box-shadow .18s;
}
.codeitem:hover {
    text-decoration: none; transform: translateY(-2px);
    border-color: var(--blue2); box-shadow: 0 10px 26px rgba(16, 26, 51, .07);
}
.codeitem b {
    font: 600 15px/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: var(--blue);
    /* ⚠️ «flex: 0 1 auto», а не «none»: длинный заголовок должен уметь
       сжиматься и переноситься, иначе он выдавливает описание. Минимум 62
       точки оставлен ради ровной колонки коротких кодов. */
    flex: 0 1 auto; min-width: 62px;
}
/* ⚠️ Минимальная ширина описания и есть переключатель вёрстки: не влезло рядом
   с заголовком — ушло на свою строку целиком. */
/* ⚠️ Заголовок-ТЕКСТ (статья, признак, термин) — обычным шрифтом и во всю
   строку. Моноширинный оставлен номерам кодов, где важна ровная колонка. */
.textitem b {
    font: 650 16px/1.35 inherit; font-family: inherit;
    color: var(--ink); flex: 1 1 100%; min-width: 0;
}
.codeitem span { color: var(--dim); font-size: 14px; flex: 1 1 15rem; min-width: 15rem; }
@media (max-width: 520px) {
    /* ⚠️ На телефоне 15rem не влезают вообще никуда, и описание уходило бы
       вниз даже у кода. Там строка и так узкая — пусть переносится сама. */
    .codeitem span { flex: 1 1 100%; min-width: 0; }
}

.codehead { display: flex; align-items: center; gap: 14px; margin-top: 10px; }
.codebig {
    font: 700 34px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: -.02em; color: var(--blue);
}

.btn {
    display: inline-block; padding: 12px 22px; border-radius: 999px;
    background: var(--blue-fill); color: var(--on-blue);
    /*
     * ⛔ СБРОС УМОЛЧАНИЙ КНОПКИ. Класс писался для ссылок, а на сайте девять
     * <button class="btn">: поиск, «Разобрать», «Прочитать», кнопки на 404 и
     * в панели cookie. Замер на живой странице показал у них
     * border: 2px outset black, font-family: Arial и cursor: default — то
     * есть объёмную рамку из девяностых, чужой шрифт и отсутствие руки на
     * наведении. Именно это и выглядело дешёво.
     *
     * ⚠️ font: inherit сбрасывает и размер, поэтому свои font-weight и
     * font-size объявлены ПОСЛЕ него.
     */
    border: 0; margin: 0; font: inherit; cursor: pointer;
    -webkit-appearance: none; appearance: none;
    font-weight: 600; font-size: 15px; text-align: center;
    transition: transform .18s, box-shadow .18s;
}
/* ⚠️ След фокуса обязателен: сброс умолчаний убирает и его, а человек,
   идущий клавишами, должен видеть, где стоит. */
.btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.btn:hover { text-decoration: none; transform: translateY(-1px); box-shadow: 0 10px 24px rgba(39, 72, 161, .25); }

@media (max-width: 700px) {
    .codelist { grid-template-columns: 1fr; }
    .codesearch input { max-width: none; }
}

/* --------------------------------------------------- боковая панель */

.withside { display: grid; grid-template-columns: 1fr 300px; gap: 32px; align-items: start; }
.sidemain { min-width: 0; }

.side { position: sticky; top: 82px; display: flex; flex-direction: column; gap: 16px; }
.sidebox {
    background: var(--card); border: 1px solid var(--line); border-radius: 18px;
    padding: 18px 20px;
}
/* ⚠️ Оба уровня: боковые блоки переведены на h2, чтобы страница не
   прыгала с H1 сразу на H3 — читалки для незрячих строят по уровням
   оглавление, и пропуск уровня рвёт его. Селектор оставлен на оба:
   если где-то h3 уцелел, он не должен потерять вид. */
.sidebox h2, .sidebox h3 { margin: 0 0 12px; font-size: 15px; letter-spacing: -.01em; }
.sidebox a {
    display: block; padding: 7px 0; font-size: 14px; color: var(--dim);
    border-bottom: 1px solid var(--line);
}
.sidebox a:last-child { border-bottom: none; }
.sidebox a:hover { color: var(--ink); text-decoration: none; }
.sidebox a.on { color: var(--ink); font-weight: 600; }
.sidebox p { margin: 0 0 14px; font-size: 14px; color: var(--dim); }

.sidecodes { display: flex; flex-wrap: wrap; gap: 8px; }
.sidecodes a {
    display: inline-block; padding: 6px 11px; border: 1px solid var(--line);
    border-radius: 999px; background: var(--soft); border-bottom: 1px solid var(--line);
    font: 600 13px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: var(--blue); transition: transform .18s, border-color .18s;
}
.sidecodes a:hover { transform: translateY(-1px); border-color: var(--blue2); }

/*
 * Разбираемые коды — плотнее и с цветной каймой, упомянутые — приглушённые.
 *
 * ⚠️ Разница должна читаться без подписи: подпись человек проскакивает, вид
 * замечает. Иначе оба блока выглядят одинаково важными, а это неправда.
 */
.codeshere .sidecodes a { border-color: var(--blue2); background: var(--soft); }
.sidecodes.soft a { color: var(--dim); background: transparent; }
.sidecodes.soft a:hover { color: var(--blue); }

/*
 * Показания под статьёй — строками, а не чипами.
 *
 * ⚠️ Номер «06» сам по себе не говорит ничего; название говорит всё. Поэтому
 * здесь не круглые чипы, а строка «номер + название».
 */
.sidepids { display: flex; flex-wrap: wrap; gap: 8px; }
.sidepids a {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 7px 12px 7px 8px; border: 1px solid var(--line);
    border-radius: 10px; background: var(--soft);
    font-size: 13px; font-weight: 600; color: var(--fg);
    transition: border-color .18s, color .18s;
}
.sidepids a b {
    padding: 3px 7px; border-radius: 6px;
    background: var(--blue-fill); color: var(--on-blue);
    font: 700 12px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ⛔ Только цвет, без сдвига: список читается сверху вниз, и скачущая вбок
   строка сбивает чтение. */
.sidepids a:hover { border-color: var(--blue2); color: var(--blue); }

/*
 * Поиск по справочнику кодов грузовиков.
 *
 * ⚠️ Поле липнет к верху при прокрутке: список из 151 кода в шести группах
 * длиннее экрана, и уехавшее вверх поле пришлось бы искать прокруткой обратно.
 */
.spnfind:empty { display: none; }
.spnfindbox {
    position: sticky; top: 8px; z-index: 3;
    display: flex; align-items: center; gap: 12px;
    margin: 18px 0 6px; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 14px;
    background: var(--bg); box-shadow: 0 6px 20px rgba(11, 94, 144, .07);
}
.spnfindin {
    flex: 1; min-width: 0; padding: 8px 10px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--soft); color: var(--fg); font-size: 15px;
}
.spnfindin:focus-visible { outline: 2px solid var(--blue2); outline-offset: 1px; }
.spnfindsaid { color: var(--dim); font-size: 13px; white-space: nowrap; }
/* ⚠️ Счётчик у заголовка группы — приглушённый и мелкий: это подсказка о
   размере, а не часть названия. */
.spngroup h3 .dim { font-weight: 400; font-size: 14px; }



.sidebox.cta { background: linear-gradient(180deg, #fff, var(--soft)); }
/* ⚠️ Цвет задаём явно: правило «.sidebox a» специфичнее «.btn» и перекрашивало
   надпись на кнопке в приглушённый серый — на синем фоне это давало контраст
   2.25 вместо 4.5. */
.sidebox.cta .btn {
    display: block; text-align: center; padding: 11px 16px; font-size: 14px;
    color: #fff;
}

/* ⚠️ На узком экране панель уходит ПОД записи, а не рядом: втиснутая сбоку
   колонка в 300 точек оставляет тексту треть ширины и делает его нечитаемым. */
@media (max-width: 980px) {
    .withside { grid-template-columns: 1fr; }
    .side { position: static; }
}

/* Текст только для читалки экрана: не видно глазом, слышно голосом. */
.vh {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Переход от справочника к разбору: код → статья. */
.deeper {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    margin: 22px 0; padding: 16px 20px; border-radius: 16px;
    background: var(--soft); border: 1px solid var(--line);
}
.deeper span { color: var(--dim); font-size: 14px; }
.deeper a { font-weight: 600; }

/* ------------------------------------------- полосы: коды по системам */

.bars { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin: 26px 0 6px; }
.bar { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 14px 16px; }
.barhead { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.barhead b { font-size: 14px; font-weight: 600; }
.barhead i {
    font-style: normal; font-size: 20px; font-weight: 700; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; color: var(--blue);
}
.bartrack { height: 6px; border-radius: 999px; background: var(--soft); margin-top: 10px; overflow: hidden; }
.bartrack span {
    display: block; height: 100%; width: 0; border-radius: 999px;
    background: linear-gradient(90deg, var(--blue2), var(--blue));
    transition: width .9s cubic-bezier(.2, .7, .3, 1);
}
/* Полоса растёт, когда блок появился в поле зрения. */
.reveal.in .bartrack span { width: var(--w); }

/* Цвет по системе: двигатель, шасси, кузов, сеть — разные вещи. */
.bar[data-letter="C"] .bartrack span { background: linear-gradient(90deg, #F0A020, #C97A05); }
.bar[data-letter="B"] .bartrack span { background: linear-gradient(90deg, #9C6BD8, #6D3FB0); }
.bar[data-letter="U"] .bartrack span { background: linear-gradient(90deg, #37B96B, #0E9F6E); }
.bar[data-letter="C"] .barhead i { color: #B45309; }
.bar[data-letter="B"] .barhead i { color: #6D3FB0; }
.bar[data-letter="U"] .barhead i { color: var(--good); }

@media (max-width: 900px) { .bars { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .bars { grid-template-columns: 1fr; } }

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

/* ------------------------------------------------ вопросы и ответы */

.faqbox { margin-bottom: 26px; }
.faqbox h2 { font-size: 22px; margin: 0 0 12px; }
.faqbox details {
    border: 1px solid var(--line); border-radius: 16px; background: var(--card);
    padding: 2px 18px; margin-bottom: 10px; transition: border-color .2s;
}
.faqbox details[open] { border-color: var(--blue2); }
.faqbox summary {
    cursor: pointer; padding: 14px 0; font-weight: 600; font-size: 16px;
    list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.faqbox summary::-webkit-details-marker { display: none; }
/* Значок «плюс» поворачивается в «минус» — видно, что вопрос раскрыт. */
.faqbox summary::after {
    content: "+"; font-size: 22px; font-weight: 400; color: var(--dim);
    transition: transform .25s cubic-bezier(.2, .7, .3, 1);
    flex: none; line-height: 1;
}
.faqbox details[open] summary::after { transform: rotate(45deg); color: var(--blue); }
.faqbox details p { margin: 0 0 16px; color: var(--dim); line-height: 1.6; }

@media (prefers-reduced-motion: reduce) {
    .faqbox summary::after { transition: none; }
}

/* ==================================================================== */
/*  Тёмная тема                                                          */
/* ==================================================================== */

/* =====================================================================
 * Страница «Подойдёт ли моя машина»
 *
 * Все цвета — через уже заведённые переменные: тогда тёмная тема
 * подхватывается сама, и второго набора правил, который разъедется при
 * первой доработке, не появляется.
 * ===================================================================== */

.carcheck {
    background: var(--card); border: 1px solid var(--line);
    border-radius: 16px; padding: 20px; margin-bottom: 22px;
}
.carform { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.cfield { display: flex; flex-direction: column; gap: 6px; flex: 1 1 130px; }
.cfield span { font-size: 13px; color: var(--dim); }
.cfield input, .cfield select {
    font: inherit; color: var(--ink); background: var(--bg);
    border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
    min-height: 44px;
}
.cfield input:focus, .cfield select:focus {
    outline: 2px solid var(--blue); outline-offset: 1px;
}
.carform .btn { min-height: 44px; flex: 0 0 auto; }

/* Ответ появляется мягко, но без задержки: человек ждёт именно его. */
.cverdict {
    margin-top: 16px; padding: 14px 16px; border-radius: 12px;
    border: 1px solid var(--line); background: var(--soft);
    opacity: 0; transform: translateY(-4px);
    transition: opacity .18s ease, transform .18s ease;
}
/* ⚠️ Пока ответа нет, блок не занимает места: иначе под формой зияет пустая
   полоса, и карточка выглядит недоделанной. Из разметки он при этом не
   исчезает — иначе экранный диктор не объявил бы появившийся ответ. */
.cverdict:not(.on) {
    margin: 0; padding: 0; height: 0; border-width: 0; overflow: hidden;
}
.cverdict.on { opacity: 1; transform: none; }
.cverdict b { display: block; font-size: 18px; margin-bottom: 4px; }
.cverdict.yes b { color: var(--good); }
.cverdict.no b { color: var(--warn); }
.cverdict.likely b { color: var(--blue); }

/* Таблица рынков — строками, а не таблицей: на телефоне она читается,
   а не уезжает вбок. */
.mtable { display: grid; gap: 10px; }
.mrow {
    display: grid; grid-template-columns: 150px auto; gap: 6px 14px;
    padding: 14px 16px; background: var(--card);
    border: 1px solid var(--line); border-radius: 12px;
}
.mname { font-weight: 600; }
.myears { display: flex; gap: 8px; flex-wrap: wrap; }
.mnote { grid-column: 1 / -1; color: var(--dim); font-size: 14px; }
.ychip {
    display: inline-block; padding: 3px 10px; border-radius: 999px;
    background: var(--soft); border: 1px solid var(--line); font-size: 13px;
}
.ychip.soft { color: var(--dim); }

.protos { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.proto {
    display: grid; grid-template-columns: 28px auto; gap: 4px 12px;
    padding: 14px 16px; background: var(--card);
    border: 1px solid var(--line); border-radius: 12px;
}
.proto b { font-size: 15px; }
.proto span { grid-column: 2; color: var(--dim); font-size: 14px; }
.picon {
    grid-row: 1 / 3; width: 28px; height: 28px; fill: none;
    stroke: var(--blue); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
/* Линия «кардиограммы» прочерчивается один раз — значок оживает, но не
   мельтешит перед глазами при чтении. */
.picon path {
    stroke-dasharray: 40; stroke-dashoffset: 40;
    animation: ptrace .7s ease forwards; animation-delay: calc(var(--i) * .09s);
}
@keyframes ptrace { to { stroke-dashoffset: 0; } }

.socketbox { display: grid; gap: 16px; grid-template-columns: minmax(200px, 260px) auto; align-items: start; }
.socket { width: 100%; height: auto; }
.socket .shell { fill: var(--soft); stroke: var(--line); stroke-width: 2; }
.socket .pin { fill: var(--blue); opacity: 0; animation: pinon .3s ease forwards; animation-delay: calc(var(--i) * .045s); }
@keyframes pinon { to { opacity: .85; } }
.socketbox ul { margin: 0; padding-left: 20px; }
.socketbox li { margin-bottom: 8px; }

@media (max-width: 640px) {
    .mrow { grid-template-columns: 1fr; }
    .socketbox { grid-template-columns: 1fr; }
    .cfield { flex: 1 1 100%; }
}

/* ⚠️ Кто просил не двигать — тому не двигаем. Прочерк и проявление
   заменяются на готовый вид, а не проигрываются медленнее. */
@media (prefers-reduced-motion: reduce) {
    .picon path { animation: none; stroke-dashoffset: 0; }
    .socket .pin { animation: none; opacity: .85; }
    .cverdict { transition: none; }
}


/* =====================================================================
 * Текстовые документы: политика конфиденциальности и подобные.
 *
 * ⚠️ Свой класс, а не общий .card. Общая карточка — это карточка блога:
 * отступы в ней даёт вложенный .cbody, и она приподнимается под курсором.
 * Текстовые блоки, свёрстанные ею, прижимались к краям экрана и шли встык.
 *
 * ⚠️ Ширина строки ограничена. Юридический текст во всю ширину монитора
 * читать невозможно — глаз теряет строку на возврате.
 * ===================================================================== */

/*
 * ⚠️ Ширину ограничиваем, но отступ от края НЕ трогаем. Он держится
 * автоматическим полем из .wrap, и стоило поставить margin-left: 0, чтобы
 * прижать текст влево, как отступ исчез вовсе — строки упёрлись в край окна.
 */
.doc { max-width: 780px; }
.doccard {
    background: var(--card); border: 1px solid var(--line);
    border-radius: 16px; padding: 22px 24px; margin-bottom: 16px;
}
.doccard h2 { font-size: 20px; letter-spacing: -.015em; margin: 0 0 10px; }
.doccard p { margin: 0 0 12px; }
.doccard p:last-child, .doccard ul:last-child { margin-bottom: 0; }
.doccard ul { margin: 0 0 12px; padding-left: 22px; }
.doccard li { margin-bottom: 7px; }
.doccard .dim { color: var(--dim); }
.upd { color: var(--dim); font-size: 14px; margin-bottom: 24px; }

/* ⚠️ Ссылки внутри правового текста подчёркиваем.
   Lighthouse на /offer/ отметил: link-in-text-block — ссылка отличается от
   текста ТОЛЬКО цветом. В договоре это хуже, чем в статье: человек, который
   не различает оттенки, не увидит, что «политика конфиденциальности» — это
   ссылка на отдельный документ, являющийся частью договора. */
/* ⚠️ Кнопки исключены: у .btn своя заливка, и подчёркивание на ней читается
   как дефект вёрстки, а не как ссылка. */
.doc .doccard p a:not(.btn),
.doc .doccard li a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }

/* Абзац с кнопкой внутри правовой карточки: отступ сверху, иначе кнопка
   прилипает к последней строке текста. */
.doc .doccard p.docbtn { margin-top: 20px; }

/* ── Пожелания к улучшению ───────────────────────────────────────────────
   ⚠️ Сделанное ЗАЧЁРКНУТО, а не убрано: ради этого раздел и заведён —
   человек видит, что его просьбу выполнили, а не что она исчезла. */
.wishes { max-width: 860px; }

/* Постраничный переход. ⚠️ Настоящие ссылки, скрипт только перехватывает. */
.wishpages { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 18px; align-items: center; }
.wishpage {
    min-width: 38px; text-align: center;
    font-size: 14px; padding: 8px 12px; border-radius: 10px;
    border: 1px solid var(--line); background: var(--card);
    color: var(--ink); text-decoration: none;
}
.wishpage:hover { border-color: var(--blue); }
.wishpage.on { background: var(--blue-fill); border-color: var(--blue-fill);
    color: var(--on-blue); cursor: default; }

/* ⚠️ Пока идёт запрос — приглушаем и запрещаем щелчки: иначе человек нажимает
   второй фильтр по ещё не обновлённому списку. */
.wishwait { opacity: .45; pointer-events: none; transition: opacity .12s; }

/* ⚠️ Место под сообщение держим ЗАРАНЕЕ скрытым элементом, а не создаём его
   на ответ: появляющийся блок сдвигает страницу, и человек читает не там, где
   смотрел. */
.wishnotebox { border-radius: 12px; padding: 12px 14px; margin: 16px 0; font-size: 14px; }
.wishhidden { display: none; }

/* Короткий список пожеланий на главной. */
.homewishes { list-style: none; margin: 18px 0 0; padding: 0; }
.homewishes li {
    display: flex; gap: 12px; align-items: baseline;
    padding: 11px 0; border-bottom: 1px solid var(--line);
}
.homewishes li:last-child { border-bottom: 0; }
.hwvotes {
    flex: 0 0 auto; min-width: 30px; text-align: center;
    font-size: 13px; font-weight: 700; color: var(--dim);
    border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px;
}
.hwtext { font-size: 15px; line-height: 1.5; }
/* ⚠️ Зачёркиваем только текст, не число голосов: зачёркнутое число читалось
   бы как «голоса отменены». */
.homewishdone .hwtext { text-decoration: line-through; color: var(--dim); }
.homewishdone .hwvotes { border-color: #10a37f; color: #10a37f; }

.wishform label { display: block; font-size: 14px; color: var(--dim); margin: 12px 0 6px; }
.wishform textarea, .wishform input, .wishform select {
    width: 100%; font: inherit; color: var(--ink); background: var(--bg);
    border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px;
    box-sizing: border-box;
}
.wishform textarea { min-height: 96px; resize: vertical; }
.wishform textarea:focus, .wishform input:focus, .wishform select:focus {
    outline: 2px solid var(--blue); outline-offset: 1px;
}
.wishrow { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.wishnote { font-size: 13px; color: var(--dim); margin: 8px 0 0; }
.wishform .btn { margin-top: 14px; }

/* ⛔ Ловушка для роботов. Убираем СО СТРАНИЦЫ, а не display:none: часть
   заполнителей форм проверяет именно display и пропускает такое поле. */
.wishtrap {
    position: absolute; left: -9999px; top: auto;
    width: 1px; height: 1px; overflow: hidden;
}

.wishtabs { display: flex; gap: 8px; flex-wrap: wrap; margin: 24px 0 16px; }
.wishtab {
    font-size: 14px; padding: 7px 13px; border-radius: 999px;
    border: 1px solid var(--line); background: var(--card);
    color: var(--ink); text-decoration: none;
}
.wishtab:hover { border-color: var(--blue); }
.wishtab.on { background: var(--blue-fill); border-color: var(--blue-fill);
    color: var(--on-blue); }

.wishlist { list-style: none; margin: 0; padding: 0; }
.wish {
    display: flex; gap: 14px; align-items: flex-start;
    background: var(--card); border: 1px solid var(--line);
    border-radius: 14px; padding: 14px 16px; margin-bottom: 10px;
}
.wishvote { margin: 0; flex: 0 0 auto; }

/* ⛔ Голосование — пара ПАЛЬЦЕВ со счётчиком между ними. Владелец про прежний
   значок со стрелкой: «если это голосовать то обычно и всем привычно это палец
   вверх и вниз и счетчик». Пара пальцев узнаётся без подписи, одиночная
   стрелка с числом — нет, её читают как готовый рейтинг.

   ⚠️ Нажатый палец ЗАЛИТ, а не обведён другим оттенком: прежнее «вы уже
   голосовали» отличалось одной границей и в списке читалось как случайное
   выделение. */
.votebox { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 56px; }
.vth {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 30px; padding: 0; font: inherit;
    color: var(--dim); background: var(--bg);
    border: 1px solid var(--line); border-radius: 9px; cursor: pointer;
    transition: background .12s, border-color .12s, color .12s;
}
.vth .vico { display: block; fill: currentColor; }
.vth:hover { border-color: var(--blue); color: var(--blue); background: var(--card); }
.vth:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.vup.on { border-color: var(--blue); color: var(--blue); background: rgba(37, 99, 235, .12); }
.vdown:hover { border-color: #d97706; color: #d97706; }
.vdown.on { border-color: #d97706; color: #d97706; background: rgba(217, 119, 6, .12); }
.vnum { font-size: 16px; font-weight: 700; color: var(--ink); line-height: 1.1; }

/* ⚠️ Подпись к числу для чтения вслух: без неё слышно «минус три» и ничего
   больше. Прятать через display:none нельзя — так её не читают вовсе. */
.vhide {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Сделанное: голосовать не за что, поэтому это метка, а не кнопки. */
.votebox.votedone {
    gap: 1px; padding: 7px 8px 6px; cursor: default;
    border: 1px solid #10a37f; border-radius: 10px;
    color: #10a37f; background: rgba(16, 163, 127, .10); text-align: center;
}
.votebox.votedone .vsign { font-size: 13px; font-style: normal; line-height: 1; }
.votebox.votedone .vnum { color: #10a37f; }
.votebox.votedone .vword {
    font-size: 10.5px; text-decoration: none; letter-spacing: .02em;
    text-transform: uppercase; opacity: .85; line-height: 1.15;
}

/* ⛔ На телефоне площадка пальца — не меньше 44 точек. Две кнопки стоят одна
   под другой, и промах по мелкой паре означает голос В ОБРАТНУЮ сторону: это
   не косметика, а неверно учтённое мнение. touch-action убирает задержку
   ожидания двойного касания. */
.vth { touch-action: manipulation; }
@media (max-width: 640px) {
    .votebox { gap: 4px; min-width: 46px; }
    .vth { width: 44px; height: 42px; }
    .vth .vico { width: 21px; height: 21px; }
}

/* История поиска: последние запросы этого браузера. */
.searchhist { margin: 10px 0 0; font-size: 14px; color: var(--dim); }
.searchhist a { color: var(--blue); }
.histclear {
    font: inherit; color: var(--dim); background: none; border: 0; padding: 0;
    text-decoration: underline; cursor: pointer;
}
.histclear:hover { color: var(--ink); }

/* Пока магазины закрыты: вместо кнопок честная строка, без битых ссылок. */
.storessoon { margin: 10px 0 0; font-size: 14px; color: var(--dim); }
.footstores.storessoon { margin-top: 6px; }

/* Голосовой поиск. Кнопку рисует скрипт — и только если распознавание есть. */
.voicebtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0; margin: 0 4px 0 0;
    color: var(--dim); background: var(--bg);
    border: 1px solid var(--line); border-radius: 10px; cursor: pointer;
    transition: background .12s, border-color .12s, color .12s;
}
.voicebtn svg { fill: currentColor; display: block; }
.voicebtn:hover { border-color: var(--blue); color: var(--blue); }
.voicebtn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* Слушаем: заметно, но БЕЗ мигания — мигание раздражает и мешает людям со
   светочувствительностью. */
.voicebtn.on {
    border-color: #d92d20; color: #fff; background: #d92d20;
    box-shadow: 0 0 0 4px rgba(217, 45, 32, .18);
}
.navfind .voicebtn { width: 34px; height: 34px; border-radius: 9px; }
/* Отказ в шапке: короткая краснота на кнопке вместо абзаца текста — абзац
   разъезжал меню на каждой странице. */
.voicebtn.voicefail { border-color: #d92d20; color: #d92d20; }

/* ---------- уровень микрофона ----------
 *
 * ⚠️ Полоски отвечают на вопрос «меня слышно?»: без них человек не знает, куда
 * говорить и не занят ли микрофон другим приложением.
 *
 * ⚠️ Встают ПОВЕРХ значка и только пока слушаем: место в кнопке одно.
 *
 * ⚠️ Высота — через transform: scaleY. Через height браузер пересчитывал бы
 * раскладку шестьдесят раз в секунду, и на телефоне это видно.
 */
.voicelvl {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center; gap: 2px;
}
.voicelvl i {
    /* ⚠️ Три пикселя, а не два, и высота почти во всю кнопку: на снимке
       первой версии полоски читались как ряд точек, а не как голос. */
    display: block; width: 3px; height: 72%;
    background: currentColor; border-radius: 3px;
    transform: scaleY(.18); transform-origin: center;
    transition: transform .08s linear;
}
/* ⚠️ Кнопке нужна точка отсчёта для полосок, иначе они лягут по странице. */
.voicebtn { position: relative; }
/* Пока слушаем, значок уступает место полоскам. */
.voicebtn.on svg { visibility: hidden; }

/* ⛔ Черновик распознавания. Браузер сначала отдаёт догадку и меняет её, пока
   человек говорит; наклон говорит «это ещё не решение». Прежде мы черновик от
   окончательного ответа не отличали и искали по нему — отсюда было «плохо
   распознаёт». */
input.voicedraft { font-style: italic; color: var(--dim); }

.voicenote { margin: 10px 0 0; font-size: 14px; color: var(--ink); }
.voicebad { color: #d92d20; }
.voicehint { margin: 8px 0 0; font-size: 13px; }

@media (max-width: 640px) {
    /* ⚠️ Площадка под палец: микрофон нажимают на телефоне чаще всего. */
    .voicebtn { width: 44px; height: 42px; }
}

/* Сообщение об исправленной опечатке: заметное, но не пугающее. */
.spellfix {
    margin: 14px 0 0; padding: 10px 14px; font-size: 15px;
    background: var(--card); border: 1px solid var(--line);
    border-left: 3px solid var(--blue); border-radius: 10px; color: var(--ink);
}
.spellfix a { color: var(--blue); }

/* Строка-объяснение над списком. */
.wishhow { font-size: 14px; color: var(--dim); margin: 22px 0 0; }
.wishbody { flex: 1 1 auto; min-width: 0; }
.wishtext { font-size: 15px; line-height: 1.6; }
.wishmeta {
    display: flex; gap: 12px; flex-wrap: wrap;
    font-size: 13px; color: var(--dim); margin-top: 8px;
}
.wisharea { border: 1px solid var(--line); border-radius: 999px; padding: 1px 9px; }
.wishdonemark { color: #10a37f; font-weight: 600; }
.wishanswer {
    background: var(--bg); border-radius: 10px; padding: 10px 12px;
    margin-top: 10px; font-size: 14px; line-height: 1.55;
}

/* ⚠️ Зачёркиваем только САМ ТЕКСТ пожелания. Зачёркнутый ответ и дата
   читались бы как отменённые, а они как раз главное. */
.wishdone .wishtext { text-decoration: line-through; color: var(--dim); }

.wishok, .wishbad {
    border-radius: 12px; padding: 12px 14px; margin: 16px 0; font-size: 14px;
}
.wishok { background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46; }
.wishbad { background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; }

@media (max-width: 560px) {
    .wishrow { grid-template-columns: 1fr; }
    .wish { padding: 12px 13px; gap: 10px; }
}

/* ── Кнопки магазинов ────────────────────────────────────────────────────
   ⚠️ Значки официальные и НЕ перекрашиваются: правила Apple и Google это
   запрещают. Единственное, что мы делаем, — выравниваем их по высоте, потому
   что у значка Google Play в самой картинке заложены поля. */
.stores { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.store { display: inline-flex; text-decoration: none; border: 0; }
.store img { display: block; height: auto; max-width: 100%; }
/* ⚠️ Отрицательный отступ гасит «воздух», встроенный в значок Play.
   Только ПО ВЕРТИКАЛИ: по бокам полей у значка нет вовсе, и боковой
   отрицательный отступ лишь съедал промежуток между кнопками.

   Числа измерены: поля 29 из 250 точек, картинка ставится высотой 57 при
   44 у Apple, значит гасить надо (57 − 44) / 2 = 6,5 точки. */
.store-play img { margin: -6.5px 0; }
.store:hover { transform: translateY(-1px); }
.store:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 8px; }

.storesblock { margin: 18px 0; }
.storestitle { font-size: 14px; color: var(--dim); margin-bottom: 8px; }

/* В подвале — своим рядом над способами оплаты. */
.footstores { margin-bottom: 14px; }

@media (max-width: 520px) {
    .stores { gap: 6px; }
}

/* Таблица файлов cookie. ⚠️ Обёртка со своей прокруткой: на телефоне четыре
   столбца не влезают, и без неё страница ехала бы вбок целиком. */
.tablewrap { overflow-x: auto; margin: 14px 0 0; }
/* Поле FMI — короткое: там всегда число от 0 до 31, и поле во всю ширину
   обещает человеку, что можно вписать больше. */
.searchbig input.narrow { max-width: 150px; flex: 0 0 auto; }
.ctable { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 520px; }
.ctable th, .ctable td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.ctable th { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--dim); }
.ctable code { font-size: 13px; background: var(--bg); padding: 2px 6px; border-radius: 6px; }
.ctable tr:last-child td { border-bottom: 0; }

/* ── Панель согласия на cookie ───────────────────────────────────────────
   ⚠️ Панель НЕ перекрывает страницу и не блокирует прокрутку: читать сайт
   можно, не отвечая. Cookie-стена («ответь или уходи») недопустима — она
   делает согласие несвободным, то есть недействительным.

   ⚠️ Окно настроек — блокирует, но его человек открыл сам. */
.cc {
    position: fixed; z-index: 9000;
    left: 0; right: 0; bottom: 0;
    display: flex; justify-content: center;
    padding: 14px;
    pointer-events: none;             /* мимо панели щелчки проходят на страницу */
}
.cc-box {
    pointer-events: auto;
    width: 100%; max-width: 560px;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line); border-radius: 18px;
    box-shadow: 0 18px 50px rgba(15, 23, 42, .28);
    padding: 20px 22px;
}
.cc-title { font-size: 18px; letter-spacing: -.01em; margin: 0 0 8px; }
.cc-text { font-size: 14px; line-height: 1.55; color: var(--dim); margin: 0 0 14px; }
.cc-text a { color: var(--blue); text-decoration: underline; text-underline-offset: 2px; }
.cc-text b { color: var(--ink); }

/* ⚠️ Кнопки ОДНОГО размера и веса. Отказаться должно быть так же легко, как
   согласиться: серая мелкая ссылка «отклонить» рядом с крупной цветной
   «принять» делает согласие недействительным. */
.cc-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.cc-btn {
    flex: 1 1 auto; min-width: 120px;
    font: inherit; font-size: 14px; font-weight: 600;
    padding: 11px 16px; border-radius: 12px; cursor: pointer;
    border: 1px solid var(--line); background: var(--bg); color: var(--ink);
}
.cc-btn:hover { border-color: var(--blue); }
.cc-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.cc-yes { background: var(--blue-fill); border-color: var(--blue-fill);
    color: var(--on-blue); }
.cc-yes:hover { filter: brightness(1.08); border-color: var(--blue); }

/* ── окно настроек ── */
.cc-modal {
    top: 0; align-items: center;
    background: rgba(15, 23, 42, .5);
    pointer-events: auto;
    overflow-y: auto; padding: 24px 14px;
}
.cc-wide { max-width: 640px; }
html.cc-locked { overflow: hidden; }

.cc-group {
    border: 1px solid var(--line); border-radius: 14px;
    padding: 14px 16px; margin-bottom: 10px;
}
.cc-fixed { background: var(--bg); }
.cc-head { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.cc-fixed .cc-head { cursor: default; }
.cc-head input { width: 18px; height: 18px; accent-color: var(--blue); flex: 0 0 auto; }
.cc-name { font-weight: 700; font-size: 15px; }
.cc-always, .cc-none, .cc-count {
    font-size: 12px; color: var(--dim);
    border: 1px solid var(--line); border-radius: 999px; padding: 2px 9px;
}
.cc-why { font-size: 13px; line-height: 1.5; color: var(--dim); margin: 8px 0 0; }
.cc-more { margin: 14px 0; }

@media (max-width: 520px) {
    .cc { padding: 10px; }
    .cc-box { padding: 16px 15px; }
    .cc-btn { flex: 1 1 100%; }
}

/* ── Публичная оферта ────────────────────────────────────────────────────
   ⚠️ Договор читают иначе, чем статью: сначала ищут «а что мне за это
   будет», потом — свой раздел. Поэтому вверху плашка с редакцией, четыре
   карточки «коротко» и оглавление, а не четырнадцать разделов подряд. */
.offer { max-width: 860px; }

.offerbadge {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin: 18px 0 26px;
}
.offerbadge span {
    font-size: 13px; color: var(--dim);
    background: var(--card); border: 1px solid var(--line);
    border-radius: 999px; padding: 6px 13px;
}
.offerbadge b { color: var(--ink); font-weight: 700; }

.offerkeys {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px; margin-bottom: 26px;
}
.okey {
    background: var(--card); border: 1px solid var(--line);
    border-radius: 14px; padding: 16px 18px;
}
.okey b { display: block; font-size: 15px; margin-bottom: 6px; }
.okey span { color: var(--dim); font-size: 14px; line-height: 1.5; }

/* Оглавление: сетка ссылок с номерами — по нему видно объём документа. */
.offertoc {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 2px 18px; margin-bottom: 26px;
    padding: 18px 20px;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
}
.offertoc a {
    display: flex; align-items: baseline; gap: 10px;
    padding: 6px 0; font-size: 14px;
    color: var(--ink); text-decoration: none;
}
.offertoc a:hover { color: var(--blue); }
.offertoc b {
    flex: 0 0 22px; text-align: right;
    color: var(--dim); font-weight: 700; font-size: 13px;
}

/* Номер раздела: кружок перед заголовком — глазу легче держать место. */
.offer .doccard h2 { display: flex; align-items: center; gap: 11px; }
.onum {
    flex: 0 0 28px; height: 28px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; font-weight: 700; color: var(--on-blue);
    background: var(--blue-fill); border-radius: 50%;
}

/* ⚠️ Раздел про границы приложения выделен намеренно: это единственное
   место договора, которое человек обязан прочитать до покупки, а не после
   спора. Красная рамка, а не жирный шрифт: жирный теряется среди прочего. */
.offerwarn { border-color: #d97706; box-shadow: inset 3px 0 0 #d97706; }
.offerwarn .onum { background: #d97706; }

/* ⚠️ Якорь из оглавления не должен прятать заголовок под шапкой. */
.offer .doccard h2[id] { scroll-margin-top: 84px; }

@media (max-width: 520px) {
    .offertoc { padding: 14px 15px; }
    .offerkeys { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
    .doccard { padding: 18px 16px; }
}


/* Время чтения: часы и число. Значок того же роста, что и цифры. */
.rtime { display: inline-flex; align-items: center; gap: 5px; }
.ticon {
    width: 14px; height: 14px; flex: none; fill: none;
    stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round; opacity: .75;
}


/* Страница «такой страницы нет»: куда пойти дальше. */
.gonext { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.go {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 16px 18px; background: var(--card);
    border: 1px solid var(--line); border-radius: 14px; color: var(--ink);
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), border-color .2s;
}
.go:hover { text-decoration: none; transform: translateY(-2px); border-color: var(--blue2); }
/* ⚠️ Значок показываем принудительно: в шапке .mi на широком экране спрятан,
   и без этого правила карточка оставалась без картинки. */
.go .mi { display: block; margin-top: 2px; }
.go b { display: block; margin-bottom: 3px; }
.go span { color: var(--dim); font-size: 14px; }


/* Словарь терминов. */
.termlist { display: grid; gap: 10px; }
/* ⚠️ Термин наследует .codeitem, чтобы общий поиск справочников отбирал его
   тем же кодом. Но раскладка у него своя: там строка, здесь абзацы. */
.term.codeitem { display: block; padding: 18px 20px; }
.term.codeitem:hover { transform: none; box-shadow: none; border-color: var(--line); }
.term h3 { font-size: 18px; margin: 0 0 6px; }
.term .tshort { font-weight: 500; margin: 0 0 8px; }
.term p { margin: 0 0 8px; }
.term p:last-child { margin-bottom: 0; }
.term .twhere a { font-size: 14px; }
/* Значок «#» проявляется при наведении: он нужен, чтобы скопировать ссылку
   на термин, и не должен мешать чтению. */
/* ⚠️ Значок ссылки вместо голой решётки: «#» читался как опечатка. Виден
   всегда, но приглушён — заголовок важнее. */
.tanchor {
    display: inline-flex; vertical-align: middle; margin-left: 6px;
    color: var(--line); text-decoration: none; font-weight: 400;
}
.tanchor svg {
    width: 16px; height: 16px; fill: none; stroke: currentColor;
    stroke-width: 1.8; stroke-linecap: round;
}
.term:hover .tanchor { color: var(--blue); }
.tanchor:focus { color: var(--blue); }
/* ⚠️ Отступ под шапку: без него якорь уводит термин под прилипшую шапку,
   и человек попадает на заголовок, которого не видно. */
.term { scroll-margin-top: 78px; }


/* Подвал столбцами: ссылок стало полтора десятка, строкой их не читают. */
/* ⚠️ Отступы ТОЛЬКО сверху и снизу. Короткая запись padding затирала
   боковые отступы .wrap — и при ширине окна от 1092 и уже столбцы подвала
   упирались в левый край экрана. На широком экране это пряталось за центровкой. */
.fcols {
    display: grid; gap: 26px 30px;
    padding-top: 34px; padding-bottom: 10px;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}
.fcol { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
/* ⚠️ Длинный столбец занимает две доли сетки и раскладывает ссылки в два
   ряда: двенадцать справочников в один столбик делали подвал вдвое выше
   остальных колонок, и глаз читал это как ошибку вёрстки.
   ⚠️ Заголовок — во всю ширину столбца, иначе он встаёт первым пунктом
   первого ряда и теряется среди ссылок. */
.fcol.wide {
    grid-column: span 2; display: grid; align-content: start;
    grid-template-columns: 1fr 1fr; gap: 8px 22px;
}
.fcol.wide h2 { grid-column: 1 / -1; }
/* ⚠️ На широком экране задаём шесть дорожек явно. При «auto-fit» их выходило
   пять, широкий столбец занимал две — и «Продавец» уезжал на второй ряд,
   оставляя рядом пустое поле в половину подвала. */
@media (min-width: 1040px) {
    .fcols { grid-template-columns: repeat(6, 1fr); }
}
@media (max-width: 700px) {
    /* ⚠️ На телефоне — обычным одним столбиком: два ряда по 80 точек ширины
       рвут подписи вроде «Что делает машина» на три строки. */
    .fcol.wide { grid-column: auto; display: flex; }
}
/* ⚠️ Уровень h3, а не h4: после h2 на странице перескок через уровень —
   Lighthouse считает это ошибкой доступности и снижает оценку, а читалка
   экрана теряет строение страницы. */
/* ⚠️ Оба уровня: заголовки подвала переведены на h2. На страницах без своего
   H2 — например, на поиске — после H1 сразу шёл H3 подвала, и оглавление
   страницы для читалок рвалось. Селектор оставлен на оба на случай, если
   где-то h3 уцелел. */
.fcol h2, .fcol h3 {
    margin: 0 0 2px; font-size: 13px; text-transform: uppercase;
    letter-spacing: .05em; color: var(--dim); font-weight: 600;
}
/* ⚠️ Значок и подпись в одну строку, значок не сжимается: без flex:none он
   на узком экране расплющивался в полоску. */
.fcol a { color: var(--ink); font-size: 15px;
    display: inline-flex; align-items: center; gap: 8px; }
.fcol a .mi {
    /* ⛔ display обязателен. Базовое правило .mi скрывает значок («display:
       none»), а показывают его отдельные правила для каждого места — шапки,
       поля поиска, списка. Я задал размер и цвет, но не показал значок, и
       тридцать три рисунка честно висели в разметке невидимыми. Мерил в
       браузере — размер вышел 0×0, display: none. */
    display: block;
    width: 15px; height: 15px; flex: none;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
    opacity: .5; transition: opacity .16s;
}
.fcol a:hover .mi { opacity: 1; }
/*
 * ⛔ В подвале значки НЕ прочерчиваются при появлении. Тридцать один рисунок,
 * оживающий разом при прокрутке до подвала, — это иллюминация, а не
 * украшение. Движение только по наведению: тогда оно отвечает на действие
 * человека.
 */
.fcol a:hover .mi path { animation: midraw .5s cubic-bezier(.3, .8, .3, 1) backwards; }
@media (prefers-reduced-motion: reduce) {
    .fcol a:hover .mi path { animation: none; }
}
.fcol a:hover { color: var(--blue); }
.fnote { color: var(--dim); font-size: 14px; line-height: 1.5; }
/* Нижняя строка: знак, год и языки. */
.fbottom { padding-top: 16px; border-top: 1px solid var(--line); }
@media (max-width: 700px) {
    .fcols { gap: 20px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}


/* Шаги оплаты: схема пути, а не список в столбик. */
.steps { display: grid; gap: 10px; margin: 4px 0 14px; }
.step {
    display: grid; grid-template-columns: 44px auto; gap: 14px; align-items: center;
    padding: 12px 14px; background: var(--bg);
    border: 1px solid var(--line); border-radius: 14px;
}
.step b { display: block; }
.step > div > span { color: var(--dim); font-size: 14px; }
.sicon { position: relative; width: 44px; height: 44px; }
.sicon svg {
    width: 44px; height: 44px; fill: none; stroke: var(--blue);
    stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* Номер шага — на значке: и порядок виден, и картинка не потеряна. */
.sicon b {
    position: absolute; right: -2px; bottom: -2px;
    min-width: 18px; height: 18px; padding: 0 4px;
    background: var(--blue-fill); color: var(--on-blue); border-radius: 999px;
    font-size: 11px; line-height: 18px; text-align: center;
}
/* ⚠️ Контур прочерчивается один раз при появлении: движение показывает
   последовательность шагов, но не мельтешит под рукой у читающего. */
.step svg path {
    stroke-dasharray: 60; stroke-dashoffset: 60;
    animation: strace .8s ease forwards; animation-delay: calc(var(--i) * .12s);
}
@keyframes strace { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
    .step svg path { animation: none; stroke-dashoffset: 0; }
}


/* Поиск по сайту: одно поле и кнопка. */
.searchbig { display: flex; gap: 10px; margin: 18px 0 14px; flex-wrap: wrap; }
.searchbig input {
    flex: 1 1 320px; font: inherit; font-size: 17px; color: var(--ink);
    background: var(--card); border: 1px solid var(--line);
    border-radius: 14px; padding: 14px 18px; min-height: 52px; outline: none;
    transition: border-color .2s, box-shadow .2s;
}
.searchbig input:focus {
    border-color: var(--blue2); box-shadow: 0 0 0 4px rgba(76, 111, 216, .12);
}
.searchbig .btn { min-height: 52px; padding: 0 24px; }

/*
 * ⚠️ Включается по настройке системы, без переключателя на странице. Человек
 * уже сказал телефону, какой вид ему удобен, — спрашивать второй раз значит
 * не поверить ему.
 *
 * ⚠️ Меняем только переменные. Правка отдельных правил под тёмный вид
 * означала бы два набора стилей, которые разъезжаются при первой же доработке.
 */
@media (prefers-color-scheme: dark) {
    :root {
        --ink: #E7ECF5;
        --dim: #A6B0C2;
        --line: #242D3E;
        --bg: #0B1220;
        --card: #131C2C;
        /* На тёмном можно взять цвет ближе к знаку: 9,97 на фоне. */
        --blue: #6EC6FF;
        --blue2: #4FB6F7;
        /* ⚠️ Фон плашки НЕ светлеет: белому тексту нужен насыщённый синий.
           Этот оттенок уже был подобран для кнопки и проверен контрастом. */
        --blue-fill: #3E6BD6;
        --on-blue: #fff;
        --soft: #14263A;
        --good: #34C77B;
        --warn: #E8A54F;
    }

    /* Шапка полупрозрачная — подложку тоже затемняем. */
    .top { background: rgba(11, 18, 32, .82); }

    /* Карточки на тёмном не нуждаются в тенях: они только грязнят фон. */
    .card:hover, .codeitem:hover { box-shadow: 0 12px 30px rgba(0, 0, 0, .35); }
    .sarrow { background: rgba(19, 28, 44, .92); }

    /* Предупреждения: тёплый цвет на тёмном фоне, а не жёлтая заливка. */
    .article .warn, .preview .warn {
        background: #26200F; border-color: #4A3A16; color: #EFC178;
    }
    .sidebox.cta { background: linear-gradient(180deg, var(--card), var(--soft)); }

    /* Обложки записей: приглушаем, чтобы не выжигали глаза в темноте. */
    .cover img, .hero-cover img { filter: brightness(.88); }

    /*
     * ⚠️ Отдельной заплаты для кнопки больше нет: насыщенный фон задан цветом
     * --blue-fill, и его берут все девять синих плашек сразу. Прежняя заплата
     * лечила одну кнопку из девяти мест с той же бедой — и выглядела как
     * решённая задача.
     */
    .btn:hover { background: #4E7BE6; }

    /* ⚠️ Значки способов оплаты НЕ инвертируем: перекрашенный логотип
       платёжной системы нарушает правила их использования. Вместо этого
       кладём их на светлую подложку — так они читаются и на тёмном фоне. */
    .paymethods img {
        background: #fff; border-radius: 4px; padding: 2px 4px;
    }
}


/* ── Пошаговые руководства ──────────────────────────────────────────────
   ⚠️ Карточки — ссылки целиком, а не заголовок-ссылка внутри блока: попасть
   пальцем в строку из двух слов на телефоне трудно, и человек несколько раз
   промахивается мимо того, что явно выглядит кнопкой. */
.howlist { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.howcard {
    display: flex; gap: 14px; align-items: flex-start; padding: 18px;
    background: var(--card); border: 1px solid var(--line); border-radius: 18px;
    color: var(--ink); text-decoration: none;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.howcard:hover {
    transform: translateY(-2px); border-color: var(--brand);
    box-shadow: 0 14px 34px rgba(16, 26, 51, .10); text-decoration: none;
}
.howcard .hico {
    flex: none; width: 42px; height: 42px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: var(--soft); color: var(--brand);
}
.hicon { width: 22px; height: 22px; }
.howcard .hbody { display: flex; flex-direction: column; gap: 6px; }
.howcard .htitle { font-weight: 650; line-height: 1.35; }
.howcard .hshort { color: var(--dim); font-size: 14px; line-height: 1.5; }
.howcard .hmeta { color: var(--dim); font-size: 13px; }

.hhead { display: flex; gap: 16px; align-items: center; margin-bottom: 6px; }
.hhead .hicon { width: 34px; height: 34px; color: var(--brand); flex: none; }
.hhead h1 { margin: 0; }
.hhead .hmeta { margin: 4px 0 0; color: var(--dim); font-size: 14px; }

/* Сами шаги. Номер — крупный кружок: по нему видно, где ты в списке. */
.steps { list-style: none; margin: 26px 0 0; padding: 0; counter-reset: none; }
.step { display: flex; gap: 16px; padding: 0 0 22px; position: relative; }
.step:not(:last-child)::before {
    content: ""; position: absolute; left: 17px; top: 38px; bottom: 4px;
    width: 2px; background: var(--line);
}
.snum {
    flex: none; width: 36px; height: 36px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--brand); color: #fff; font-weight: 700; font-size: 15px;
    position: relative; z-index: 1;
}
.step .sbody h2 { margin: 6px 0 6px; font-size: 19px; }
.step .sbody p { margin: 0; color: var(--dim); line-height: 1.6; }
.alsohow { margin-top: 34px; }
.alsohow h2 { margin-bottom: 14px; }

/* ── Разбор кода по знакам ──────────────────────────────────────────────
   ⚠️ Схема рисуется разметкой, а не картинкой: так она читается в тёмной
   теме, тянется под ширину экрана и доступна читалке. Картинка со схемой
   на телефоне превращается в нечитаемую полоску. */
.codemap { margin: 26px 0; padding: 20px; background: var(--soft); border-radius: 18px; }
.cmrow { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.cmpart { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 74px; }
.cmsign {
    font: 700 30px/1 ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    color: var(--brand); background: var(--card); border: 1px solid var(--line);
    border-radius: 12px; padding: 10px 16px;
}
.cmline { width: 2px; height: 14px; background: var(--line); }
.cmname { font-size: 12px; color: var(--dim); text-align: center; line-height: 1.35; max-width: 96px; }
.codemap figcaption { margin-top: 14px; text-align: center; color: var(--dim); font-size: 14px; }


/* ── Выбор адаптера ─────────────────────────────────────────────────────
   Короткий ответ двумя карточками: большинству нужна левая, и незачем
   заставлять читать всю страницу, чтобы это понять. */
.verdicts { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin: 22px 0 30px; }
.verdict { padding: 20px; border-radius: 18px; border: 1px solid var(--line); background: var(--card); }
.verdict .vhead { display: flex; align-items: center; gap: 10px; }
.verdict .vhead svg { width: 22px; height: 22px; flex: none; }
.verdict h2 { margin: 0; font-size: 18px; }
.verdict p { margin: 10px 0 0; color: var(--dim); line-height: 1.6; }
.verdict .vprice { margin-top: 12px; font-weight: 700; color: var(--ink); }
.verdict.good { border-color: #34a85333; background: #34a8530d; }
.verdict.good .vhead svg { color: #2e9e4b; }
.verdict.warn { border-color: #e8940033; background: #e894000d; }
.verdict.warn .vhead svg { color: #d18100; }

.kinds { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 16px; }
.kind { padding: 18px; border: 1px solid var(--line); border-radius: 16px; background: var(--card); }
.kind h3 { margin: 0 0 4px; font-size: 17px; }
.kind .kwho { margin: 0 0 12px; color: var(--dim); font-size: 13px; }
.kind p { margin: 0 0 8px; font-size: 14px; line-height: 1.55; }
.kind .kplus span, .kind .kminus span { font-weight: 700; margin-right: 4px; }
.kind .kplus span { color: #2e9e4b; }
.kind .kminus span { color: #d05a3a; }
.kind .kios { display: inline-block; margin: 6px 0 0; padding: 4px 10px; border-radius: 999px; font-size: 12px; }
.kind .kios.yes { background: #34a8531f; color: #227a39; }
.kind .kios.no { background: #d05a3a1f; color: #a8442a; }

/* Пять команд: код слева, объяснение справа — глазами читается как таблица,
   а на телефоне переносится столбиком. */
.cmdlist { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 10px; }
.cmd { display: flex; gap: 14px; align-items: flex-start; padding: 14px 16px;
    border: 1px solid var(--line); border-radius: 14px; background: var(--card); }
.cmdcode { flex: none; font: 600 14px/1 ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    color: var(--brand); background: var(--soft); padding: 8px 10px; border-radius: 9px; }
.cmd b { display: block; margin-bottom: 4px; }
.cmd p { margin: 0; color: var(--dim); font-size: 14px; line-height: 1.55; }

.warnbox { margin: 22px 0 0; padding: 20px; border-radius: 16px;
    border: 1px solid #e8940040; background: #e894000f; }
.warnbox h3 { margin: 0 0 8px; font-size: 17px; }
.warnbox p { margin: 0; line-height: 1.65; }

.fakes { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); margin-top: 16px; }
.fake { padding: 18px; border: 1px solid var(--line); border-radius: 16px; background: var(--card); }
.fake h3 { margin: 0 0 8px; font-size: 16px; }
.fake p { margin: 0; color: var(--dim); font-size: 14px; line-height: 1.6; }


/* Как приходит услуга после оплаты — нумерованный список с крупными цифрами.
   ⚠️ Это требование банка, и читать его будет человек, который уже заплатил
   и волнуется: цифры крупные, шаги короткие. */
.getlist { list-style: none; margin: 18px 0 0; padding: 0; counter-reset: getn; display: grid; gap: 12px; }
.getitem { counter-increment: getn; display: grid; grid-template-columns: 34px 1fr; gap: 12px; align-items: start; }
.getitem::before {
    content: counter(getn); grid-row: span 2;
    width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--soft); color: var(--brand); font-weight: 700; font-size: 14px;
}
.getitem b { font-weight: 650; }
.getitem span { display: block; color: var(--dim); font-size: 14px; line-height: 1.55; margin-top: 3px; }


/* ------------------------------------------------------------------ /calc/
   Калькуляторы. Ползунок и число рядом — одно значение, два способа задать:
   пальцем на ощупь и цифрами точно. */
.calcnav { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 6px; }
.calcnav a {
    padding: 8px 14px; border-radius: 999px; font-size: 14px; text-decoration: none;
    color: var(--dim); background: var(--card); border: 1px solid var(--line);
    transition: color .15s, border-color .15s, transform .15s;
}
.calcnav a:hover { color: var(--blue); border-color: var(--blue2); transform: translateY(-1px); }

.calcs { display: grid; gap: 18px; margin-top: 18px; }
.calc {
    padding: 22px; border: 1px solid var(--line); border-radius: 18px; background: var(--card);
    scroll-margin-top: 90px;
}
.calc h2 { margin: 0 0 6px; font-size: 20px; }
.chint { margin: 0 0 16px; color: var(--dim); font-size: 14px; line-height: 1.6; }
.cnote { margin: 14px 0 0; color: var(--dim); font-size: 13px; line-height: 1.6; }

.cfield { margin-bottom: 14px; }
.cfield label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 7px; }
.crow { display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center; }

/* ⚠️ Ползунок оформлен явно для обоих движков: без -webkit-slider-thumb в
   Safari остаётся системный, и «премиальность» рассыпается ровно на телефоне,
   ради которого всё и делалось. */
/* ⚠️ Селектор с именем тега: рядом живёт правило «.cfield input», а оно
   весомее одного класса — и молча перекрывало дорожку ползунка цветом
   обычного поля. Снаружи это выглядело как «правка не сработала»; нашлось
   вопросом к самой странице (tools/probe_style.mjs), а не чтением файла. */
input.crange {
    -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
    border-radius: 999px; outline: none; margin: 0;
    touch-action: pan-y;
    /* ⚠️ Пройденная часть — фирменным синим. Доля приходит из calc.js
       переменной --p; без неё (скрипт не загрузился) дорожка просто серая,
       и ползунок остаётся рабочим. */
    background: linear-gradient(90deg,
        var(--blue) 0 var(--p, 0%), var(--soft) var(--p, 0%) 100%);
}
input.crange::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 24px; height: 24px; border-radius: 50%; cursor: grab;
    background: var(--blue2); border: 3px solid var(--card);
    box-shadow: 0 2px 8px rgba(11, 94, 144, .35);
    transition: transform .12s;
}
input.crange::-webkit-slider-thumb:active { cursor: grabbing; transform: scale(1.15); }
input.crange::-moz-range-thumb {
    width: 18px; height: 18px; border-radius: 50%; cursor: grab;
    background: var(--blue2); border: 3px solid var(--card);
    box-shadow: 0 2px 8px rgba(11, 94, 144, .35);
}
input.crange:focus-visible { box-shadow: 0 0 0 3px rgba(0, 166, 255, .35); }

.cnum { display: inline-flex; align-items: baseline; gap: 5px; }
.cinput {
    width: 104px; padding: 9px 10px; text-align: right;
    font-size: 15px; font-variant-numeric: tabular-nums;
    color: var(--ink); background: var(--bg);
    border: 1px solid var(--line); border-radius: 10px;
}
.cinput:focus { outline: none; border-color: var(--blue2); background: var(--card); }
.cnum i { font-style: normal; color: var(--dim); font-size: 13px; min-width: 42px; }

/* Итог — крупно, потому что ради него страницу и открыли. */
.cout {
    margin-top: 18px; padding: 16px 18px; border-radius: 14px;
    background: var(--soft); display: grid; gap: 10px;
}
.cline { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; }
.cline span { color: var(--dim); font-size: 14px; }
.cline b { font-size: 22px; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.cline.small b { font-size: 16px; font-weight: 600; }
/* Заплатка здесь больше не нужна: --good и --warn исправлены глобально
   (см. :root). Точечные цвета разошлись бы с остальным сайтом при первой же
   правке палитры. */
.cbad b { color: var(--warn); }
.cgood b { color: var(--good); }

.units { display: grid; gap: 12px; }
.upair {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    padding: 12px 14px; border: 1px solid var(--line); border-radius: 14px;
}
.upair b { min-width: 120px; font-size: 14px; font-weight: 600; }
.upair span { display: inline-flex; align-items: baseline; gap: 5px; }
.upair i { font-style: normal; color: var(--dim); font-size: 13px; }

.calcmore { margin-top: 22px; padding: 20px; border: 1px solid var(--line); border-radius: 18px; background: var(--card); }
.calcmore h2 { margin: 0 0 10px; font-size: 18px; }
.calcmore ul { margin: 0; padding-left: 18px; }
.calcmore li { margin: 6px 0; line-height: 1.6; }

@media (max-width: 560px) {
    .crow { grid-template-columns: 1fr; gap: 10px; }
    .cnum { justify-content: flex-end; }
    .cinput { width: 120px; }
    .upair b { min-width: 100%; }
}


/* ---------------------------------------------- шкала рынков на /cars/
   ⚠️ Раньше здесь была таблица «рынок — год»: точная, но её надо было
   ЧИТАТЬ. Шкала отвечает положением — видно, что дизель в Европе включился
   на три года позже бензина, и в эту щель попадает дизель 2002 года. */
.mscale { display: grid; gap: 20px; margin-top: 14px; }
.mruler { position: relative; height: 18px; margin-left: 132px; }
.mruler span {
    position: absolute; transform: translateX(-50%);
    font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums;
}
.mline { display: grid; grid-template-columns: 120px 1fr; gap: 12px; align-items: center; }
.mline .mname { font-weight: 600; font-size: 15px; }
.mtrack {
    position: relative; height: 10px; border-radius: 999px;
    background: var(--soft); margin: 22px 0 26px;
}
/* Заливка «здесь разъём уже обязателен». */
.mfill, .mfog {
    position: absolute; top: 0; bottom: 0; border-radius: 999px;
    background: linear-gradient(90deg, var(--blue2), var(--blue));
    animation: mgrow .7s ease both;
}
/* ⚠️ Неопределённость — размытая полоса, а не точка: точка означала бы год,
   которого никто не вводил. */
.mfog { background: linear-gradient(90deg, transparent, var(--line) 45%, var(--line)); }
@keyframes mgrow { from { transform: scaleX(.2); transform-origin: left; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .mfill, .mfog { animation: none; } }

.mdot {
    position: absolute; top: 50%; transform: translate(-50%, -50%);
    white-space: nowrap; font-size: 12px; font-weight: 600;
    padding: 4px 9px; border-radius: 999px; color: var(--on-blue);
    background: var(--blue-fill);
    box-shadow: 0 2px 8px rgba(11, 18, 32, .18);
}
/* Развели по вертикали: иначе «бензин 2001» и «дизель 2004» наезжают. */
.mdot.petrol { top: -14px; }
.mdot.diesel { top: auto; bottom: -18px; transform: translate(-50%, 50%); background: var(--blue2); }
.mdot.soft { background: var(--card); color: var(--dim); border: 1px solid var(--line); box-shadow: none; }
.mscale .mnote { grid-column: 2; margin-top: -14px; color: var(--dim); font-size: 14px; line-height: 1.55; }

@media (max-width: 640px) {
    .mruler { margin-left: 0; }
    .mline { grid-template-columns: 1fr; gap: 4px; }
    .mscale .mnote { grid-column: 1; }
    .mdot { font-size: 11px; padding: 3px 7px; }
}

/* ------------------------------------------------- разбор кода по знакам */

/*
 * ⚠️ Плитки появляются ступенькой (--step задаётся в разметке), но задержка
 * маленькая: 70 мс на плитку. Красивая долгая волна на четыре плитки — это
 * почти полсекунды, в течение которых человек смотрит на пустоту.
 */
.anat { display: grid; gap: 10px; margin: 14px 0 6px; }
@media (min-width: 760px) {
    .anat { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
}
.anatcard {
    display: flex; align-items: center; gap: 14px;
    padding: 12px 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 1px 2px rgba(16, 26, 51, .04);
    transition: transform .5s cubic-bezier(.2, .7, .3, 1) calc(var(--step, 0) * 70ms),
                box-shadow .2s, border-color .2s;
}
.reveal .anatcard { transform: translateY(10px); }
.reveal.in .anatcard { transform: none; }
.anatcard:hover { border-color: var(--blue2); box-shadow: 0 6px 18px rgba(16, 26, 51, .08); }
/*
 * ⚠️ Знак кода — моноширинным и крупно: он и есть предмет разговора. Подложка
 * градиентом, но текст на ней белый и жирный, контраст 8:1 — цветная плашка
 * со светлой цифрой читалась бы хуже обычной серой.
 */
.anatchar {
    flex: 0 0 auto; width: 52px; height: 52px;
    display: flex; align-items: center; justify-content: center;
    font: 700 20px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: .5px; color: #fff;
    background: linear-gradient(135deg, var(--blue) 0%, var(--blue2) 100%);
    border-radius: 12px;
}
.anattext { min-width: 0; }
.anattext b {
    display: flex; align-items: center; gap: 7px;
    font-size: 13px; font-weight: 600; color: var(--dim);
    text-transform: uppercase; letter-spacing: .3px;
}
/* ⚠️ display: block обязателен. Общее правило прячет .mi (в шапке на широком
   экране значки не нужны), и без этой строки плитки остаются без картинок —
   в разметке значок есть, на экране его нет. */
.anattext b .mi {
    display: block; flex: 0 0 auto; width: 16px; height: 16px;
    fill: none; stroke: var(--blue2); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.anattext span { display: block; margin-top: 3px; font-size: 15px; color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
    .anatcard, .reveal .anatcard { transform: none; transition: none; }
}

/* ------------------------------------------------- значки на панели */

/*
 * ⚠️ Цвет здесь — не украшение, а смысл: красный значит «остановись», жёлтый
 * «проверь». Поэтому цветом красим сам значок и полосу карточки, но НИКОГДА
 * не полагаемся на него одного: рядом всегда стоит слово («Красный —
 * остановиться»). Человек, не различающий красный и зелёный, — это каждый
 * двенадцатый мужчина, и раздел про безопасность обязан говорить словами.
 */
.lampsec { margin: 26px 0 8px; }
.lamptitle { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.lamptitle::before {
    content: ""; width: 12px; height: 12px; border-radius: 50%;
    background: currentColor; flex: none;
}
.lamp-red { color: #A3231B; }
.lamp-amber { color: var(--warn); }
.lamp-green { color: var(--good); }

.lampgrid { display: grid; gap: 12px; margin-top: 14px; }
@media (min-width: 700px) {
    .lampgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1040px) {
    .lampgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/*
 * ⚠️ color здесь НЕ задаём. Цвет карточки — это цвет её уровня (.lamp-red и
 * соседи), и он приходит из класса рядом; собственный color: var(--ink) в
 * этом правиле забивал его — оба селектора весом в один класс, а это правило
 * ниже по файлу. Итог: полоса и значок красились чернилами, и красная лампа
 * выглядела точно как жёлтая. Цвет текста задан отдельно у b и span.
 */
.lampcard {
    display: block; padding: 16px 16px 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
    border-top: 3px solid currentColor;
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), box-shadow .2s, border-color .2s;
}
.lampcard:hover {
    text-decoration: none; transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(16, 26, 51, .10);
}
.lampcard b { display: block; margin: 10px 0 4px; font-size: 16px; color: var(--ink); }
.lampcard span { display: block; font-size: 14px; color: var(--dim); }
/* ⚠️ display: block обязателен: общее правило прячет значки в шапке. */
.lampicon {
    display: block; width: 34px; height: 34px;
    fill: none; stroke: currentColor; stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round;
}
.lamphead { display: flex; align-items: center; gap: 16px; margin-bottom: 10px; }
.lamphead .lampicon { width: 56px; height: 56px; flex: none; }
/*
 * Значок лампы прочерчивается при открытии страницы.
 *
 * ⚠️ Не украшение: эта страница — обещание сайта («что значит значок»), и
 * первое, что человек видит, — сам значок. Когда он рисуется у него на глазах,
 * читается «мы знаем, что это за лампа».
 *
 * ⚠️ По очереди, потому что значок состоит из нескольких контуров: руль
 * отдельно, восклицательный знак отдельно. Видно, как рисунок собирается, а не
 * как он мигает целиком.
 *
 * ⛔ Пунктир живёт ТОЛЬКО в кадрах анимации (@keyframes midraw выше). Обычное
 * состояние — целый контур, поэтому любой сбой оставит значок непрочерченным, а
 * не пустым.
 */
.lamphead .lampicon path {
    animation: midraw .55s cubic-bezier(.3, .8, .3, 1) backwards;
}
.lamphead .lampicon path:nth-child(2) { animation-delay: .16s; }
.lamphead .lampicon path:nth-child(3) { animation-delay: .3s; }
.lamphead .lampicon path:nth-child(4) { animation-delay: .42s; }
.lamphead h1 { margin: 2px 0 0; }
.lamplevel {
    display: inline-block; font-size: 13px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .3px; color: currentColor;
}
.steps { margin: 10px 0 18px; padding-left: 22px; }
.steps li { margin-bottom: 8px; color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
    .lampcard { transition: none; }
    .lampcard:hover { transform: none; }
}

/* ------------------------------------------------- фирменный штрих */

/*
 * Полоска из трёх цветов знака под заголовком раздела.
 *
 * ⚠️ Это единственное место, где цвета знака показаны как есть: здесь они
 * фигура, а не текст. Буквами их брать нельзя — измерено: 2,28–2,66 на белом
 * при норме 4,5.
 *
 * ⚠️ Полоска рисуется псевдоэлементом, а не отдельным тегом: в разметке
 * пришлось бы дописывать её к каждому заголовку, и однажды где-то забыли бы.
 */
.page h1::after,
.article h1::after {
    content: "";
    display: block;
    width: 68px;
    height: 4px;
    margin-top: 14px;
    border-radius: 2px;
    background: linear-gradient(90deg,
        var(--brand-orange) 0 33%,
        var(--brand-blue) 33% 66%,
        var(--brand-green) 66% 100%);
}

/*
 * ⚠️ Рамка при выборе с клавиатуры — фирменным оранжевым, и она ОБЯЗАНА быть
 * заметной. Браузерную рамку часто убирают ради красоты, и тогда человек,
 * ходящий по сайту клавишей Tab, теряет место — сайт для него превращается в
 * лабиринт. Оранжевый выбран потому, что он не совпадает ни с одним смысловым
 * цветом страницы: ни с синим действием, ни с красным предупреждением.
 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
summary:focus-visible {
    outline: 3px solid var(--brand-orange);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Выделение текста — в цвет знака, но мягкой заливкой, чтобы буквы читались. */
::selection { background: rgba(0, 166, 255, .22); }

/* --------------------------------------- шаги на странице значка */

/*
 * ⚠️ Отдельный класс, а не общий .steps: тот занят руководствами, и там
 * нумерация выключена (list-style: none). Здесь номера — суть: это порядок
 * действий на дороге, и «сначала съехать» не равно «сначала проверить масло».
 */
.lampsteps { counter-reset: lampstep; list-style: none; margin: 12px 0 20px; padding: 0; }
.lampsteps li {
    counter-increment: lampstep;
    position: relative;
    padding: 0 0 16px 44px;
    color: var(--ink);
}
.lampsteps li::before {
    content: counter(lampstep);
    position: absolute; left: 0; top: 0;
    width: 28px; height: 28px;
    display: flex; align-items: center; justify-content: center;
    font-size: 14px; font-weight: 700; color: var(--on-blue);
    background: var(--blue-fill);
    border-radius: 50%;
}
/* Разбор со страницы лампы: «что почитать дальше».

   ⚠️ Намеренно НЕ похож на .lampsteps с их номерами: это не продолжение
   порядка действий, а другой ход — уйти читать. Одинаковый вид склеил бы
   их в один список, и человек читал бы ссылки как пятый и шестой шаги. */
.lampread { list-style: none; margin: 12px 0 20px; padding: 0; }
.lampread li { position: relative; padding: 0 0 10px 26px; }
.lampread li::before {
    content: "→";
    position: absolute; left: 0; top: 0;
    color: var(--blue); font-weight: 700;
}
.lampread a { color: var(--blue); text-decoration: none; border-bottom: 1px solid var(--line); }
.lampread a:hover { border-bottom-color: var(--blue); }

/* Ниточка между шагами: видно, что это последовательность, а не список. */
.lampsteps li:not(:last-child)::after {
    content: ""; position: absolute; left: 13.5px; top: 32px; bottom: 6px;
    width: 1px; background: var(--line);
}

/* ==================================================================
   Симптомы: /symptoms/
   ================================================================== */
/*
 * ⚠️ Цвет карточки — это срочность, ровно как у значков на панели, и правила
 * .sym-stop / .sym-soon / .sym-watch задают именно color. Свой color в
 * .symcard забил бы его: оба селектора весом в один класс, а правило карточки
 * стоит ниже. На значках панели эта ошибка уже была — красные карточки стали
 * неотличимы от жёлтых. Цвет текста задаём отдельно у b и span.
 */
.sym-stop { color: #A3231B; }
.sym-soon { color: var(--warn); }
.sym-watch { color: var(--blue); }

.symgroup { display: flex; align-items: center; gap: 9px; margin: 30px 0 4px; }
.symgroup::before {
    content: ""; width: 12px; height: 12px; border-radius: 50%;
    background: currentColor; flex: none;
}

.symgrid { display: grid; gap: 12px; margin: 14px 0 8px; }
@media (min-width: 700px) {
    .symgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1040px) {
    .symgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.symcard {
    display: block; padding: 16px 16px 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
    border-top: 3px solid currentColor;
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), box-shadow .2s, border-color .2s;
}
.symcard:hover {
    text-decoration: none; transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(16, 26, 51, .10);
}
.symcard b { display: block; margin: 10px 0 4px; font-size: 16px; color: var(--ink); }
.symcard span { display: block; font-size: 14px; color: var(--dim); }

/* ⚠️ display: block обязателен: общее правило .mi прячет значки в шапке, и
   любой новый блок со значком обязан вернуть показ. Наступали дважды. */
.symico { display: block; width: 34px; height: 34px; color: currentColor; }
.symico svg { display: block; width: 100%; height: 100%; }
.symhead { display: flex; align-items: center; gap: 16px; margin-bottom: 10px; }
.symhead .symico { width: 54px; height: 54px; flex: none; }
/*
 * Значок признака прочерчивается при открытии — как значок лампы рядом.
 *
 * ⚠️ Контур у признака один, поэтому очередь не нужна: рисуется одним
 * движением. У ламп контуров до четырёх, и там они идут по очереди.
 *
 * ⛔ Пунктир — только в кадрах анимации (@keyframes midraw). Обычное состояние
 * целый контур: сбой оставит значок непрочерченным, а не пустым.
 */
.symhead .symico path {
    animation: midraw .55s cubic-bezier(.3, .8, .3, 1) backwards;
}
.symhead h1 { margin: 2px 0 0; }
.symlevel {
    display: inline-block; font-size: 13px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .3px; color: currentColor;
}

/*
 * ⚠️ Свой класс, а не .steps и не .lampsteps. От .steps здесь отличается
 * нумерация (там она выключена), а от .lampsteps — смысл: у значков это
 * порядок действий на дороге, здесь — порядок проверки, от дешёвого к
 * дорогому. Один класс на два смысла разъедется при первой же правке.
 */
.symsteps { counter-reset: symstep; list-style: none; margin: 12px 0 22px; padding: 0; }
.symsteps li {
    counter-increment: symstep;
    position: relative; padding: 0 0 16px 44px; color: var(--ink);
}
.symsteps li::before {
    content: counter(symstep);
    position: absolute; left: 0; top: 0;
    width: 28px; height: 28px;
    display: flex; align-items: center; justify-content: center;
    font-size: 14px; font-weight: 700; color: var(--on-blue);
    background: var(--blue-fill); border-radius: 50%;
}
.symsteps li:not(:last-child)::after {
    content: ""; position: absolute; left: 13.5px; top: 32px; bottom: 6px;
    width: 1px; background: var(--line);
}

@media (prefers-reduced-motion: reduce) {
    .symcard { transition: none; }
    .symcard:hover { transform: none; }
}

/* ==================================================================
   Разбор списка кодов: /decode/
   ================================================================== */
/*
 * ⚠️ Поле ввода крупное и на всю ширину намеренно: сюда ВСТАВЛЯЮТ, а не
 * печатают. Узкая строка в одну ячейку заставляет человека вычищать список
 * руками — и он уходит, не начав.
 */
.decform { display: flex; gap: 12px; align-items: flex-start; margin: 18px 0 6px; flex-wrap: wrap; }
.decform textarea {
    flex: 1 1 320px; min-height: 82px; resize: vertical;
    padding: 14px 16px; font: inherit; font-size: 16px; line-height: 1.45;
    color: var(--ink); background: var(--card);
    border: 1px solid var(--line); border-radius: 14px;
}
.decform textarea:focus-visible { outline: 2px solid var(--brand-orange); outline-offset: 2px; }
.decform .btn { flex: none; }

/* ---------------------------------------- коды грузовиков: SPN и FMI */
/*
 * ⛔ Своя форма, а НЕ searchbig. Тот класс означает роль поиска: голосовой
 * ввод цепляется ко всем формам с ним, и на расшифровщике появлялись кнопка
 * микрофона и подпись «Распознаёт сам браузер» — под полем для номера.
 */
.spnform { display: flex; gap: 12px; align-items: flex-end; margin: 20px 0 8px; flex-wrap: wrap; }
/* ⚠️ Поле не растягивается во всю ширину: четырёхзначное число в поле на
   тысячу точек выглядит как ошибка вёрстки, а не как поле для числа. */
.spnfield { display: flex; flex-direction: column; gap: 6px; flex: 0 1 300px; }
.spnfield.narrow { flex: 0 0 132px; }
/* ⚠️ Подпись ВИДИМАЯ и остаётся после ввода: подсказка внутри поля исчезает,
   и два числа рядом становятся безымянными. */
.spnfield label { font-size: 13px; color: var(--dim); font-weight: 600; letter-spacing: .01em; }
.spnfield input {
    padding: 13px 16px; font: inherit; font-size: 17px; font-variant-numeric: tabular-nums;
    color: var(--ink); background: var(--card);
    border: 1px solid var(--line); border-radius: 14px; width: 100%;
    transition: border-color .14s, box-shadow .14s;
}
.spnfield input:hover { border-color: var(--blue2); }
.spnfield input:focus-visible {
    outline: none; border-color: var(--blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 18%, transparent);
}
.spnform .btn { flex: none; }

/* ------------------------------------------------------- разбор VIN */
/*
 * ⚠️ Поле VIN длиннее прочих: семнадцать знаков в коротком поле не видны
 * целиком, а человек сверяет их со стеклом машины по одному.
 *
 * ⛔ Но НЕ растягивается: с «flex: 1 1» оно занимало почти всю ширину и
 * выталкивало кнопку «Проверить» за край экрана — на снимке её было не видно.
 * Ширины под номер с запасом достаточно.
 */
.spnfield.wide { flex: 0 1 480px; }
.spnfield.wide input { font-variant-numeric: tabular-nums; letter-spacing: .06em; }
/*
 * ⚠️ Ответ про контрольную цифру — своим цветом слева, а не только словами.
 * Человек у чужой машины смотрит на страницу секунду, и «сходится» должно
 * читаться до чтения.
 */
.vinres { border-left: 3px solid var(--line); }
.vinres.vinok { border-left-color: #1a7f4b; }
.vinres.vinbad { border-left-color: #d92d20; }
/* ⚠️ Заголовок ответа и первая строка стояли через полтора отступа абзаца —
   карточка выглядела разреженной. Сжимаем: это один ответ, а не две мысли. */
.vinres h2 { margin-top: 0; margin-bottom: 8px; }
.vinres > p:first-of-type { margin-top: 0; }
.vinres h3 { margin: 18px 0 8px; font-size: 16px; }
.vintable td:first-child { width: 84px; font-variant-numeric: tabular-nums; }
/* ⚠️ Выпадающий список в той же форме: браузер даёт ему свой шрифт и рамку —
   ту же беду, что была у кнопки. Приводим к виду полей рядом. */
.spnfield select {
    padding: 13px 16px; font: inherit; font-size: 17px; cursor: pointer;
    color: var(--ink); background: var(--card);
    border: 1px solid var(--line); border-radius: 14px; width: 100%;
}
.spnfield select:focus-visible {
    outline: none; border-color: var(--blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 18%, transparent);
}

/* Пара фактов об одной поломке: «что» и «как» читаются рядом, а не через
   отступ абзаца в полэкрана. */
.spnfacts { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: 4px 0 0; }
.spnfacts dt {
    font-size: 13px; font-weight: 600; color: var(--dim);
    text-transform: uppercase; letter-spacing: .04em; padding-top: 3px;
}
.spnfacts dd { margin: 0; font-size: 17px; line-height: 1.45; }
.j1939res h3 { margin: 18px 0 8px; font-size: 16px; }

/*
 * ⛔ Отступы у карточек ответа. Их не было ВОВСЕ: замерил в браузере —
 * заголовок стоял в одном пикселе от рамки, а под последней строкой зияли
 * тридцать семь. Класс .card задуман для плиток с картинкой во всю ширину и
 * потому без отступов; карточкам с текстом нужны свои.
 *
 * ⚠️ Правило ИМЕННО для карточек ответа, а не для «.card»: общее сломало бы
 * плитки главной, где картинка обязана доходить до края.
 *
 * ⚠️ Первый и последний ребёнок теряют внешние отступы: иначе к отступу
 * карточки прибавляется margin заголовка сверху и margin списка снизу, и
 * симметрия, заданная здесь, на глаз рассыпается.
 */
/* ⛔ Последний шаг не носит отступ «до следующего шага»: следующего нет.
   Именно он и давал пустоту под ответом. */
.j1939res .lampsteps li:last-child,
.vinres .lampsteps li:last-child { padding-bottom: 0; }


/*
 * ⚠️ Ширина первого столбца — ТОЛЬКО у таблицы видов отказа. Первая версия
 * правила била по «.tablewrap table», то есть по всем таблицам сайта разом:
 * и по списку файлов cookie, и по таблицам внутри статей. Правило, написанное
 * шире задачи, ломает чужое молча.
 *
 * Без ширины браузер растягивал столбец на треть экрана, и число стояло далеко
 * от своего смысла.
 */
/* ⚠️ Колонка не переносит строку и ширину держит по содержимому. Свёрнутый
   диапазон «22–30» в жёстких 56 точках ломался на две строки — видно только
   глазами на снимке, разметка при этом безупречна. */
.fmitable th:first-child, .fmitable td:first-child {
    min-width: 56px; white-space: nowrap; font-variant-numeric: tabular-nums;
}

/* Наблюдение о связке: рамка со своим цветом — это вывод, а не просто абзац. */
.declink {
    margin: 14px 0; padding: 16px 18px;
    background: var(--card); border: 1px solid var(--line);
    border-left: 3px solid var(--blue); border-radius: 14px;
}
.declink b { display: block; font-size: 17px; margin-bottom: 6px; }
.declink p { margin: 0 0 10px; color: var(--dim); }
.decchips { display: flex; gap: 8px; flex-wrap: wrap; }
.decchip {
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 13px; padding: 4px 10px; border-radius: 999px;
    background: color-mix(in srgb, var(--blue) 10%, var(--card));
    color: var(--blue); text-decoration: none;
}
.decchip:hover { background: color-mix(in srgb, var(--blue) 18%, var(--card)); text-decoration: none; }

.decgrid { display: grid; gap: 12px; margin: 14px 0 8px; }
@media (min-width: 760px) {
    .decgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.deccard {
    padding: 16px 18px; background: var(--card);
    border: 1px solid var(--line); border-radius: 16px;
}
.deccard b { display: block; margin: 8px 0 6px; font-size: 16px; line-height: 1.4; }
.deccard p { margin: 0; color: var(--dim); font-size: 15px; line-height: 1.55; }
.deccode {
    display: inline-block;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 15px; font-weight: 700; color: var(--blue); text-decoration: none;
}
a.deccard-link { display: block; text-decoration: none; color: var(--ink);
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), box-shadow .2s, border-color .2s; }
a.deccard-link:hover {
    text-decoration: none; transform: translateY(-2px); border-color: var(--blue);
    box-shadow: 0 10px 26px rgba(16, 26, 51, .10);
}
a.deccard-link b { color: var(--dim); font-weight: 500; font-size: 15px; }

@media (prefers-reduced-motion: reduce) {
    a.deccard-link { transition: none; }
    a.deccard-link:hover { transform: none; }
}

/* ==================================================================
   Общий фон внутренних страниц
   ================================================================== */
/*
 * ⚠️ Тот же приём, что на главной, но БЕЗ движения. На главной по фону идёт
 * осциллограмма — там её смотрят две секунды. Здесь читают длинный текст, и
 * любое движение за буквами мешает; остаётся одна миллиметровка прибора.
 *
 * ⚠️ Без неё внутренние страницы выглядели чужими: главная ушла вперёд, а
 * справочники остались на ровной заливке. Сетка почти неразличима (6% цвета) и
 * гаснет к краям — она не украшение, а то, что делает сайт одним целым.
 *
 * ⚠️ z-index:-1 работает потому, что фон страницы задан у body и уходит на
 * холст: слой рисуется НАД холстом и ПОД содержимым.
 */
body::before {
    content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background-image:
        linear-gradient(color-mix(in srgb, var(--blue) 6%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--blue) 6%, transparent) 1px, transparent 1px);
    background-size: 58px 58px;
    -webkit-mask-image: radial-gradient(120% 70% at 50% 0%, #000 25%, transparent 75%);
    mask-image: radial-gradient(120% 70% at 50% 0%, #000 25%, transparent 75%);
}

/* ==================================================================
   Шапка признака и лампы на узком экране
   ================================================================== */
/*
 * ⚠️ Значок, подпись срочности и заголовок стояли в одну строку всегда. На
 * телефоне подпись «ДОЕХАТЬ МОЖНО, ОТКЛАДЫВАТЬ НЕЛЬЗЯ» переносилась на три
 * строки и прижимала заголовок к правому краю — блок читался как сломанный.
 */
.symlevel, .lamplevel {
    padding: 3px 10px; border-radius: 999px;
    background: color-mix(in srgb, currentColor 12%, var(--card));
    /* ⚠️ 13px, а не 12: на двенадцати сторож мелкого текста справедливо
       ругался. Подпись срочности читают в спешке, и уменьшать её ради
       красоты — ровно тот случай, когда оформление мешает делу. */
    font-size: 13px; letter-spacing: .4px;
}
@media (max-width: 560px) {
    .symhead, .lamphead { flex-direction: column; align-items: flex-start; gap: 10px; }
    .symhead .symico, .lamphead .lampicon { width: 44px; height: 44px; }
    .symhead h1, .lamphead h1 { margin-top: 6px; }
}

/* ==================================================================
   Таблицы в статьях
   ================================================================== */
/*
 * ⚠️ Обёртка со своей прокруткой обязательна. Таблица из двух колонок на
 * телефоне не влезает, и без обёртки она растягивает ВСЮ страницу — та начинает
 * ездить вбок, и это заметно на каждом экране, а не только на таблице.
 */
.tablewrap { overflow-x: auto; margin: 16px 0 22px; -webkit-overflow-scrolling: touch; }
.ptable { border-collapse: collapse; width: 100%; min-width: 420px; font-size: 15px; }
.ptable th, .ptable td {
    text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--line);
    vertical-align: top; line-height: 1.5;
}
.ptable th { font-weight: 650; color: var(--ink); background: var(--soft); }
.ptable td { color: var(--dim); }
/* Первая колонка — то, что человек ищет глазами: она и должна читаться первой. */
.ptable td:first-child { color: var(--ink); font-weight: 500; }
.ptable tr:last-child td { border-bottom: 0; }

/* ==================================================================
   Отметка «есть разбор» в списке кодов
   ================================================================== */
/*
 * ⚠️ Отметка мелкая и приглушённая намеренно. Её задача — дать понять, где
 * написано больше, а не разделить список на «хорошие» и «плохие» коды: у
 * половины кодов разбора нет просто потому, что до них ещё не дошли руки.
 */
.codeitem { position: relative; }
.codeitem .adv {
    display: inline-block; margin-top: 6px;
    font-style: normal; font-size: 11px; letter-spacing: .3px;
    padding: 2px 8px; border-radius: 999px;
    background: color-mix(in srgb, var(--good) 12%, var(--card));
    color: var(--good);
}
.codeitem:hover .adv { background: color-mix(in srgb, var(--good) 20%, var(--card)); }
.onlyadv {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 14px; color: var(--dim); cursor: pointer; white-space: nowrap;
}
.onlyadv input { width: 16px; height: 16px; accent-color: var(--good); cursor: pointer; }
.onlyadv:hover { color: var(--ink); }

/* ================================================================== */
/*  Справочник по системам: /codes/system/                             */
/* ================================================================== */

/*
 * ⚠️ Карточка — ссылка целиком, а не заголовок внутри неё. Раздел выбирают
 * пальцем на телефоне, и попадать надо в блок, а не в строку из трёх слов.
 */
.syscards { display: grid; gap: 12px; margin: 18px 0 8px; }
@media (min-width: 700px) {
    .syscards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.syscard {
    display: flex; flex-direction: column; padding: 16px 16px 14px;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
    border-top: 3px solid var(--blue2);
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), box-shadow .2s;
}
.syscard:hover {
    text-decoration: none; transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(16, 26, 51, .10);
}
.syscard h2 { margin: 0 0 6px; font-size: 17px; color: var(--ink); }
.syscard p { margin: 0 0 12px; font-size: 14px; color: var(--dim); flex: 1 1 auto; }

/* ⚠️ Счёт прижат к низу карточки: у разделов разной длины подписи иначе
   пляшут по вертикали, и сетка выглядит сломанной. */
.sysfoot {
    margin-top: auto; padding-top: 10px; border-top: 1px dashed var(--line);
    font-size: 13px; color: var(--dim);
}
.sysfoot b { font-size: 18px; color: var(--ink); margin-right: 2px; }
.sysfoot i {
    font-style: normal; margin-left: 8px; padding: 2px 8px; border-radius: 999px;
    background: var(--soft); color: var(--blue);
}
.syscount { color: var(--dim); font-size: 14px; margin: -6px 0 14px; }
.syswhole { margin-top: 16px; }

.sysnav { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line); }
.sysnav h2 { font-size: 17px; margin: 0 0 10px; }
.syslinks { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.syslinks a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 12px; border: 1px solid var(--line); border-radius: 999px;
    background: var(--card); font-size: 14px;
}
.syslinks a:hover { text-decoration: none; border-color: var(--blue2); }
.syslinks a i { font-style: normal; color: var(--dim); font-size: 12px; }

/* Ссылка на раздел со страницы самого кода. */
.codesys { margin: 14px 0 0; font-size: 14px; color: var(--dim); }

/* ⚠️ Подсказки стоят ДО списка кодов: голый перечень из шестидесяти строк
   ничему не учит, а три честные строки читают все. */
.syshints {
    margin: 4px 0 18px; padding: 14px 16px;
    background: var(--soft); border-radius: 14px;
}
.syshints h2 { margin: 0 0 8px; font-size: 16px; }
.syshints ul { margin: 0; padding-left: 20px; }
.syshints li { margin: 5px 0; font-size: 14px; color: var(--ink); }
.sysread { margin-top: 22px; }
.sysread h2 { font-size: 17px; margin: 0 0 8px; }
.sysread ul { margin: 0; padding-left: 20px; }
.sysread li { margin: 4px 0; font-size: 14px; }

/* ⚠️ Появляется, когда разбор есть у ВСЕХ кодов и отбор «только с разбором»
   убран за ненадобностью. Молча убранный отбор выглядел бы как пропажа
   возможности — строка объясняет, почему его нет. */
.allcovered {
    margin: -4px 0 16px; padding: 9px 14px;
    background: var(--soft); border-radius: 12px;
    font-size: 14px; color: var(--ink);
}

/* ================================================================== */
/*  Свежее на главной                                                  */
/* ================================================================== */

/* ⚠️ Карточка — ссылка целиком: на телефоне попадать надо в блок, а не в
   строку заголовка. */
.freshgrid { display: grid; gap: 14px; margin-top: 18px; }
@media (min-width: 760px) {
    .freshgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.freshcard {
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
    transition: transform .2s cubic-bezier(.2, .7, .3, 1), box-shadow .2s;
}
.freshcard:hover {
    text-decoration: none; transform: translateY(-2px);
    box-shadow: 0 12px 30px rgba(16, 26, 51, .12);
}
/* ⚠️ Размеры у картинки заданы в разметке, а здесь только пропорция: без
   этого блок прыгает при загрузке, и Lighthouse честно снимает за это баллы. */
.freshcard img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.freshkind {
    align-self: flex-start; margin: 12px 14px 0; padding: 2px 9px;
    border-radius: 999px; background: var(--soft); color: var(--blue);
    font-size: 12px; letter-spacing: .02em;
}
.freshcard b { margin: 8px 14px 4px; font-size: 16px; color: var(--ink); line-height: 1.3; }
.freshcard > span:last-child { margin: 0 14px 14px; font-size: 14px; color: var(--dim); }
.freshmore { margin-top: 14px; font-size: 15px; }

/* ================================================================== */
/*  Оглавление статьи                                                  */
/* ================================================================== */

/* ⚠️ Показывается только у длинных статей — у коротких оно занимало бы
   первый экран и отодвигало сам текст. Решение принимает post_toc(). */
.toc {
    margin: 0 0 22px; padding: 14px 16px;
    background: var(--soft); border-radius: 14px;
}
.toc b { display: block; margin-bottom: 8px; font-size: 14px; color: var(--dim);
    font-weight: 600; letter-spacing: .02em; }
.toc ol { margin: 0; padding-left: 20px; }
.toc li { margin: 4px 0; font-size: 15px; }
.toc a { color: var(--blue); }

/* ⚠️ Отступ сверху у заголовка с якорем: без него переход по ссылке
   прижимает заголовок вплотную к шапке, и он оказывается под ней. */
article h2[id], article h3[id] { scroll-margin-top: 84px; }

/* «Скопировать для мастера» на разборе кодов. */
.decshare { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 16px 0 4px; }
/* ⚠️ Место под сообщение занято заранее: без этого строка появляется и
   сдвигает всё под собой — Lighthouse считает это сдвигом раскладки. */
.decsaid { min-height: 20px; font-size: 14px; color: var(--dim); }

/* ================================================================== */
/*  Полоса тем над списком записей                                     */
/* ================================================================== */

/* ⚠️ Стоит НАД карточками, а не в боковой панели: на телефоне панель уезжает
   под все девять карточек, и там её никто не видит. */
.topicbar {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    margin: 0 0 18px;
}
.topicbar b { font-size: 14px; color: var(--dim); font-weight: 600; margin-right: 2px; }
.topicbar a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
    background: var(--card); font-size: 14px; color: var(--ink); text-decoration: none;
}
.topicbar a:hover { border-color: var(--blue2); color: var(--blue); text-decoration: none; }
/* Число записей в теме — тише названия: оно подсказка, а не заголовок. */
.topicbar a i { font-style: normal; font-size: 12px; color: var(--dim); }

/* Ссылка на руководство рядом с кнопкой «скопировать для мастера». */
.decguide { margin: 6px 0 0; font-size: 14px; }

/* ================================================================== */
/*  Ряд ссылок кнопками                                                */
/* ================================================================== */

/* ⚠️ Строка вида «Реквизиты · Оплата · Контакты» на телефоне читается плохо:
   точки сливаются со словами, попасть пальцем в одну ссылку трудно, а внизу
   раздела она выглядит прижатой. Кнопки решают всё сразу. */
.linkrow { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 0; }
.linkrow a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 9px 16px; border: 1px solid var(--line); border-radius: 999px;
    background: var(--card); color: var(--ink); font-size: 15px; text-decoration: none;
    transition: border-color .15s, color .15s, transform .15s;
}
.linkrow a:hover {
    border-color: var(--blue2); color: var(--blue); text-decoration: none;
    transform: translateY(-1px);
}
/* ⚠️ Внизу раздела ряду нужен воздух: без него он прижат к краю. */
.linkrow.last { margin-bottom: 8px; }

/* ⚠️ Подпись руководства со значками — как время чтения в блоге. Две пары
   «значок + число» не должны слипаться, поэтому свой промежуток. */
.hmeta .hmi { display: inline-flex; align-items: center; gap: 5px; margin-right: 14px; }
.hmeta .hmi:last-child { margin-right: 0; }

/* ================================================================== */
/*  Подсказки поиска под полем                                         */
/* ================================================================== */

.navfind { position: relative; }
.sugbox {
    position: absolute; top: calc(100% + 6px); right: 0; z-index: 90;
    width: min(420px, calc(100vw - 32px));
    max-height: min(70vh, 460px); overflow-y: auto;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 18px 44px rgba(16, 26, 51, .16); padding: 6px;
}
.sughead {
    padding: 8px 10px 4px; font-size: 12px; letter-spacing: .03em;
    text-transform: uppercase; color: var(--dim);
}
.sugitem {
    display: block; padding: 8px 10px; border-radius: 10px;
    color: var(--ink); text-decoration: none;
}
.sugitem b { display: block; font-size: 15px; font-weight: 600; }
.sugitem span { display: block; font-size: 13px; color: var(--dim); }
/* ⚠️ Наведение и выбор стрелками красим ОДИНАКОВО: иначе человек не понимает,
   что именно откроется по Enter. */
.sugitem:hover, .sugitem.on { background: var(--soft); text-decoration: none; }

/*
 * Последние запросы человека — скруглёнными плашками.
 *
 * ⚠️ Намеренно НЕ похожи на строки находок (.sugitem): это не результат, а
 * напоминание. Одинаковый вид заставлял бы читать их как найденное по пустому
 * запросу.
 */
.sugrecent { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 14px 12px; }
.sugchip {
    display: inline-block; max-width: 100%; padding: 6px 12px;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--soft); color: var(--fg);
    font-size: 13px; font-weight: 600; line-height: 1.2;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: border-color .16s, color .16s, background .16s;
}
.sugchip:hover, .sugchip.on {
    border-color: var(--blue2); color: var(--blue);
    background: var(--card); text-decoration: none;
}

.sugempty { padding: 14px 10px; font-size: 14px; color: var(--dim); }
/* «Все результаты» — кнопка внизу списка, всегда на месте. */
.sugall {
    display: block; margin-top: 6px; padding: 10px; border-radius: 10px;
    background: var(--soft); color: var(--blue); text-align: center;
    font-size: 14px; font-weight: 600; text-decoration: none;
}
.sugall:hover, .sugall.on { background: var(--blue-fill); color: var(--on-blue);
    text-decoration: none; }
@media (max-width: 700px) {
    .sugbox { right: auto; left: 0; width: calc(100vw - 24px); }
}


/* ================================================================== */
/*  Шапка выехавшего меню на телефоне                                  */
/* ================================================================== */

/* ⚠️ На большом экране её нет: там название и так в шапке страницы. */
.navhead { display: none; }
@media (max-width: 1120px) {
    /* ⚠️ order:-2 поднимает шапку выше переключателя языка: он объявлен в
       разметке первым, а видеть человек должен сначала «где я». */
    .navhead {
        order: -2; display: flex; align-items: center; gap: 10px;
        padding: 2px 0 14px; margin-bottom: 10px;
        border-bottom: 1px solid var(--line);
    }
    .navbrand {
        display: flex; align-items: center; gap: 9px;
        font-weight: 750; font-size: 19px; letter-spacing: -.3px; color: var(--ink);
    }
    .navbrand .name span { color: var(--blue); }
    .navclose {
        margin-left: auto; width: 36px; height: 36px; flex: none;
        border-radius: 11px; border: 1px solid var(--line); background: var(--card);
        color: var(--dim); display: flex; align-items: center; justify-content: center;
        cursor: pointer;
    }
    .navclose svg { width: 18px; height: 18px; }
}

/* ================================================================== */
/*  Кнопка «наверх»                                                    */
/* ================================================================== */

/* ⚠️ Слева от края держим расстояние, чтобы не наезжать на содержимое, и
   ниже — чтобы не спорить с прилипшей шапкой. */
.totop {
    position: fixed; right: 18px; bottom: 22px; z-index: 60;
    width: 46px; height: 46px; border-radius: 50%;
    border: 1px solid var(--line); background: var(--card); color: var(--blue);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    box-shadow: 0 10px 26px rgba(16, 26, 51, .16);
    transition: transform .15s, box-shadow .15s, border-color .15s;
}
.totop svg { width: 22px; height: 22px; }
.totop:hover { transform: translateY(-2px); border-color: var(--blue2);
    box-shadow: 0 14px 32px rgba(16, 26, 51, .2); }
/* ⚠️ [hidden] сам по себе не прячет элемент с display:flex — нужен явный
   запрет, иначе кнопка видна всегда. */
.totop[hidden] { display: none; }
@media (max-width: 700px) {
    .totop { right: 14px; bottom: 16px; width: 44px; height: 44px; }
}

/* ⚠️ Больше воздуха под подвалом НА ТЕЛЕФОНЕ. На широком экране 40 пикселей
   выглядят нормально, а на телефоне значки оплаты переносятся на три ряда, и
   последний из них оказывается прижат к краю. Плюс запас под панель жестов:
   у части телефонов внизу живёт системная полоска. */
@media (max-width: 700px) {
    footer { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
}

/* ================================================================== */
/*  Правила чтения списка кодов на /decode/                            */
/* ================================================================== */

.decrules { display: grid; gap: 12px; margin: 16px 0 8px; }
@media (min-width: 760px) { .decrules { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.decrule {
    display: flex; gap: 14px; padding: 16px;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
}
/* Номер правила — крупный и тихий: он про порядок, а не про важность. */
.decrule > b {
    flex: none; width: 30px; height: 30px; border-radius: 10px;
    background: var(--soft); color: var(--blue);
    display: flex; align-items: center; justify-content: center;
    font-size: 15px; font-weight: 700;
}
.decrule h3 { margin: 2px 0 6px; font-size: 16px; line-height: 1.35; }
.decrule p { margin: 0; font-size: 14px; color: var(--dim); }

/* ⚠️ «Все …» в боковой панели: без своего вида это ЧЕТВЁРТЫЙ пункт списка,
   неотличимый от трёх названий выше. Отделяем чертой и уводим вправо. */
.sidebox a.sideall {
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
    border-bottom: none;
    font-weight: 600;
    color: var(--ink);
}
.sidebox a.sideall::after { content: " \2192"; opacity: .55; }
.sidebox a.sideall:hover::after { opacity: 1; }

/* ⚠️ Знак в подвале — ссылка на главную. Показываем это курсором и лёгким
   подъёмом: без признака нажимаемости по нему не нажимают. */
.fhome { display: inline-block; line-height: 0; transition: transform .16s; }
.fhome:hover { transform: translateY(-1px); }
.fhome:focus-visible { outline: 2px solid var(--blue2); outline-offset: 3px; border-radius: 6px; }
