/*
 * Тема «Дневник» для Nex1on — для сайта, который пишут.
 *
 * Родилась из темы, которую друг когда-то сделал для своего блога о
 * нейросетях: светлый лист, зелёный акцент, карточки с мягкой тенью,
 * крупные заголовки. Сайт закрылся, а облик остался — и он оказался
 * ровно тем, чего у нас не было: «Обычная» тёмная и техническая,
 * «Бумага» строгая и с засечками, «Витрина» кричит про товар. Для
 * новостей и статей нужен лист, на который приятно смотреть подолгу.
 *
 * Что взято оттуда: зелёный как единственный цветной, скруглённые
 * карточки, воздух между записями, спокойный рубленый шрифт.
 *
 * Что не взято: там на каждую страницу был свой файл стилей и ни одной
 * переменной — цвет темы жил в двадцати местах сразу. Здесь, как и в
 * остальных наших темах, все настраиваемые значения стоят наверху
 * переменными, и ниже по файлу нет ни одного вписанного руками цвета:
 * админка подставляет их из theme.json, и тема перекрашивается целиком
 * из панели, а не поиском по файлу.
 *
 * Шаблонов в папке темы нет ни одного — только theme.json, этот файл и
 * значок. Вся разметка общая, из ядра: модули рисуют своими именами и
 * про тему не знают ничего.
 */

:root {
    /*
     * Светлая тема или тёмная — говорим браузеру прямо.
     *
     * От этого зависит всё, что браузер рисует сам: раскрытый список
     * «select», календарь, подсказка сохранённого пароля, полосы
     * прокрутки. Странице эти части не принадлежат, и ни одно наше
     * правило их не перекрасит — без этой строки они приезжают не в тон
     * теме и выглядят как чужие.
     */
    color-scheme: light;

    /* ---- то, что настраивается из админки ---- */
    --color-accent: #1a7f5a;
    --color-accent-soft: #0f5f8a;
    --color-background: #f6f7f9;
    --color-surface: #ffffff;
    --color-text: #16202b;

    --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-heading: var(--font-body);

    --radius: 12px;
    --logo-height: 36px;
    --content-width: 1020px;

    /* ---- производные: считаются от настраиваемых ---- */
    --color-muted: color-mix(in srgb, var(--color-text) 84%, transparent);
    --color-faint: color-mix(in srgb, var(--color-text) 70%, transparent);
    --color-line: color-mix(in srgb, var(--color-text) 14%, transparent);
    --color-line-strong: color-mix(in srgb, var(--color-text) 28%, transparent);
    --color-tint: color-mix(in srgb, var(--color-accent) 6%, var(--color-surface));

    --color-danger: #b3261e;
    --color-success: #1a6f43;
    --color-warning: var(--color-accent-soft);

    --font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;

    --gap: 2.4rem;

    /*
     * Тень мягкая и в два слоя: близкая даёт карточке край, дальняя —
     * ощущение, что она лежит на листе, а не нарисована на нём. Так было
     * в теме, из которой эта выросла, и это её главная примета: записи
     * разделяют не линии, а воздух между приподнятыми карточками.
     */
    --shadow-panel:
        0 1px 2px color-mix(in srgb, var(--color-text) 6%, transparent),
        0 8px 24px color-mix(in srgb, var(--color-text) 7%, transparent);

    /* Тень под тем, что человек трогает: кнопка, поднятая карточка. */
    --shadow-lift:
        0 2px 4px color-mix(in srgb, var(--color-text) 8%, transparent),
        0 12px 32px color-mix(in srgb, var(--color-text) 10%, transparent);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

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

body {
    margin: 0;
    background: var(--color-background);
    color: var(--color-text);
    /*
     * Строка чуть крупнее и просторнее обычного: эту тему ставят те, у
     * кого на странице текст, а не таблица, и читают её подолгу.
     */
    font: 1.09rem/1.75 var(--font-body);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
    margin: 0 0 0.6em;
}

h1 { font-size: clamp(1.9rem, 1.4rem + 2vw, 2.6rem); }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.2rem; }

p { margin: 0 0 1em; }

a {
    color: var(--color-accent);
    /* Подчёркивание оставлено нарочно: на светлом фоне цвет один ссылку
       не выделяет, а людям с нарушенным цветовосприятием — тем более. */
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1px;
}

a:hover { color: var(--color-accent-soft); }

img { max-width: 100%; height: auto; }

hr {
    border: 0;
    border-top: 1px solid var(--color-line);
    margin: var(--gap) 0;
}

blockquote {
    margin: 1.5em 0;
    padding-inline-start: 1.2em;
    border-inline-start: 3px solid var(--color-line-strong);
    color: var(--color-muted);
    font-style: italic;
}

code, pre, .mono { font-family: var(--font-mono); font-size: 0.9em; }

:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

::selection {
    background: color-mix(in srgb, var(--color-accent) 22%, transparent);
}

/* ------------------------------------------------------------- каркас */

.wrap {
    width: min(100% - 2.5rem, var(--content-width));
    margin-inline: auto;
}

.skip {
    position: absolute;
    left: -9999px;
}

.skip:focus {
    left: 1rem;
    top: 1rem;
    z-index: 20;
    padding: 0.6rem 1rem;
    background: var(--color-accent);
    color: var(--color-surface);
    border-radius: var(--radius);
}

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

.site-head {
    position: sticky;
    top: 0;
    z-index: 10;
    /*
     * Шапка непрозрачная, без размытия. Полупрозрачная шапка — приём
     * тёмного оформления: там просвечивающее пятно читается как стекло.
     * На светлом фоне сквозь неё лезет текст, и получается грязь, а не
     * стекло. Бумага не просвечивает.
     */
    background: var(--color-background);
    border-bottom: 1px solid var(--color-line);
}

.site-head .wrap {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    min-height: calc(var(--logo-height) + 1.5rem);
    flex-wrap: wrap;
    padding-block: 0.5rem;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    color: inherit;
    text-decoration: none;
}

.brand-mark {
    display: grid;
    place-items: center;
    width: var(--logo-height);
    height: var(--logo-height);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
}

.brand-name {
    font-family: var(--font-heading);
    font-size: 1.2rem;
    font-weight: 700;
}

.nav {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    font-size: 0.98rem;
}

.nav a {
    color: var(--color-muted);
    text-decoration: none;
    padding-block: 0.35rem;
    /* Место под будущую черту занято сразу, иначе строка прыгает. */
    border-bottom: 2px solid transparent;
}

.nav a:hover { color: var(--color-text); }

.nav a.is-active {
    color: var(--color-text);
    border-bottom-color: var(--color-accent);
}

.nav__split { margin-inline-start: auto; }

/* ------------------------------------------------- значки в строке шапки

   Место для мелочи рядом с языками: корзина и всё, что появится дальше.
   Ряд не переносится и не сжимается — значок в шапке не должен уезжать под
   логотип на узком экране. */
.head-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex: 0 0 auto;
}

/* Значок корзины: тележка, а на плече число. Пустая корзина приглушена, но
   не исчезает — место, где корзина «то есть, то нет», не запоминается. */
.cart-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.35rem;
    height: 2.35rem;
    border-radius: 50%;
    color: inherit;
    opacity: 0.65;
    text-decoration: none;
    transition: opacity 0.15s ease, background-color 0.15s ease;
}

.cart-icon:hover,
.cart-icon:focus-visible { opacity: 1; background: var(--color-hover, rgba(127, 127, 127, .16)); }

.cart-icon.is-full { opacity: 1; }

.cart-icon__pic { display: block; }

.cart-icon__count {
    position: absolute;
    top: 0.05rem;
    inset-inline-end: 0.05rem;
    min-width: 1.05rem;
    padding: 0 0.22rem;
    border-radius: 999px;
    background: var(--color-accent, #4fd0ff);
    color: var(--color-on-accent, #06121a);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.15rem;
    text-align: center;
}

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

.langs {
    display: flex;
    gap: 0.3rem;
    padding-inline-start: 0.75rem;
    border-inline-start: 1px solid var(--color-line);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    text-transform: uppercase;
}

.lang {
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    color: var(--color-faint);
    text-decoration: none;
}

.lang:hover { color: var(--color-text); }

.lang.is-active {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

/* --------------------------------------------------------- содержимое */

main {
    display: grid;
    gap: var(--gap);
    padding-block: var(--gap) calc(var(--gap) * 1.5);
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 62rem) {
    /* Боковая колонка появляется, только когда в неё что-то поставили. */
    main.has-side {
        grid-template-columns: minmax(0, 1fr) minmax(0, 18rem);
        align-items: start;
    }
}

.main-col { min-width: 0; }

.region { min-width: 0; }
.region--header { padding-top: 1.25rem; }
.region--before { margin-bottom: var(--gap); }
.region--after  { margin-top: var(--gap); }
.region--footer { margin-bottom: 1.25rem; }

.side-col {
    position: sticky;
    top: calc(var(--logo-height) + 3rem);
    display: grid;
    gap: 1.25rem;
}

/* ------------------------------------------------------------- панели */

.panel {
    padding: 1.6rem;
    background: var(--color-surface);
    border: 0;
    border-radius: var(--radius);
    box-shadow: var(--shadow-panel);
}

.panel--tight { padding: 1.1rem 1.25rem; }

.hero {
    margin-bottom: var(--gap);
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--color-line);
}

.hero h1 { margin-bottom: 0.3em; }

.eyebrow,
.hero__eyebrow {
    display: block;
    margin-bottom: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-faint);
}

.lead {
    font-size: 1.15rem;
    color: var(--color-muted);
}

.stack { display: grid; gap: 1.25rem; }

/* ------------------------------------------------------- лента записей

   Общий словарь: этими же именами рисуют «Новости», «Загрузки» и записи
   разделов. Тема отвечает за вид, модуль — только за содержание.
   ------------------------------------------------------------------ */

.feed { display: grid; gap: 1.25rem; }

.feed-item {
    padding: 1.25rem 1.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
}

.feed-item:hover { border-color: var(--color-line-strong); }

@media (min-width: 42rem) {
    /* С обложкой — две колонки, но только там, где для них есть место. */
    .feed-item:has(.feed-item__cover) {
        display: grid;
        grid-template-columns: 12rem minmax(0, 1fr);
        gap: 1.25rem;
        align-items: start;
    }
}

.feed-item__cover { display: block; overflow: hidden; border-radius: var(--radius); }

.feed-item__cover img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}

.feed-item__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-faint);
}

.feed-item__pin { color: var(--color-accent-soft); }

.feed-item__title { margin: 0 0 0.4rem; font-size: 1.3rem; }
.feed-item__title a { text-decoration: none; }
.feed-item__title a:hover { text-decoration: underline; }

.feed-item__lead { margin: 0 0 0.6rem; color: var(--color-muted); }
.feed-item__more { font-size: 0.92rem; }

.cover { display: block; border-radius: var(--radius); overflow: hidden; }

/* ------------------------------------------------------- карточки, блоки */

.cards {
    display: grid;
    gap: 1.25rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/*
 * Карточку держит тень, а не рамка. Рамка вокруг тени — это два края у
 * одного предмета: на светлом фоне видно оба, и карточка выглядит
 * обведённой. Здесь она просто чуть приподнята над листом.
 */
.card {
    padding: 1.35rem;
    background: var(--color-surface);
    border: 0;
    border-radius: var(--radius);
    box-shadow: var(--shadow-panel);
    transition: box-shadow 0.18s ease, transform 0.18s ease;
}

/*
 * Карточка, по которой можно нажать, чуть приподнимается под указателем.
 * Не «оживает», а именно приподнимается: полтора миллиметра и тень —
 * этого хватает, чтобы палец понял, что тут ссылка.
 */
.card:hover,
.card:focus-within {
    box-shadow: var(--shadow-lift);
    transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
    .card { transition: none; }
    .card:hover, .card:focus-within { transform: none; }
}

.card h3 { margin-bottom: 0.4rem; }

.block {
    padding: 1.2rem 1.3rem;
    background: var(--color-surface);
    border: 0;
    border-radius: var(--radius);
    box-shadow: var(--shadow-panel);
}

/*
 * Заголовок блока читается как заголовок, а не как ярлык. Мелкие
 * прописные вразрядку уместны там, где подпись служебная; здесь в блоках
 * стоят «Последние новости» и «Новинки» — это названия разделов, и
 * шептать их незачем.
 */
.block__title {
    margin: 0 0 0.85rem;
    font-family: var(--font-heading);
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    text-transform: none;
    color: var(--color-text);
}

.block__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.75rem;
}

.block__list li { padding-bottom: 0.75rem; border-bottom: 1px solid var(--color-line); }
.block__list li:last-child { padding-bottom: 0; border-bottom: none; }

.block__note { display: block; font-size: 0.8rem; color: var(--color-faint); }
.block__empty { color: var(--color-faint); margin: 0; }
.block__more { margin: 0.75rem 0 0; font-size: 0.9rem; }

/* --------------------------------------------------------------- формы */

.field { margin-bottom: 1.1rem; }

.field label,
.label {
    display: block;
    margin-bottom: 0.35rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-faint);
}

/* У флажка подпись обычная: это фраза, а не название прибора. */
.check label,
.field label.check {
    font: inherit;
    text-transform: none;
    letter-spacing: normal;
    color: inherit;
}

.check {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 1.1rem;
}

.input {
    width: 100%;
    padding: 0.6rem 0.75rem;
    background: var(--color-surface);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    color: var(--color-text);
    font: inherit;
}

.input:focus {
    border-color: var(--color-accent);
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 18%, transparent);
}

.input[aria-invalid="true"] { border-color: var(--color-danger); }

textarea.input { min-height: 8rem; resize: vertical; }

.field__hint { display: block; margin-top: 0.35rem; font-size: 0.85rem; color: var(--color-faint); }
.field__error { display: block; margin-top: 0.35rem; font-size: 0.85rem; color: var(--color-danger); }

.form-page {
    max-width: 27rem;
    margin-inline: auto;
    padding: 1.75rem;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-panel);
}

.form-page__head { margin-bottom: 1.25rem; text-align: center; }

.form-links {
    margin-top: 1.25rem;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: center;
    font-size: 0.9rem;
}

/* -------------------------------------------------------------- кнопки */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.6rem 1.2rem;
    background: var(--color-accent);
    color: var(--color-surface);
    border: 1px solid var(--color-accent);
    border-radius: var(--radius);
    font: inherit;
    font-size: 0.95rem;
    cursor: pointer;
    text-decoration: none;
}

.button {
    /* Кнопка скруглена сильнее карточки: она меньше, и на ней это видно. */
    border-radius: 999px;
    padding-inline: 1.35rem;
    font-weight: 600;
    box-shadow: 0 1px 2px color-mix(in srgb, var(--color-text) 10%, transparent);
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

.button:hover {
    background: color-mix(in srgb, var(--color-accent) 85%, black);
    color: var(--color-surface);
    box-shadow: var(--shadow-lift);
}

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

.button--wide { width: 100%; }

.button--ghost {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-line-strong);
}

.button--ghost:hover {
    background: var(--color-tint);
    color: var(--color-text);
}

.button--danger { background: var(--color-danger); border-color: var(--color-danger); }
.button--small { padding: 0.35rem 0.7rem; font-size: 0.85rem; }

/* ----------------------------------------------------------- сообщения */

.alerts { display: grid; gap: 0.75rem; margin-bottom: var(--gap); }

.alert {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-inline-start: 3px solid var(--color-line-strong);
    border-radius: var(--radius);
}

.alert__mark { font-weight: 700; }

.alert--success { border-inline-start-color: var(--color-success); }
.alert--success .alert__mark { color: var(--color-success); }

.alert--error { border-inline-start-color: var(--color-danger); }
.alert--error .alert__mark { color: var(--color-danger); }

.alert--warning { border-inline-start-color: var(--color-warning); }
.alert--warning .alert__mark { color: var(--color-warning); }

/* ------------------------------------------------------------- таблицы */

.table-scroll {
    /* Таблица не ломает страницу: она прокручивается внутри себя. */
    overflow-x: auto;
    margin-inline: -1px;
}

.table {
    width: 100%;
    border-collapse: collapse;
}

.table th,
.table td {
    padding: 0.6rem 0.75rem;
    text-align: start;
    border-bottom: 1px solid var(--color-line);
    vertical-align: top;
}

.table th {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-faint);
    font-weight: 400;
}

.table tr:last-child td { border-bottom: none; }

.table--card,
.table--cards {
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
}

.props {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.35rem 1rem;
    margin: 0 0 0.9rem;
    align-items: baseline;
}

.props dt {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-faint);
}

.props dd { margin: 0; }

/* --------------------------------------------------------------- метки */

.tag {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border: 1px solid var(--color-line-strong);
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-muted);
    white-space: nowrap;
}

.tag--now {
    border-color: var(--color-success);
    color: var(--color-success);
}

/*
 * «Состояние» на главной — не значок, а раздел с парами «что: сколько».
 * Имя короткое и обманчивое: я сам принял его за метку и покрасил
 * кружочком. Разметку надо смотреть, а не угадывать по имени.
 */
.state dl {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    gap: 1rem;
    margin: 0;
    padding: 1.25rem 1.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
}

.state dt {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-faint);
}

.state dd {
    margin: 0.3rem 0 0;
    font-family: var(--font-mono);
    font-size: 0.95rem;
}

/* -------------------------------------------------------------- вкладки */

.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-bottom: var(--gap);
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--color-line);
}

.tabs__item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding-bottom: 0.5rem;
    margin-bottom: -0.5rem;
    color: var(--color-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}

.tabs__item:hover { color: var(--color-text); }

.tabs__item.is-on {
    color: var(--color-text);
    border-bottom-color: var(--color-accent);
}

.tabs__count { font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-faint); }

/* -------------------------------------------------------------- листание */

.pager {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    margin-top: var(--gap);
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-line);
}

.pager__link {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    text-decoration: none;
}

.pager__now {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--color-accent);
    border-radius: var(--radius);
    color: var(--color-accent);
}

/* ----------------------------------------------------------- обсуждения

   Тот же словарь, что и у обычной темы: модуль комментариев ничего про
   оформление не знает и рисует одну и ту же разметку в обеих.
   ------------------------------------------------------------------ */

.comments { margin-top: var(--gap); }
.comments__list { margin: 1.25rem 0 var(--gap); }

.comment { padding: 1rem 1.25rem; }

.comment--reply {
    margin-inline-start: 1.75rem;
    border-inline-start: 3px solid var(--color-line-strong);
}

.comment__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0 0 0.4rem;
}

.comment__body { overflow-wrap: anywhere; }

.comments__form { margin-top: 1.25rem; }

/* «display» сильнее встроенного правила для hidden — прячем явно. */


.comments__answering {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.75rem;
    color: var(--color-muted);
}

/* --------------------------------------------------------------- профиль */

.profile-grid {
    display: grid;
    gap: var(--gap);
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 52rem) {
    .profile-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.identity {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: var(--gap);
}

.identity__mark {
    display: grid;
    place-items: center;
    width: 3.25rem;
    height: 3.25rem;
    border: 1px solid var(--color-line-strong);
    border-radius: 50%;
    font-family: var(--font-heading);
    font-size: 1.3rem;
}

.identity__name { margin: 0; font-size: 1.35rem; }
.identity__meta { margin: 0; color: var(--color-faint); font-size: 0.9rem; }

/* ---------------------------------------------------------------- ошибки */

.error { text-align: center; padding-block: 4rem; }

.error-code {
    display: block;
    font-family: var(--font-mono);
    font-size: clamp(3rem, 2rem + 6vw, 5rem);
    line-height: 1;
    color: var(--color-line-strong);
}

.error-ref { font-family: var(--font-mono); font-size: 0.8rem; color: var(--color-faint); }

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

.site-foot {
    margin-top: auto;
    padding-block: var(--gap);
    border-top: 1px solid var(--color-line);
    color: var(--color-faint);
    font-size: 0.9rem;
}

.site-foot__line {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
    align-items: baseline;
}

.site-foot p { margin: 0; }

.site-foot .engine {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
}

/* --------------------------------------------------------------- форум

   Ещё часть общего словаря темы, а не собственность модуля. Форум
   привозит разметку с этими именами и ни одного своего стиля — тема
   решает, как это выглядит.
   ------------------------------------------------------------------- */

/* Строка действий: «Новая тема», кнопки модератора. */
.forum-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: var(--gap);
}

/* Каждая кнопка модератора — своя форма; без этого они встают столбиком. */
.forum-bar form { margin: 0; }

.forum-section__last,
.forum-topic__last {
    display: grid;
    gap: 0.15rem;
    align-content: center;
    padding-inline-start: 1rem;
    border-inline-start: 1px solid var(--color-line);
    font-size: 0.9rem;
}

@media (min-width: 48rem) {
    /* Раздел и последний в нём разговор — в две колонки. */
    .forum-section {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 16rem);
        gap: 1rem;
        align-items: start;
    }

    .forum-topic {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 11rem);
        gap: 1rem;
        align-items: start;
    }
}

.forum-topic--pinned { border-color: var(--color-line-strong); }

.forum-post__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0 0 0.5rem;
}

/* Длинная ссылка без пробелов не должна расталкивать страницу. */
.forum-post__body { overflow-wrap: anywhere; }

.forum-post__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    margin: 0.75rem 0 0;
}

.forum-post__actions form { margin: 0; }

/* «Убрать» — действие, а не ссылка: кнопка, притворяющаяся ссылкой,
   потому что действие требует POST, а выглядеть должно скромно. */
.forum-post__remove {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-danger);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.forum-post__remove:hover { text-decoration: underline; }

.forum-reply { margin-top: var(--gap); }

@media (max-width: 40rem) {
    .forum-section__last,
    .forum-topic__last {
        padding-inline-start: 0;
        border-inline-start: none;
        padding-top: 0.6rem;
        border-top: 1px solid var(--color-line);
    }
}

/* ------------------------------------------------------------- магазин

   Продолжение общего словаря темы. Модуль магазина привозит разметку с
   этими именами и ни одного своего стиля.
   ------------------------------------------------------------------- */

.goods {
    display: grid;
    gap: 1.25rem;
    /*
     * Сколько товаров в ряд — задаёт владелец в «Оформлении».
     *
     * Число не наше: у одного магазина десять крупных вещей, у другого
     * триста мелких, и «правильной» ширины карточки не существует. Запасное
     * значение стоит на случай темы без этой настройки — витрина не должна
     * рассыпаться оттого, что переменной не нашлось.
     */
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--good-min, 16rem)), 1fr));
}

.good {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    box-shadow: var(--shadow-panel);
}

.good:hover { border-color: var(--color-line-strong); }

.good__cover { display: block; overflow: hidden; }

.good__cover img {
    display: block;
    width: 100%;
    /*
     * Форма снимка и что делать с лишним — тоже настройка.
     *
     * «Обрезать» годится снимкам вещей, «вписать целиком» — рисункам и
     * упаковке, где важны края: обрезанная коробка выглядит браком. Форма
     * одна на все карточки, иначе ряды разъезжаются по высоте.
     */
    aspect-ratio: var(--good-ratio, 4 / 3);
    object-fit: var(--good-fit, cover);
}

.good__body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem 1.1rem 1.2rem;
    /* кнопка прижимается вниз, чтобы карточки разной высоты не разъезжались */
    flex: 1 1 auto;
}

.good__title { margin: 0; font-size: 1.05rem; }
.good__title a { text-decoration: none; }

.good__lead { margin: 0; color: var(--color-muted); font-size: 0.92rem; }

.good__body .buy { margin-top: auto; }

/* Цена: нынешняя крупно, старая рядом и мельче. */
.price {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0;
}

.price__now { font-size: 1.2rem; font-weight: 700; }
.price__old { color: var(--color-faint); font-size: 0.95rem; }

.buy { margin: 0; }

/* Карточка товара: картинка и покупка рядом, на узком — друг под другом. */
.good-page {
    display: grid;
    gap: var(--gap);
    grid-template-columns: minmax(0, 1fr);
    margin-bottom: var(--gap);
}

@media (min-width: 48rem) {
    .good-page { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); align-items: start; }
}

.good-page__cover img { display: block; width: 100%; }

/* Значки на снимке товара: скидка и новинка.

   Цену человек читает, когда уже выбрал карточку глазами; значок работает
   раньше — он виден при беглом взгляде на ряд и решает, куда взгляд
   пойдёт. Кладём в угол картинки, а не в текст: в тексте он стал бы ещё
   одной строкой, которую надо прочесть. */
/* Витрина магазина на широкой части страницы.

   Карточки те же, что в каталоге, — меняется только рамка вокруг: заголовок
   со ссылкой в магазин и ряд, который на телефоне становится столбиком, а на
   широком экране идёт в четыре карточки. */
.showcase { margin-bottom: var(--gap); }

/* Лента новостей куском на широкой части страницы.

   Не карточки: запись — это текст, и мельчить её снимком незачем. Строки
   разделяет черта, а не рамка: так читается как лента, а не как набор
   плиток. */
/* Куски модулей на главной: единый ритм.

   Их кладут разные модули — новости, магазин, форум, загрузки, — и без
   общего правила каждый жил бы со своими отступами. Тогда главная читается
   как склейка чужих страниц: заголовки на разной высоте, промежутки
   вразнобой. Здесь у всех одна шапка и один шаг между кусками. */
.home-block { margin-bottom: var(--gap); }
.home-block:last-child { margin-bottom: 0; }

.home-block__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.9rem;
}

.home-block__title { margin: 0; font-size: 1.3rem; }
.home-block__title a { text-decoration: none; }
.home-block__all { white-space: nowrap; font-size: 0.95rem; }

/* Обсуждения и файлы: список без точек, строки разделены чертой — тот же
   приём, что у ленты новостей, чтобы куски не спорили друг с другом. */
.home-talks__items,
.home-files__items {
    display: grid;
    gap: 0.9rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.home-talks__item,
.home-files__item {
    display: grid;
    gap: 0.25rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--color-line, rgba(127, 127, 127, .2));
}

.home-talks__item:last-child,
.home-files__item:last-child { padding-bottom: 0; border-bottom: 0; }

.home-talks__name,
.home-files__name { font-size: 1.05rem; text-decoration: none; }

.home-talks__meta,
.home-files__meta {
    margin: 0;
    font-size: 0.85rem;
    opacity: 0.72;
}

.home-feed { margin-bottom: var(--gap); }

.home-feed__items { display: grid; gap: 1.1rem; }

.home-feed__item {
    display: grid;
    gap: 0.3rem;
    padding-bottom: 1.1rem;
    border-bottom: 1px solid var(--color-line, rgba(127, 127, 127, .2));
}

/* У последней записи черты нет: она отделяла бы ленту от того, что ниже,
   а это разные вещи. */
.home-feed__item:last-child { padding-bottom: 0; border-bottom: 0; }

.home-feed__when {
    margin: 0;
    font-size: 0.82rem;
    opacity: 0.7;
}

.home-feed__name { margin: 0; font-size: 1.12rem; line-height: 1.35; }
.home-feed__name a { text-decoration: none; }
.home-feed__lead { margin: 0; opacity: 0.85; }


/* На витрине карточки уже, чем в каталоге: их задача — позвать в магазин,
   а не заменить его. Меньше 12rem не даём: снимок станет маркой. */
.goods--showcase {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 12rem), 1fr));
}

/* На телефоне витрина идёт по две карточки в ряд.

   В каталоге карточка во всю ширину уместна: человек пришёл выбирать, и
   снимок ему нужен крупный. Витрина на главной — приглашение, а не выбор:
   четыре карточки во всю ширину занимают два экрана, и до остального
   содержимого страницы никто не долистает. */
@media (max-width: 48rem) {
    .goods--showcase {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.7rem;
    }

    .goods--showcase .good__body { padding: 0.6rem 0.7rem; }
    .goods--showcase .good__title { font-size: 0.95rem; }
    .goods--showcase .good__lead { display: none; }
}


.good__cover,
.good-page__cover { position: relative; }

.good__mark {
    position: absolute;
    top: 0.6rem;
    inset-inline-start: 0.6rem;
    z-index: 1;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: 0.01em;
    pointer-events: none;
}

/* Скидка — цветом «выгоды», новинка — спокойным: одна зовёт покупать
   сейчас, вторая просто сообщает. */
.good__mark--off { background: var(--color-ok, #2f8f5b); color: #fff; }

.good__mark--new {
    background: var(--color-surface, rgba(20, 24, 32, .82));
    color: var(--color-text, inherit);
    border: 1px solid var(--color-border, rgba(127, 127, 127, .35));
}


.good-page__buy { display: grid; gap: 0.75rem; align-content: start; }

/* Галерея товара: большая картинка и ряд миниатюр под ней.

   Ряд прокручивается вбок, а не переносится: на телефоне перенос делает из
   четырёх снимков две строки и отодвигает цену с кнопкой ниже сгиба. */
.gallery__big { display: block; width: 100%; }

.gallery__strip {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
    scrollbar-width: thin;
}

.gallery__thumb {
    flex: 0 0 auto;
    width: 4.5rem;
    border: 2px solid transparent;
    border-radius: var(--radius-small, 0.35rem);
    overflow: hidden;
    line-height: 0;
    text-decoration: none;
}

.gallery__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; aspect-ratio: 1; }

/* Текущий снимок обведён: без этого непонятно, который сейчас большой. */
.gallery__thumb.is-current { border-color: var(--color-accent, currentColor); }


.good-page__text p:last-child { margin-bottom: 0; }

/* Корзина. */
.cart__qty { max-width: 5.5rem; }
.cart__remove { text-align: end; }

/* Мои заказы: карточками, а не таблицей.

   Таблица из пяти столбцов на телефоне уезжает за край, и «Открыть»
   оказывается там, куда не дотянуться. Тот же приём, что в корзине. */
.orders { display: grid; gap: 0.9rem; }

.order-card { display: grid; gap: 0.6rem; justify-items: start; }

.order-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 0.9rem;
    width: 100%;
}

.order-card__number { font-weight: 600; font-size: 1.05rem; }
.order-card__when { opacity: 0.7; font-size: 0.9rem; }
.order-card__what { margin: 0; opacity: 0.85; }

.order-card__line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
}

.order-card__total { font-weight: 600; font-size: 1.1rem; }

.cart__total {
    margin: 1rem 0 0;
    text-align: end;
    font-size: 1.1rem;
}

.cart__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: flex-end;
    margin-top: 1rem;
}

/* Строка «товар — сумма» в оформлении и в письме об успехе. */
.checkout__line {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 0 0.5rem;
}

.checkout__total {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-line);
    font-size: 1.1rem;
}

.checkout__summary { margin-bottom: var(--gap); }

@media (max-width: 40rem) {
    .cart__actions { justify-content: stretch; }
    .cart__actions .button { flex: 1 1 auto; }
}

/* ============================================================== телефон ==
 *
 * Тема одна и та же для настольного экрана и для телефона. То же, о чём
 * помнит обычная тема, здесь помнить нужно ровно так же: поле мельче
 * 16 пикселей заставляет Safari приближать страницу, палец требует
 * площади, подсветку при наведении надо прятать от касания.
 */

@media (hover: none) {
    .feed-item:hover { border-color: var(--color-line); }
    .nav a:hover { color: var(--color-muted); }
}

@media (pointer: coarse) {
    .button { min-height: 44px; }
    /*
     * Крупный шрифт — только полям, в которые печатают: иначе он попадёт и
     * на кнопку, если та когда-нибудь наденет этот же класс, и выбьется из
     * строки. Отступ под палец нужен всем, он остаётся общим.
     */
    input.input,
    textarea.input,
    select.input {
        font-size: max(16px, 1rem);
    }

    .input { padding-block: 0.7rem; }
    .nav a { padding-block: 0.6rem; }
    .langs a { padding: 0.4rem 0.6rem; }
}

@media (max-width: 48rem) {
    :root { --gap: 1.5rem; }

    .site-head .wrap { gap: 0.75rem; }
    .nav { gap: 0.9rem; font-size: 0.95rem; }
    .nav__split { margin-inline-start: 0; }

    .panel { padding: 1.1rem; }
    .feed-item { padding: 1rem 1.1rem; }
}

@media (max-width: 40rem) {
    body { font-size: 1rem; }

    /*
     * Список входов на узком экране становится карточками: три столбца
     * на 360 пикселях не читаются никак.
     */
    .table--cards thead { display: none; }

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

    .table--cards tr {
        padding: 0.85rem 0;
        border-bottom: 1px solid var(--color-line);
    }

    .table--cards tr:last-child { border-bottom: none; }
    .table--cards td { border: none; padding: 0.15rem 0; }
    .table--cards td:last-child { text-align: start !important; padding-top: 0.6rem; }

    .comment--reply { margin-inline-start: 0.75rem; }

    .site-foot__line { flex-direction: column; gap: 0.35rem; }
}

/*
 * Название сайта на узком экране.
 *
 * В шапке к нему прибавились значок корзины и выбор языка, и в этой теме,
 * где шрифт крупнее обычного, «Nex1on» перестал помещаться — обрывался на
 * «Nex...». Сначала уменьшаем кегль: имя сайта важнее лишних двух точек
 * кегля. И только на совсем узком экране убираем его совсем — там
 * остаётся значок, по которому и так понятно, куда нажимать.
 */
@media (max-width: 30rem) {
    /*
     * Место в шапке отдаём имени сайта.
     *
     * Тесно там из-за трёх языков в рамках: они занимают почти треть
     * строки, хотя нужны единицам. Сжимаем их — рамки убираем, отступы
     * уменьшаем, черту-разделитель прячем, — и «Nex1on» перестаёт
     * обрываться на «Nex...». Выбор языка при этом остаётся на месте и
     * нажимается: три буквы никуда не делись.
     */
    .langs {
        gap: 0.15rem;
        padding-inline-start: 0.4rem;
        border-inline-start: 0;

        /*
         * И сам шрифт мельче. Три языка занимали почти треть строки
         * шапки — больше, чем имя сайта, ради которого сюда и заходят.
         * Буквы кода языка узнаются и в мелком кегле: их всего две.
         */
        font-size: 0.66rem;
    }

    .lang {
        padding: 0.2rem 0.3rem;
        border-color: transparent;
    }

    .lang.is-active { border-color: var(--color-line); }

    /*
     * И ещё немного тесноты убираем оттуда, где она не видна: зазоры в
     * строке шапки и поля кнопки «Меню». Каждый по паре точек, вместе —
     * те самые, которых не хватало имени сайта.
     */
    .site-head .wrap { gap: 0.5rem; }

    .nav-open { padding-inline: 0.55rem; }
}

@media (max-width: 22rem) {
    .wrap { width: min(100% - 1.5rem, var(--content-width)); }
    .brand-name { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* Ряд переключателей: выбор типа темы, отбор по метке. */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: var(--gap);
}

.chip {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--color-line);
    border-radius: 2px;
    font-size: 0.85rem;
    text-decoration: none;
    color: var(--color-muted);
}

.chip:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

.chip--on {
    border-color: var(--color-accent);
    color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}

.field__check {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
}

.field__check input {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--color-accent);
}

.props {
    display: grid;
    grid-template-columns: minmax(6rem, max-content) 1fr;
    gap: 0.4rem 1rem;
    margin: var(--gap) 0 0;
}

.props dt {
    color: var(--color-muted);
    font-size: 0.85rem;
}

.props dd {
    margin: 0;
}

@media (max-width: 30rem) {
    .props {
        grid-template-columns: 1fr;
        gap: 0.15rem;
    }

    .props dd {
        margin-bottom: 0.5rem;
    }
}

/* Пять тонов значка состояния — цвет решает тема, а не панель. */
.tag--info    { border-color: var(--color-accent);      color: var(--color-accent); }
.tag--ok      { border-color: var(--color-success);     color: var(--color-success); }
.tag--warn    { border-color: var(--color-warning);     color: var(--color-warning); }
.tag--danger  { border-color: var(--color-danger);      color: var(--color-danger); }
.tag--neutral { border-color: var(--color-line-strong); color: var(--color-muted); }

/* «Это решение» — скромная кнопка, как «Убрать», но спокойного цвета. */
.forum-post__solve {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-muted);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.forum-post__solve:hover { color: var(--color-success); text-decoration: underline; }

.forum-post--solution {
    border-color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 5%, transparent);
}

/* Смена состояния темы: подпись, список и кнопка в строку. */
.forum-status {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: var(--gap);
}

.forum-status .input { width: auto; min-width: 12rem; }

/* Голоса за тему: число и две кнопки в строку. */
.forum-votes {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: var(--gap);
}

.forum-votes__score {
    font-family: var(--font-mono);
    font-size: 1.2rem;
    color: var(--color-accent);
}

/* Заголовок над облаком меток. */
.forum-tags__title {
    margin: var(--gap) 0 0.75rem;
    font-size: 1.1rem;
}

/* Число тем у метки — рядом с названием, а не под ним: подсказка в теме
   объявлена блочной, и без этого метка занимает две строки. */
.chip .field__hint {
    display: inline;
    margin-left: 0.35rem;
    opacity: 0.7;
}

/* Заголовок категории над разделами. */
.forum-category {
    margin: var(--gap) 0 0.5rem;
    font-size: 1.05rem;
    color: var(--color-accent);
}

.forum-category .field__hint {
    display: block;
    margin-top: 0.25rem;
}

.forum-section--inside { margin-left: 1.25rem; }

@media (max-width: 40rem) {
    .forum-section--inside { margin-left: 0.5rem; }
}

/* Непрочитанное уведомление: полоса слева. */
.notify--new {
    border-left: 3px solid var(--color-accent);
}

.notify-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    flex-wrap: wrap;
}

.notify-bar .chips { margin-bottom: 0; }

.nav__bell {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.nav__bell-count {
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-surface);
    font-family: var(--font-mono);
    font-size: 0.7rem;
}

/* Жалоба: раскрывающийся блок вместо окошка поверх страницы. */
.forum-report { display: inline-block; }

.forum-report summary {
    color: var(--color-muted);
    font-size: 0.85rem;
    cursor: pointer;
    list-style: none;
}

.forum-report summary::-webkit-details-marker { display: none; }
.forum-report summary:hover { color: var(--color-danger); }

.forum-report__form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
    padding: 0.75rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
}

.forum-report__form .input { width: auto; min-width: 10rem; }
.forum-report__form label { width: 100%; }

/* Вложения под сообщением. */
.forum-files {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.75rem;
}

.forum-files__image img {
    display: block;
    max-height: 140px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
}

.forum-files__file {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.7rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    font-size: 0.9rem;
    text-decoration: none;
}

.forum-files__file:hover { border-color: var(--color-accent); }

/* --------------------------------------------------- размеченный текст */

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

.panel ul,
.panel ol,
.forum-post__body ul,
.forum-post__body ol {
    margin: 1em 0;
    padding-inline-start: 1.5em;
}

.panel li,
.forum-post__body li {
    margin: 0.35em 0;
}

.panel h2,
.panel h3,
.forum-post__body h2,
.forum-post__body h3 {
    margin: 1.6em 0 0.5em;
}

.panel h2:first-child,
.panel h3:first-child,
.forum-post__body h2:first-child {
    margin-top: 0;
}

.panel pre,
.forum-post__body pre,
.comment pre {
    margin: 1.2em 0;
    padding: 0.9em 1em;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 4px);
    background: var(--color-surface, #f6f6f4);
    overflow-x: auto;
}

/* ------------------------------------------------------------ окно кода */

figure.code {
    margin: 1.4em 0;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 4px);
    overflow: hidden;
}

.code__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.4rem 0.8rem;
    border-bottom: 1px solid var(--color-line);
    background: var(--color-surface, #f6f6f4);
}

.code__lang {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-muted);
}

.code__lang:empty::before {
    content: "\00a0";
}

.code__copy {
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--color-line);
    border-radius: 3px;
    background: transparent;
    color: var(--color-muted);
    font: inherit;
    font-size: 0.78rem;
    cursor: pointer;
}

.code__copy:hover,
.code__copy:focus-visible {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

figure.code pre {
    margin: 0;
    border: 0;
    border-radius: 0;
    padding: 0.9em 1em;
    overflow-x: auto;
}

/* Внутри окна кода рамка и подложка встроенного «code» не нужны: они
   рисуются вокруг каждой строки и превращают код в полосатый ковёр.
   Рамку держит само окно. */
figure.code code,
figure.code pre code {
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
}

/* Номер сообщения — ссылка на конкретную реплику. */
.forum-post__number {
    margin-inline-start: auto;
    color: var(--color-muted);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    text-decoration: none;
}

.forum-post__number:hover { color: var(--color-accent); }

/* Управление темой: свёрнуто, скромно, не спорит с разговором. */
.forum-manage {
    margin: 1rem 0;
    border: 1px solid var(--color-line, var(--color-border));
    border-radius: var(--radius, 6px);
    padding: 0.5rem 0.9rem;
}

.forum-manage summary {
    cursor: pointer;
    color: var(--color-muted);
    font-size: 0.85rem;
}

.forum-manage__body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.8rem;
}

.forum-manage__body form {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
}

/* «Последний ответ»: кто и когда. Имя отдельной строкой — при взгляде на
   список важнее, кто ответил, а не в котором часу. */
.forum-topic__last-who {
    display: block;
    color: var(--color-text);
}

.forum-topic__last-link { text-decoration: none; }
.forum-topic__last-link:hover { text-decoration: underline; }

/* Полоса над списком разделов: «что нового» и поиск. */
.forum-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.8rem;
    margin: 0 0 1.4rem;
}

.forum-search {
    display: flex;
    gap: 0.4rem;
    margin: 0;
    margin-inline-start: auto;
}

.forum-search .input {
    width: min(18rem, 50vw);
}

/* Корзина в шапке: видна, пока в ней что-то лежит. */
.shop-cartline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.8rem;
    padding: 0.5rem 0;
}

.shop-cartline__sum { margin-inline-end: auto; }

/* Полоса кнопок разметки над полем. Прижата к полю: между ними ничего не
   должно вклиниваться, иначе непонятно, к чему она относится. */
.markup-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--color-line, var(--color-border));
    border-bottom: 0;
    border-radius: var(--radius, 6px) var(--radius, 6px) 0 0;
}

.markup-bar + .field .input,
.markup-bar + .field textarea {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.markup-bar__btn {
    min-width: 2rem;
    padding: 0.2rem 0.45rem;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var(--color-text);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    cursor: pointer;
}

.markup-bar__btn:hover,
.markup-bar__btn:focus-visible {
    border-color: var(--color-line, var(--color-border));
}

/* Предпросмотр — черновик, а не сообщение: пунктир говорит это без слов,
   иначе человек ищет свою реплику в теме и не находит. */
.forum-preview {
    border-style: dashed;
    margin-bottom: 1rem;
}

.forum-reply__buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
}

/* Кружок с инициалами вместо аватара. Цвет считается из имени: у одного
   человека он всегда один и тот же, у соседей по списку — разный. */
.who-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: hsl(var(--hue, 200) 45% 30%);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    flex: 0 0 auto;
}

/* «Сколько штук» рядом с кнопкой: поле узкое — больше трёх цифр там не
   нужно, а широкое сбивает с толку. */
.buy {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.6rem;
}

.buy__count {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.buy__count .input { width: 5rem; }

/* Полоса порядка: ссылки, а не выпадающий список — список требует
   двух нажатий и не показывает, из чего выбор, пока его не откроешь.
   Одна на форум и на магазин: класс с именем модуля в общей теме
   означал бы вторую такую же полосу при первом же новом списке.
   Порядок тем: ссылки, а не список. Текущий выделен — иначе непонятно,
   что сейчас показано. */
.order-line {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    margin-inline-start: auto;
    font-size: 0.85rem;
}

.order-line__item {
    color: var(--color-muted);
    text-decoration: none;
}

.order-line__item:hover { color: var(--color-accent); }

.order-line__item.is-current {
    color: var(--color-text);
    text-decoration: underline;
}

/* Насколько дешевле. */
.price__off {
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
    color: var(--color-accent);
    font-size: 0.8rem;
    font-weight: 600;
}

/* Меню на телефоне прокручивается вбок — и об этом надо сказать.
   Пункты за краем есть, но человек их не видит и решает, что «Поиска» на
   сайте нет вовсе. Тень у правого края держится, пока есть что показать,
   и пропадает, когда прокрутили до конца.

   Двумя слоями фона: «затычки» цвета шапки прокручиваются вместе с
   содержимым (local) и закрывают тени (fixed) у самых краёв. Ни одной
   строчки скриптов. */
@media (max-width: 52rem) {
    .nav {
        background:
            linear-gradient(to right, var(--color-background, #fff) 30%, transparent) left center / 2rem 100% no-repeat local,
            linear-gradient(to left,  var(--color-background, #fff) 30%, transparent) right center / 2rem 100% no-repeat local,
            linear-gradient(to right, rgba(0, 0, 0, 0.18), transparent) left center / 1.2rem 100% no-repeat,
            linear-gradient(to left,  rgba(0, 0, 0, 0.18), transparent) right center / 1.2rem 100% no-repeat;
    }
}

/* «Новое» — заливкой, а не рамкой.
   Остальные значки рассказывают о теме: решено, закрыто, вопрос. Этот —
   единственный, который говорит лично тебе, и глаз должен цеплять его
   раньше прочих. */
.tag--new {
    border-color: var(--color-accent);
    background: var(--color-accent);
    color: var(--color-background, #05070d);
    font-weight: 600;
}

/*
 * «hidden» должен быть сильнее любого нашего «display».
 *
 * Браузер прячет такой элемент правилом «display: none», и оно слабее
 * нашего собственного «.класс { display: flex }» — просто потому, что
 * своё правило именованное, а браузерное нет. Ловились на этом дважды:
 * первый раз ответ в комментариях, второй — окно быстрого перехода,
 * которое стояло открытым на каждой странице панели, хотя в разметке
 * было спрятано. Ставим один раз и на всех.
 */
[hidden] { display: none !important; }

/* Цвета в полосе разметки — кружками, как в панели: список короткий, и
   выбирать из него глазами быстрее, чем читать названия. */
.markup-bar__sep {
    width: 1px;
    height: 1.2rem;
    margin: 0 0.2rem;
    background: var(--color-line, var(--color-border));
}

.markup-bar__color {
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    border: 1px solid var(--color-line, var(--color-border));
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
}

.markup-bar__color span { display: block; width: 100%; height: 100%; border-radius: 50%; }

.markup-bar__color--red    span { background: #e5484d; }
.markup-bar__color--orange span { background: #f76b15; }
.markup-bar__color--yellow span { background: #ffb224; }
.markup-bar__color--green  span { background: #30a46c; }
.markup-bar__color--blue   span { background: #0090ff; }
.markup-bar__color--purple span { background: #8e4ec6; }
.markup-bar__color--gray   span { background: #8b8d98; }

/* Подсказка по разметке: свёрнутая не занимает ничего, а открывается без
   скриптов — значит работает и там, где полосы кнопок нет вовсе. */
/* Подсказка занимает всю ширину полосы: содержимое её раскрывается
   строкой ниже кнопок, а не рядом с ними. */
/* «min-width: 0» обязателен: без него содержимое растягивает элемент
   гибкой раскладки шире родителя, и на телефоне страница уезжает вбок. */
.markup-help { flex: 1 0 100%; min-width: 0; margin: 0; font-size: 0.9rem; }

.markup-help > summary {
    cursor: pointer;
    color: var(--color-muted);
}

.markup-help > summary:hover { color: var(--color-accent); }

.markup-help__table {
    width: 100%;
    margin: 0.6rem 0 0;
    border-collapse: collapse;
    table-layout: fixed;
}

.markup-help__table td { word-break: break-word; }

.markup-help__table td {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid var(--color-line, var(--color-border));
    vertical-align: top;
}

.markup-help__table td:first-child { width: 45%; }

.markup-help__table code {
    white-space: pre-wrap;
    font-size: 0.8rem;
    color: var(--color-muted);
}

.markup-help__table p { margin: 0; }

/* «Слежу за темой» — состояние словами рядом с тихой кнопкой: надпись на
   кнопке говорит, что будет по нажатию, а не что есть сейчас. */
.forum-watch {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
}

.forum-watch__state { color: var(--color-muted); font-size: 0.9rem; }


/* ------------------------------------------------- меню на телефоне

   Раньше меню на узком экране было полоской, прокручивающейся вбок:
   из десяти пунктов помещались четыре, а «Загрузки», «Связаться»,
   «Вакансии», «Поиск», уведомления и своя учётная запись уезжали за край
   без единого намёка, что там что-то есть.

   Кнопку показывает скрипт (внизу макета). Не выполнился — кнопки нет,
   и остаётся прежняя полоска: она хотя бы прокручивается. */

.nav-open {
    display: none;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.7rem;
    border: 1px solid var(--line, currentColor);
    border-radius: 0.5rem;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
    /* палец, а не курсор: меньше сорока восьми точек мажут мимо */
    min-height: 2.5rem;
}

.nav-open__bars,
.nav-open__bars::before,
.nav-open__bars::after {
    display: block;
    width: 1.1rem;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
}

.nav-open__bars {
    position: relative;
}

.nav-open__bars::before,
.nav-open__bars::after {
    content: '';
    position: absolute;
    inset-inline-start: 0;
}

.nav-open__bars::before { top: -6px; }
.nav-open__bars::after { top: 6px; }

@media (max-width: 48rem) {
    /* кнопка по своему содержимому, а не во всю строку: она не заголовок */
    .nav-open {
        display: inline-flex;
        grid-column: 1 / -1;
        grid-row: 2;
        justify-self: start;
    }

    /* открыто — видно по кнопке, а не только по списку под ней */
    .nav-open[aria-expanded="true"] {
        background: color-mix(in srgb, currentColor 10%, transparent);
    }

    /*
     * Меню — список сверху вниз, и по умолчанию его нет.
     *
     * «!important» тут потому, что выше в этом же файле меню объявлено
     * прокручиваемой строкой с «display: flex», и правило то стоит в
     * своём медиа-блоке. Спорить с ним весом selector'ов пришлось бы
     * длинной цепочкой, которую потом никто не поймёт.
     */
    /*
     * Шапка у тем устроена по-разному: у одной сетка, у другой гибкая
     * строка с переносом. Поэтому распоряжения даём и те, и другие —
     * лишние просто не сработают. Порядком выстраиваем так, чтобы
     * наверху остались имя сайта, языки и кнопка, а список ушёл под них
     * во всю ширину: в «Бумаге» открытое меню иначе вставало узким
     * столбиком, а языки липли к нему сбоку.
     */
    .brand { order: 0; }
    .langs { order: 1; }
    .nav-open { order: 2; flex: 0 0 auto; }

    .nav {
        display: none !important;
        order: 3;
        flex: 1 0 100%;
        grid-column: 1 / -1;
        grid-row: 3;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        overflow: visible;
        margin: 0.5rem 0 0;
        padding: 0.35rem 0;
        border: 1px solid var(--line, currentColor);
        border-radius: 0.6rem;
    }

    /*
     * Меню открывается поверх страницы, а не раздвигает её.
     *
     * Раньше оно стояло в потоке шапки (grid-row: 3) и при открытии
     * толкало всё содержимое вниз — открыл меню, а страница ускакала.
     * Теперь при открытии меню отрывается от потока: ложится под шапку
     * absolute, поверх содержимого. Точка отсчёта — сама шапка: она
     * sticky, а значит уже служит опорой для absolute внутри, и трогать
     * её position нельзя — иначе перестанет прилипать при прокрутке.
     */
    .nav.is-open {
        display: flex !important;
        /*
         * Строго одной колонкой сверху вниз. У шапки меню flex-wrap: wrap
         * (горизонтальное меню на десктопе умеет переноситься), но открытое
         * вертикальное меню переносить нельзя: боковые блоки в самом низу
         * не влезали по высоте и уезжали во вторую колонку — становились
         * невидимыми сбоку. nowrap оставляет всё одним столбцом.
         */
        flex-wrap: nowrap;

        /*
         * Во весь оставшийся экран: от низа шапки до самого низа и до
         * самых краёв.
         *
         * Раньше меню было ровно по своему содержимому и обрывалось там,
         * где кончались пункты, — выходило окошко, висящее посреди
         * страницы, сквозь которое снизу торчало содержимое. Теперь это
         * отдельный экран: шапка с логотипом и кнопкой остаётся на месте,
         * всё остальное занимает меню, даже если пунктов немного.
         *
         * `fixed`, а не `absolute`: считать надо от окна, а не от шапки, —
         * иначе низ меню зависел бы от того, куда прокручена страница.
         * Где кончается шапка, подсказывает `--head-h`: её меряет скрипт
         * при открытии, потому что высота шапки зависит от темы и от
         * размера логотипа. Запасное значение — на случай, если скрипт до
         * замера не дошёл.
         */
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        /*
         * Высоту задаём числом, а не растяжкой «сверху донизу».
         *
         * У шапки есть размытие подложки (backdrop-filter), а элемент с
         * размытием становится точкой отсчёта даже для `fixed`. То есть
         * «до низа экрана» превращалось в «до низа шапки»: меню выходило
         * ростом в 12 точек. Поэтому считаем прямо: весь экран минус
         * шапка. Шапка прилипшая, её низ всегда на одной высоте, так что
         * счёт верен при любой прокрутке.
         *
         * Сначала vh — его понимают все, — а следом dvh: на телефоне
         * адресная строка браузера то появляется, то исчезает, и только
         * dvh считает по тому, что на экране сейчас. Кто dvh не знает,
         * второе правило пропустит и останется с первым.
         */
        height: calc(100vh - var(--head-h, 3.5rem));
        height: calc(100dvh - var(--head-h, 3.5rem));
        z-index: 60;
        margin: 0;
        border-radius: 0;
        background: var(--color-background);
        /* длинное меню прокручивается внутри себя, не утаскивая страницу */
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /*
     * Пока меню раскрыто, страница под ним стоит.
     *
     * Иначе палец, ведя по меню, уводит страницу, а её полоса прокрутки
     * отъедает у меню правый край — и меню не доходит до края экрана.
     * Класс ставит скрипт при открытии.
     */
    html.nav-otkryto,
    html.nav-otkryto body {
        /*
         * Не «overflow: hidden».
         *
         * Закрытый overflow делает элемент своим миром прокрутки, и
         * липкое внутри него липнуть перестаёт: шапка уезжала вверх
         * вместе со страницей, а открытое меню — следом за ней, потому
         * что отсчитывается от шапки. Человек, стоявший внизу длинной
         * страницы, нажимал «Меню» и не видел ничего.
         *
         * «touch-action: none» держит палец так же крепко, но раскладку
         * не трогает — шапка остаётся прилипшей, меню под ней.
         */
        touch-action: none;
    }

    /* Внутри себя меню прокручиваться должно — иначе длинное не пролистать. */
    html.nav-otkryto .nav.is-open {
        touch-action: pan-y;
    }

    /* пункт во всю ширину и высотой под палец */
        /*
     * Пункты меню — прямые дети навигации, и правило должно касаться
     * только их.
     *
     * Раньше здесь стояло «.nav a, .nav form»: любая форма внутри меню
     * становилась строкой-пунктом. Пока в меню жили ссылки и кнопка
     * «Выйти», это было верно. Потом на телефоне в меню стала переезжать
     * боковая колонка со своими блоками — и форма подписки, попав под то
     * же правило, вытянулась в один ряд: поля, кнопка и обе строки про
     * подтверждение встали друг за другом и уехали за край экрана.
     * Друг это увидел первым и прислал снимок.
     *
     * Знак «>» и лечит: пункт меню — тот, что лежит в навигации сам, а не
     * тот, что приехал внутри чужого блока.
     */
    .nav > a,
    .nav > form,
    .nav > form > button {
        display: flex;
        align-items: center;
        /*
         * Слева, а не по центру. «Выйти» и уведомления — это кнопки, а у
         * кнопок общий стиль центрирует текст; в столбце меню один пункт
         * по центру среди прижатых влево бросается в глаза как ошибка.
         * Прижимаем всё к левому краю, как ссылки.
         */
        justify-content: flex-start;
        width: 100%;
        min-height: 2.75rem;
        padding-inline: 0.85rem;
        border-radius: 0;
        text-align: start;
    }

    /* разделитель перед личными пунктами — чертой, а не пустотой */
    .nav .nav__split {
        width: auto;
        height: 1px;
        margin: 0.35rem 0.85rem;
        background: var(--line, currentColor);
        opacity: 0.5;
    }

    .nav-open__word { font-size: 0.85rem; }

    /*
     * Уведомления в строке — значок, в списке — слово.
     *
     * В строке рядом с ним соседи, и по месту понятно, что это. В списке
     * сверху вниз одинокая кружочек-закорючка не значит ничего: человек
     * не угадывает значки, он читает подписи. Берём ту же надпись, что
     * уже стоит для читалок, — переводится она вместе со всем остальным.
     */
    .nav .nav__bell::after {
        content: attr(aria-label);
        margin-inline-start: 0.5rem;
    }
}

/* язык, на котором этой страницы нет: ссылка рабочая, но обещает меньше */
.lang--none { opacity: 0.45; }

/* ------------------------------------------- боковые блоки на телефоне

   На узком экране боковая колонка встаёт под содержимым, и её блоки
   тянулись лентой до самого низа. Теперь у каждого виден только
   заголовок, а содержимое сворачивается — раскрывает стрелка справа.
   Класс «is-open» и обёртку «block__fold» ставит скрипт в макете; не
   выполнился — блоки останутся развёрнутыми, как были. */

.block__toggle { display: none; }

@media (max-width: 48rem) {
    .side-col .block__title {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.5rem;
        margin-bottom: 0;
    }

    .block__toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: none;
        width: 2rem;
        height: 2rem;
        padding: 0;
        border: 0;
        background: none;
        color: inherit;
        font-size: 1.4rem;
        line-height: 1;
        cursor: pointer;
        /* стрелка вниз в закрытом виде, вбок — открытый */
        transform: rotate(90deg);
        transition: transform 0.15s ease;
    }

    .side-col .block.is-open .block__toggle { transform: rotate(-90deg); }

    /* содержимое свёрнуто, пока блок не открыли */
    .side-col .block__fold { display: none; margin-top: 0.75rem; }
    .side-col .block.is-open .block__fold { display: block; }
}

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

/* ------------------------------------ боковая колонка внутри меню (телефон)

   На телефоне скрипт переносит боковую колонку в низ выпадающего меню —
   чтобы страница не тянулась лентой блоков, а всё вспомогательное было в
   одном выдвижном месте. Внутри меню колонка не липкая и во всю ширину,
   а сверху отделена чертой. */
@media (max-width: 48rem) {
    .nav .side-col {
        position: static;
        display: block;
        width: 100%;
        margin: 0;
        /*
         * Своего бокового отступа у колонки нет: он складывался с отступом
         * самих строк, и блоки стояли уступом правее пунктов меню. Отступ
         * задают строки, одинаково для всех.
         */
        padding: 0.35rem 0 0.5rem;
        border-top: 1px solid var(--color-line);
    }

    .nav .side-col .block {
        margin: 0.75rem 0 0;
        border: 0;
        padding: 0;
        background: none;
        box-shadow: none;
    }
}


/*
 * Телефон: шапка одной строкой и меню одним видом.
 *
 * Две беды, которые видно сразу. Первая: кнопка «Меню» уезжала под
 * логотип отдельной строкой — шапка занимала два этажа и выглядела
 * недоделанной, а кнопке место справа, наравне с именем сайта. Места
 * хватает: имя 109px, языки 106px, кнопка 88px — 303 из 343 доступных
 * на экране в 390px. Имя сайта ужимается многоточием, если экран совсем
 * узкий: строка не должна ломаться никогда.
 *
 * Вторая: в самом меню было три разных размера букв и три начертания —
 * ссылки 14.7px обычным, «Выйти» 13.6px полужирным в рамке, заголовки
 * блоков 11.5px жирным ЗАГЛАВНЫМИ вразрядку. Читается как три куска,
 * слепленных вместе. Теперь у всех строк меню один размер, одно
 * начертание и одна выключка по левому краю, а разница в размере
 * осталась одна и намеренная: содержимое свёрнутого блока мельче и
 * приглушённее заголовка — это и есть вложенность.
 */
@media (max-width: 48rem) {
    .site-head .wrap {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        /*
         * Промежуток поуже, чем на широком экране: в «Бумаге» имя сайта
         * упиралось в языки и обрезалось многоточием, хотя не хватало
         * пяти точек. Многоточие оставляем как страховку для длинных
         * названий, но срабатывать оно должно редко.
         */
        gap: 0.5rem 0.4rem;
    }

    .brand {
        flex: 1 1 auto;
        min-width: 0;
        grid-column: auto;
        grid-row: auto;
        order: 0;
    }

    /*
     * Имя сайта: не ломает строку и одного роста во всех темах.
     *
     * Темы задают ему свой размер — в «Витрине» 20px против 15px в тёмной,
     * — и на телефоне то же самое имя в одной теме помещалось, а в другой
     * обрезалось многоточием. Ширина экрана у всех тем одна, значит и рост
     * имени на ней должен быть один. Многоточие остаётся страховкой для
     * длинных названий: строка не должна ломаться никогда.
     */
    .brand-name {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: clamp(0.95rem, 4vw, 1.05rem);
    }

    .langs {
        flex: 0 0 auto;
        margin-inline-start: auto;
        grid-column: auto;
        grid-row: auto;
        order: 1;
    }

    .nav-open {
        flex: 0 0 auto;
        grid-column: auto;
        grid-row: auto;
        justify-self: auto;
        order: 2;
    }

    /*
     * Языковые значки на телефоне поуже.
     *
     * Три значка занимали 123px из 335 доступных — больше, чем имя сайта,
     * из-за чего имя обрезалось многоточием. Коды из двух букв читаются и
     * в тесной рамке, а место нужнее названию сайта.
     */
    .langs .lang {
        padding: 0.25rem 0.4rem;
    }

    /* Один размер и одна выключка на все строки открытого меню. */
    .nav.is-open a,
    .nav.is-open form:not(.side-col form) button,
    .nav.is-open .side-col .block__title {
        /*
         * Один шрифт на все строки.
         *
         * Заголовки боковых блоков — это заголовки, и тема набирает их
         * своим шрифтом (в тёмной — моноширинным). В колонке сбоку это
         * уместно, а строкой меню среди системного шрифта читается как
         * кусок из другого места. В меню все строки — строки списка.
         */
        font-family: inherit;
        font-size: 0.95rem;
        font-weight: 500;
        line-height: 1.4;
        letter-spacing: normal;
        text-transform: none;
        text-align: left;
        justify-content: flex-start;
        padding: 0.6rem 0.85rem;
    }

    /*
     * «Выйти» — такая же строка меню, как остальные.
     *
     * Рамка вокруг неё осталась от общей кнопки и в списке строк читалась
     * как чужеродная врезка: глаз цеплялся за неё вместо того, чтобы
     * скользить по списку.
     */
    .nav.is-open form:not(.side-col form),
    .nav.is-open form:not(.side-col form) button {
        width: 100%;
    }

    /* строка «Выйти» начинается там же, где все остальные, а не на 13px правее */
    .nav.is-open form:not(.side-col form) {
        padding: 0;
        margin: 0;
    }

    .nav.is-open form:not(.side-col form) button {
        border: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;
        /* тот же цвет, что у соседних строк: «Выйти» — не выделенное действие */
        color: var(--color-muted);
    }

    /*
     * Заголовок свёрнутого блока — такая же строка, со стрелкой у правого
     * края: строка целиком показывает, что её можно раскрыть.
     */
    .nav.is-open .side-col .block__title {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.5rem;
        margin: 0;
        /* те же размеры, что у остальных строк меню, — см. правило выше */
        font-size: 0.95rem;
        font-weight: 500;
        line-height: 1.4;
        letter-spacing: normal;
        text-transform: none;
        text-align: left;
        /*
         * Рост строки задаёт она сама, а не стрелка внутри.
         *
         * У кнопок на телефоне есть наименьший рост под палец (2.75rem), и
         * стрелка растягивала строку до 63px, тогда как строки меню ростом
         * 44px. Список шёл рывками. Теперь рост держит сама строка, а
         * стрелка вписывается в него.
         */
        min-height: 2.75rem;
        padding: 0 0 0 0.85rem;
        /* тот же цвет, что у остальных строк меню, — а не цвет заголовка */
        color: var(--color-muted);
    }

    /* блоки идут подряд, как строки списка, а не отдельными карточками */
    .nav .side-col .block {
        margin: 0;
    }

    /*
     * Ссылка-название внутри заголовка своих отступов не имеет.
     *
     * Она попадала под общее правило строк меню и получала второй отступ
     * поверх отступа заголовка, а во всю ширину выталкивала стрелку за
     * край экрана — стрелки просто не было видно. Отступ задаёт заголовок,
     * ссылка лишь занимает оставшееся место.
     */
    .nav.is-open .side-col .block__title a {
        flex: 1 1 auto;
        min-width: 0;
        width: auto;
        padding: 0;
        font: inherit;
        color: inherit;
    }

    .nav .side-col .block__toggle {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        /* вписывается в строку, а не растягивает её; но под палец — во всю высоту */
        min-height: 0;
        width: 2.75rem;
        align-self: stretch;
        border: 0;
        background: none;
        color: inherit;
        cursor: pointer;
        padding: 0;
        font-size: 1.05rem;
        line-height: 1;
        transition: transform 0.15s ease;
    }

    .nav .side-col .block.is-open .block__toggle {
        transform: rotate(90deg);
    }

    /* Содержимое блока — мельче и приглушённее: это вложенность, а не новый раздел. */
    .nav .side-col .block__fold {
        padding-bottom: 0.35rem;
    }

    .nav.is-open .side-col .block__fold a {
        font-size: 0.9rem;
        font-weight: 400;
        padding-block: 0.4rem;
        padding-inline-start: 1.35rem;
        color: var(--color-muted, inherit);
    }
}

/*
 * Совсем узкий экран (уже 384px): кнопка меню — одним значком.
 *
 * Слово «Меню» занимает 45px, и на экранах в 360px их не хватало именно
 * имени сайта — оно обрезалось многоточием. Три полоски понятны и без
 * подписи, а название сайта подписи не имеет вовсе, поэтому уступает
 * слово, а не имя. Для читалок подпись остаётся: она в aria-label кнопки.
 */
@media (max-width: 24rem) {
    .nav-open__word {
        display: none;
    }

    .nav-open {
        padding-inline: 0.7rem;
    }
}

/*
 * Полоса прокрутки — своя, а не системная.
 *
 * В панели она давно приведена к общему виду, а на сайте оставалась
 * браузерной: широкая, со стрелками и своим цветом. Разница бросалась в
 * глаза в открытом меню — рядом с тёмным списком шла светлая системная
 * полоса, будто из чужого окна.
 *
 * Задаём дважды: по-новому (`scrollbar-color` — Firefox, свежие Chrome) и
 * через `::-webkit-scrollbar` — для тех, кто первого ещё не знает. Цвет
 * наследуется, поэтому хватает одного правила на `html`, а вот ширина —
 * нет: `scrollbar-width` ненаследуемое, и заданная только на `html` она
 * оставляла полосу у меню обычной. Отсюда `*`.
 *
 * Цвет берём от текста темы, а не отдельной переменной: тогда он верен и
 * в тёмной теме, и в светлой, и в любой, которую заведёт покупатель.
 */
html {
    scrollbar-color: color-mix(in srgb, var(--color-text) 28%, transparent) transparent;
}

* { scrollbar-width: thin; }

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-corner { background: transparent; }

/* Прозрачная рамка вместе с `background-clip` даёт ползунку воздух по
   бокам: он получается тоньше жёлоба и не липнет к содержимому. */
*::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--color-text) 28%, transparent);
    border: 2px solid transparent;
    border-radius: 999px;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--color-text) 45%, transparent);
    background-clip: content-box;
}

/* ------------------------------------------------------------- доставка */

/*
 * Выбор способа доставки в оформлении заказа.
 *
 * Каждый способ — строка, по которой можно попасть пальцем целиком, а не
 * только по кружку переключателя. Название слева, цена справа: так их
 * сравнивают взглядом сверху вниз, не читая строк целиком. Пояснение
 * («1–2 дня», «бесплатно от 2000») уходит под них и набрано мельче — это
 * подробность, а не то, между чем выбирают.
 */
.checkout__delivery {
    margin: 0 0 1.1rem;
    padding: 0;
    border: 0;
}

.checkout__delivery legend {
    padding: 0;
    margin-bottom: 0.5rem;
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-muted);
}

.checkout__way {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: baseline;
    gap: 0.25rem 0.6rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid var(--color-line, var(--color-border, currentColor));
    border-radius: var(--radius, 0.5rem);
    cursor: pointer;
}

.checkout__way + .checkout__way { margin-top: 0.5rem; }

.checkout__way:hover { border-color: var(--color-accent); }

/* выбранный способ виден сразу, не приглядываясь к кружку */
.checkout__way:has(input:checked) {
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}

.checkout__way input { margin: 0; }

.checkout__way-name { font-weight: 600; }

.checkout__way-price { white-space: nowrap; }

/* пояснение идёт со второй колонки: под названием, а не под кружком */
.checkout__way-note {
    grid-column: 2 / -1;
    font-size: 0.85rem;
    color: var(--color-muted);
}

/*
 * Промокод: строка скидки и поле для кода в той же сводке, где сумма.
 *
 * Скидка стоит между товарами и итогом, потому что читают сверху вниз и
 * так виден сам счёт: столько стоило, столько сняли, столько платить.
 */
.checkout__discount {
    color: var(--color-accent);
}

.checkout__promo {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--color-line);
}

/*
 * Заметка о том, что код принят, но проиграл правилу. Не ошибка и не
 * успех — пояснение, поэтому спокойным цветом подписи, а не красным.
 */
.checkout__promo-note {
    margin: 0.9rem 0 0;
    padding-top: 0.9rem;
    font-size: 0.9rem;
    color: var(--color-muted);
}

.checkout__promo-label {
    display: block;
    margin-bottom: 0.4rem;
    font-size: 0.85rem;
    color: var(--color-muted);
}

/*
 * Поле и кнопка в строку, но кнопка не жмётся: на узком экране поле
 * занимает всё, что осталось, и код видно целиком.
 */
.checkout__promo-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.checkout__promo-row .input {
    flex: 1 1 8rem;
    min-width: 0;
    font-family: var(--font-mono, ui-monospace, monospace);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/*
 * Купленное цифровое.
 *
 * Ключ показываем крупно и моноширинным: его переписывают руками или
 * выделяют мышью, и похожие знаки — ноль и «о», единица и «эль» — должны
 * различаться с одного взгляда.
 */
.checkout__issues {
    margin-top: var(--gap);
}

.checkout__issues-title {
    margin: 0 0 0.8rem;
    font-size: 1.05rem;
}

.checkout__issue + .checkout__issue {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-line);
}

.checkout__issue-name {
    margin: 0 0 0.5rem;
    font-weight: 600;
}

.checkout__issue-key {
    margin: 0 0 0.5rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--radius, 0.5rem);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 1.05rem;
    letter-spacing: 0.06em;
    user-select: all;
    overflow-wrap: anywhere;
}

.checkout__issue-note {
    margin: 0.4rem 0 0;
    font-size: 0.9rem;
    color: var(--color-muted);
    white-space: pre-line;
}





/*
 * Обещания магазина и поиск по каталогу.
 *
 * Обещания — короткий ряд над товарами: доставка, оплата, связь. На узком
 * экране становятся столбиком, потому что четыре колонки по 90 пикселей
 * не читаются вовсе.
 */
.promises {
    display: grid;
    gap: 0.6rem;
    margin: 0 0 var(--gap);
    padding: 0;
    list-style: none;
}

@media (min-width: 40rem) {
    .promises { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
}

.promises__item {
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 0.5rem);
}

.promises__title { display: block; }

.promises__note {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.85rem;
    color: var(--color-muted);
}

.shop-search {
    margin: 0 0 var(--gap);
}

.shop-search__label {
    display: block;
    margin-bottom: 0.4rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-faint, var(--color-muted));
}

/* поле тянется, кнопки — нет: длинное название должно быть видно целиком */
.shop-search__row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

/* Отбор по цене — второй строкой формы поиска.

   Подписи и поля в одну линию: «Цена от [ ] до [ ]» читается как фраза, а
   столбиком из четырёх строк занимало бы пол-экрана телефона ради двух
   чисел. */
.shop-search__price {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

.shop-search__price label { font-size: 0.9rem; opacity: 0.85; }

.input--small { max-width: 7rem; }

/* Сколько нашлось — над рядом порядка, тише названий товаров. */
.shop-found { margin: 0.75rem 0 0; opacity: 0.85; }


.shop-search__row .input {
    flex: 1 1 12rem;
    min-width: 0;
}


/*
 * Подписи ячеек в карточках.
 *
 * Приём «таблица становится карточками» в теме уже был — им показывают
 * список входов, где по значению и так понятно, что это. В корзине не так:
 * «999 ₴», «1», «999 ₴» подряд без подписей читаются как загадка.
 *
 * Подпись берётся из самой ячейки (data-label), поэтому шапка таблицы не
 * нужна и остаётся скрытой, а разметка не удваивается.
 */
@media (max-width: 45rem) {
    .table--cards td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 0.1rem;
        font-family: var(--font-mono);
        font-size: 0.7rem;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--color-faint, var(--color-muted));
    }

    /*
     * «Убрать» — во всю ширину карточки. Узкая кнопка у правого края
     * уезжала за него вместе с таблицей; здесь ей уезжать некуда, но
     * попасть по ней пальцем всё равно должно быть легко.
     */
    .table--cards .cart__remove .button { width: 100%; }
}


/*
 * Выбор варианта: размер, цвет, объём.
 *
 * Переключателями и в столбик, а не выпадающим списком: цены видно все
 * сразу и сравнивать их можно не открывая ничего. Кончившийся вариант
 * остаётся на месте приглушённым — так честнее, чем прятать: покупатель
 * видит, что размер бывает, просто сейчас его нет.
 */
.buy__variants {
    margin: 0 0 0.9rem;
    padding: 0;
    border: 0;
}

.buy__variants legend {
    padding: 0;
    margin-bottom: 0.45rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-faint, var(--color-muted));
}

.buy__variant {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: baseline;
    gap: 0.25rem 0.6rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 0.5rem);
    cursor: pointer;
}

.buy__variant + .buy__variant { margin-top: 0.4rem; }

.buy__variant:hover { border-color: var(--color-accent); }

.buy__variant:has(input:checked) {
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}

.buy__variant.is-out {
    opacity: 0.55;
    cursor: default;
}

.buy__variant.is-out:hover { border-color: var(--color-line); }

.buy__variant input { margin: 0; }

.buy__variant-name { font-weight: 600; }

.buy__variant-price { white-space: nowrap; }

.buy__variant-out {
    grid-column: 2 / -1;
    font-size: 0.85rem;
    color: var(--color-muted);
}

/* вариант рядом с названием в корзине — приписка, а не вторая строка */
.cart__variant {
    margin-inline-start: 0.4rem;
    padding: 0.1rem 0.4rem;
    border-radius: var(--radius, 0.4rem);
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
    font-size: 0.85rem;
}


/*
 * Оценки: звёзды у товара и в отзывах.
 *
 * Звёзды текстом, а не картинками: они масштабируются со шрифтом, читаются
 * голосовыми помощниками и не требуют ни одного лишнего запроса. Пустые —
 * те же звёзды приглушённым цветом, поэтому «четыре из пяти» видно с
 * одного взгляда, не считая.
 */
.good-rating {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0.4rem 0 0;
    font-size: 0.95rem;
}

.good-rating__stars,
.comment__rating {
    color: var(--color-accent);
    letter-spacing: 0.08em;
}

.good-rating__rest,
.comment__rating-rest {
    color: var(--color-muted);
    opacity: 0.45;
}

.comment__rating {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
}

/*
 * Выбор оценки в форме отзыва: числа переключателями в ряд. Не звёздами,
 * потому что звезда, по которой надо попасть пальцем, — это спор с
 * человеком; число в кружке нажимается уверенно.
 */
.comments__rating {
    margin: 0 0 1rem;
    padding: 0;
    border: 0;
}

.comments__rating legend {
    padding: 0;
    margin-bottom: 0.4rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-faint, var(--color-muted));
}

.comments__star {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-inline-end: 0.5rem;
    padding: 0.35rem 0.6rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 0.5rem);
    cursor: pointer;
}

.comments__star:has(input:checked) {
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

.comments__rating .field__hint { display: block; margin-top: 0.4rem; }


/*
 * Заглушка вместо картинки товара.
 *
 * Первая буква названия крупно на приглушённом фоне. Не «нет фото» серым
 * по серому: карточки в ряду остаются различимыми, и место выглядит
 * занятым нарочно, а не забытым.
 *
 * Пропорции те же, что у настоящей картинки, — иначе ряд карточек
 * запрыгал бы по высоте в зависимости от того, у кого фото есть.
 */
/*
 * Обёртка картинки — ссылка, и в светлых темах она подчёркнута. Под
 * буквой заглушки это подчёркивание проступало чертой поперёк карточки.
 */
.good__cover,
.good-page__cover a { text-decoration: none; }

.good-stub {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 4 / 3;
    background:
        linear-gradient(135deg,
            color-mix(in srgb, var(--color-accent) 12%, transparent),
            transparent 60%),
        var(--color-background, #05070d);
    color: var(--color-muted);
    overflow: hidden;
}

.good-stub--page { aspect-ratio: 1 / 1; }

.good-stub__letter {
    font-family: var(--font-display, inherit);
    font-size: clamp(2.5rem, 18%, 6rem);
    font-weight: 700;
    line-height: 1;
    opacity: 0.5;
    user-select: none;
}

.good-stub--page .good-stub__letter { font-size: clamp(4rem, 22%, 9rem); }


/*
 * «Перезвоните мне»: значок в углу экрана.
 *
 * Держится поверх страницы и не уезжает при прокрутке — человек решает
 * позвонить в любой миг, а не только докрутив до низа. Слева от края и
 * снизу, где палец достаёт с телефона, не закрывая при этом текст.
 *
 * Раскрывается своим «details», без скриптов: закрыть можно тем же
 * нажатием или клавишей Esc.
 */
.callme {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 60;
}

/* треугольник браузера убираем: у нас своя кнопка */
.callme > summary { list-style: none; }
.callme > summary::-webkit-details-marker { display: none; }

.callme__button {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.7rem 1rem;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-background, #05070d);
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);
}

.callme__icon { font-size: 1.15rem; line-height: 1; }

/*
 * На узком экране — только значок: подпись рядом с ним съедала бы треть
 * ширины экрана ради слова, которое и так понятно по трубке.
 */
@media (max-width: 30rem) {
    .callme__word { display: none; }

    .callme__button { padding: 0.8rem; }
}

.callme__panel {
    position: absolute;
    right: 0;
    bottom: calc(100% + 0.6rem);
    width: min(20rem, calc(100vw - 2rem));
    padding: 1rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius, 0.6rem);

    /*
     * Фон непрозрачный, а не «панельный»: панель темы полупрозрачна
     * нарочно — она лежит в потоке, и сквозь неё виден узор страницы. Это
     * же окно висит поверх товаров, и сквозь него читались бы они.
     */
    background: var(--color-surface, var(--color-background, #fff));
    box-shadow: 0 12px 32px rgb(0 0 0 / 0.3);
}

.callme__title {
    margin: 0 0 0.7rem;
    font-weight: 600;
}

.callme__note {
    margin: 0.6rem 0 0;
    font-size: 0.85rem;
    color: var(--color-muted);
}

.callme__form .button { width: 100%; }


/*
 * Баннеры: своё объявление или чужая реклама.
 *
 * Картинка растягивается на ширину места и не вылезает за него: баннеры
 * приносят какие угодно, а место в боковой колонке узкое. Своей рамки у
 * баннера нет — он и так чужеродное пятно на странице, и обводить его
 * значит подчёркивать это ещё раз.
 */
.banners {
    display: grid;
    gap: 0.8rem;
    margin-bottom: var(--gap);
}

.banner img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius, 0.5rem);
}

/*
 * Чужой код бывает шире отведённого места — сети любят фиксированные
 * размеры. Обрезаем по месту, а не ломаем страницу: пусть лучше не
 * поместится баннер, чем разъедется вёрстка вокруг него.
 */
.banner { overflow: hidden; max-width: 100%; }

.banners--header,
.banners--footer { margin-inline: auto; }

/* Заглушка вместо картинки: тот же приём, что у товара без обложки.

   Не серое «нет фото», а первая буква крупно. Пустое место читается как
   поломка вёрстки; занятое место с буквой — как баннер, которому не
   донесли снимок. */
.banner-stub {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 4 / 1;
    background: var(--color-panel, rgba(127, 127, 127, .12));
    border-radius: var(--radius, 0.5rem);
    text-decoration: none;
}

.banner-stub__letter {
    font-size: clamp(1.8rem, 8vw, 3.2rem);
    font-weight: 700;
    line-height: 1;
    opacity: 0.45;
}

/* В боковой колонке заглушка ниже: на телефоне колонка едет во всю
   ширину, и три к двум занимают там пол-экрана под одну букву. */
.banners--sidebar .banner-stub { aspect-ratio: 2 / 1; }

/* Ссылка вокруг заглушки не должна подчёркивать букву. */
.banner__link { display: block; text-decoration: none; }

/* Слова со ссылкой — для тех, у кого картинки нет и не будет. */
.banner--text {
    display: grid;
    gap: 0.45rem;
    justify-items: start;
    padding: 0.9rem 1rem;
    background: var(--color-panel, rgba(127, 127, 127, .1));
    border-radius: var(--radius, 0.5rem);
}

.banner__title { font-size: 1.05rem; line-height: 1.3; }
.banner__text { margin: 0; opacity: 0.85; }

/* Размер задаёт высоту картинки и вес слов, а не ширину: ширину диктует
   место, в которое баннер поставили. */
.banner--small img,
.banner--small .banner-stub { max-height: 6rem; object-fit: cover; }

.banner--large img,
.banner--large .banner-stub { max-height: 22rem; object-fit: cover; }

.banner--small.banner--text { padding: 0.6rem 0.75rem; font-size: 0.92rem; }
.banner--large.banner--text { padding: 1.4rem 1.5rem; }
.banner--large .banner__title { font-size: 1.35rem; }

/* ------------------------------------------------- имя сайта на телефоне

   Здесь, в самом конце файла, а не рядом с остальной шапкой: общее правило
   ниже по файлу задаёт имени размер через clamp, и всё, что написано выше,
   оно перекрывает. Спорить с ним порядком правил честнее, чем «важностью».

   Кегль чуть мельче общего: в этой теме шрифт крупнее, а в строке шапки к
   имени добавились значок корзины и три языка — «Nex1on» переставало
   помещаться и обрывалось на «Nex1...». Разница в полторы точки не видна
   никому, а имя сайта целиком видно всем. */
@media (max-width: 30rem) {
    .brand-name { font-size: clamp(0.88rem, 3.5vw, 1rem); }
}

/* ========================================================================== */
/* Shop polish — карточки, фильтры и оформление заказа                        */
/* ========================================================================== */

.shop-search {
    position: relative;
    overflow: hidden;
    padding: clamp(0.9rem, 2vw, 1.2rem);
    border: 1px solid color-mix(in srgb, var(--color-accent) 22%, var(--color-border));
    border-radius: calc(var(--radius) + 4px);
    background:
        radial-gradient(circle at 0 0, color-mix(in srgb, var(--color-accent) 9%, transparent), transparent 42%),
        color-mix(in srgb, var(--color-surface) 92%, transparent);
    box-shadow: 0 18px 44px -38px color-mix(in srgb, var(--color-accent) 65%, transparent);
}

.shop-search__label {
    font-weight: 800;
    letter-spacing: -0.01em;
}

.shop-search__row,
.shop-search__price { position: relative; z-index: 1; }

.promises {
    gap: 0.65rem;
}

.promises__item {
    position: relative;
    overflow: hidden;
    min-height: 74px;
    padding: 0.85rem 0.95rem;
    border: 1px solid color-mix(in srgb, var(--color-accent) 16%, var(--color-border));
    border-radius: var(--radius);
    background: linear-gradient(145deg,
        color-mix(in srgb, var(--color-surface) 96%, transparent),
        color-mix(in srgb, var(--color-accent) 3%, var(--color-surface)));
}

.promises__item::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 2px;
    background: color-mix(in srgb, var(--color-accent) 55%, transparent);
}

.promises__title { font-size: 0.92rem; }
.promises__note { margin-top: 0.18rem; }

.goods {
    gap: clamp(0.8rem, 2vw, 1.15rem);
}

.good {
    position: relative;
    overflow: hidden;
    background: linear-gradient(160deg,
        color-mix(in srgb, var(--color-surface) 98%, transparent),
        color-mix(in srgb, var(--color-accent) 2.5%, var(--color-surface)));
    box-shadow: 0 16px 34px -30px rgb(0 0 0 / 0.9);
    transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.good::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--color-accent) 55%, transparent),
        transparent);
    opacity: 0;
    transition: opacity 0.18s ease;
}

.good:hover,
.good:focus-within {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--color-accent) 45%, var(--color-border));
    box-shadow: 0 24px 46px -34px color-mix(in srgb, var(--color-accent) 50%, rgb(0 0 0 / 0.9));
}

.good:hover::after,
.good:focus-within::after { opacity: 1; }

.good__cover img {
    transition: transform 0.28s ease, filter 0.28s ease;
}

.good:hover .good__cover img,
.good:focus-within .good__cover img {
    transform: scale(1.025);
}

.good__title a { color: var(--color-text); }
.good__title a:hover { color: var(--color-accent); }

.good-page {
    padding: clamp(0.8rem, 2vw, 1.2rem);
    border: 1px solid color-mix(in srgb, var(--color-accent) 18%, var(--color-border));
    border-radius: calc(var(--radius) + 4px);
    background: linear-gradient(150deg,
        color-mix(in srgb, var(--color-surface) 97%, transparent),
        color-mix(in srgb, var(--color-accent) 2%, var(--color-surface)));
    box-shadow: 0 24px 54px -46px color-mix(in srgb, var(--color-accent) 50%, transparent);
}

.good-page__cover {
    overflow: hidden;
    border-radius: var(--radius);
}

.order-line {
    gap: 0.3rem;
    padding: 0.35rem;
    border: 1px solid color-mix(in srgb, var(--color-accent) 12%, var(--color-border));
    border-radius: calc(var(--radius) + 2px);
    background: color-mix(in srgb, var(--color-surface) 78%, transparent);
}

.order-line__item {
    padding: 0.38rem 0.65rem;
    border-radius: calc(var(--radius) - 2px);
}

.order-line__item.is-current {
    background: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-accent) 20%, transparent);
}

.checkout__summary {
    border: 1px solid color-mix(in srgb, var(--color-accent) 18%, var(--color-border));
    background: linear-gradient(145deg,
        color-mix(in srgb, var(--color-surface) 96%, transparent),
        color-mix(in srgb, var(--color-accent) 3%, var(--color-surface)));
}

.checkout__total {
    padding-top: 0.85rem;
    border-top: 1px solid color-mix(in srgb, var(--color-accent) 18%, var(--color-border));
}

.checkout__way {
    transition: transform 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}

.checkout__way:hover { transform: translateY(-1px); }

.checkout__promo {
    padding-top: 0.75rem;
    border-top: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
}

.tabs {
    scrollbar-width: thin;
}

@media (prefers-reduced-motion: reduce) {
    .good,
    .good__cover img,
    .checkout__way { transition: none; }

    .good:hover,
    .good:focus-within,
    .checkout__way:hover { transform: none; }
}

@media (max-width: 42rem) {
    .shop-search__row { align-items: stretch; flex-direction: column; }

    /*
     * Базис «12rem» здесь перестаёт быть шириной и становится высотой:
     * ось у колонки другая. Поле вырастало до 192 точек — почти четверть
     * экрана под одну строку. Высоту задаёт содержимое, как у всех полей.
     */
    .shop-search__row .input { flex: 0 0 auto; }
    .shop-search__row .button { width: 100%; }
    .shop-search__price { align-items: stretch; }
    .good:hover,
    .good:focus-within { transform: none; }
}


/* ========================================================================== */
/* Forum 2.3 — собственная визуальная система форума                           */
/* ========================================================================== */

.forum-sections,
.forum-topics { display:grid; gap:.7rem; }

.forum-category {
    display:flex;
    align-items:baseline;
    gap:.75rem;
    margin:1.35rem 0 .15rem;
    padding:.45rem .15rem .65rem;
    border-bottom:1px solid var(--color-line-strong);
    color:var(--color-text);
    font-size:1.05rem;
    letter-spacing:-.02em;
}

.forum-category:first-child { margin-top:.25rem; }
.forum-category .field__hint { margin-left:auto; font-size:.78rem; font-weight:400; }

.forum-section {
    position:relative;
    display:grid;
    grid-template-columns:auto minmax(0,1fr) minmax(190px,28%);
    align-items:center;
    gap:1rem;
    margin:0;
    padding:1rem;
    overflow:hidden;
    border:1px solid var(--color-line);
    border-radius:var(--radius);
    background:color-mix(in srgb,var(--color-surface) 94%,var(--color-accent) 1.5%);
    transition:border-color .15s ease, transform .15s ease, background .15s ease;
}

.forum-section::before {
    content:"";
    position:absolute;
    inset:0 auto 0 0;
    width:2px;
    background:color-mix(in srgb,var(--color-accent) 52%,transparent);
}

.forum-section:hover {
    transform:translateY(-1px);
    border-color:color-mix(in srgb,var(--color-accent) 36%,var(--color-line));
    background:color-mix(in srgb,var(--color-surface) 91%,var(--color-accent) 3%);
}

.forum-section--inside { margin-left:1.5rem; }
.forum-section__icon {
    display:grid;
    place-items:center;
    width:42px;
    height:42px;
    border:1px solid color-mix(in srgb,var(--color-accent) 28%,var(--color-line));
    border-radius:calc(var(--radius) - 2px);
    background:color-mix(in srgb,var(--color-accent) 7%,transparent);
    color:var(--color-accent);
    font-size:1rem;
}
.forum-section .feed-item__title { margin-bottom:.25rem; font-size:1rem; }
.forum-section .feed-item__lead { margin:.25rem 0 .45rem; color:var(--color-muted); font-size:.85rem; }
.forum-section .feed-item__meta { display:flex; flex-wrap:wrap; gap:.55rem .85rem; margin:0; font-size:.75rem; }
.forum-section__last {
    min-width:0;
    padding:.7rem .8rem;
    border-left:1px solid var(--color-line);
}
.forum-section__last > a { display:block; overflow:hidden; font-weight:700; text-overflow:ellipsis; white-space:nowrap; }
.forum-section__last .field__hint { display:block; margin-top:.25rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.forum-bar {
    gap:.6rem;
    padding:.65rem;
    border:1px solid var(--color-line);
    border-radius:var(--radius);
    background:color-mix(in srgb,var(--color-surface) 96%,var(--color-accent) 1.5%);
}

.forum-filters {
    margin:0 0 1rem;
    padding:.8rem;
    border:1px solid var(--color-line);
    border-radius:var(--radius);
    background:color-mix(in srgb,var(--color-surface) 96%,var(--color-accent) 1.5%);
}
.forum-filters__head { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:.65rem; }
.forum-filters__head strong { display:block; font-size:.88rem; }
.forum-filters__head .field__hint { display:block; margin-top:.1rem; font-size:.72rem; }
.forum-filters__reset { color:var(--color-muted); font-size:.76rem; text-decoration:none; }
.forum-filters__reset:hover { color:var(--color-accent); text-decoration:underline; }
.forum-filters__grid { display:grid; grid-template-columns:repeat(5,minmax(125px,1fr)) auto; align-items:end; gap:.55rem; }
.forum-filters__grid label { display:grid; gap:.28rem; min-width:0; color:var(--color-muted); font-size:.7rem; font-weight:700; }
.forum-filters__grid .input { min-width:0; width:100%; }

.forum-topic {
    position:relative;
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(180px,24%);
    gap:.9rem;
    margin:0;
    padding:.9rem 1rem;
    border:1px solid var(--color-line);
    border-radius:var(--radius);
    background:color-mix(in srgb,var(--color-surface) 96%,var(--color-accent) 1%);
    transition:border-color .14s ease, background .14s ease;
}
.forum-topic:hover { border-color:color-mix(in srgb,var(--color-accent) 30%,var(--color-line)); background:color-mix(in srgb,var(--color-surface) 93%,var(--color-accent) 2.5%); }
.forum-topic--pinned { border-color:color-mix(in srgb,var(--color-accent) 42%,var(--color-line)); }
.forum-topic--pinned::before { content:""; position:absolute; inset:0 auto 0 0; width:2px; background:var(--color-accent); }
.forum-topic .feed-item__title { display:flex; align-items:center; flex-wrap:wrap; gap:.35rem; margin:0 0 .35rem; font-size:.98rem; line-height:1.45; }
.forum-topic .feed-item__title > a { font-weight:750; }
.forum-topic .feed-item__meta { display:flex; flex-wrap:wrap; gap:.55rem .85rem; margin:0; font-size:.73rem; }
.forum-topic__type { opacity:.78; }
.forum-topic__last { align-self:center; min-width:0; margin:0; padding-left:.85rem; border-left:1px solid var(--color-line); }
.forum-topic__last-who, .forum-topic__last-link { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.forum-topic__last-who { color:var(--color-text); font-weight:650; }
.forum-topic__last-link { margin-top:.2rem; }

.forum-posts { gap:.8rem; }
.forum-post {
    margin:0;
    padding:0;
    overflow:hidden;
    border:1px solid var(--color-line);
    border-radius:var(--radius);
    background:color-mix(in srgb,var(--color-surface) 97%,var(--color-accent) 1%);
}
.forum-post--solution { border-color:color-mix(in srgb,var(--color-success) 52%,var(--color-line)); box-shadow:inset 3px 0 0 color-mix(in srgb,var(--color-success) 80%,transparent); }
.forum-post .feed-item__body { padding:.95rem 1rem; }
.forum-post__head {
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:.35rem .6rem;
    margin:-.95rem -1rem .8rem;
    padding:.65rem 1rem;
    border-bottom:1px solid var(--color-line);
    background:color-mix(in srgb,var(--color-surface) 94%,var(--color-accent) 2%);
}
.forum-post__body { min-height:3rem; line-height:1.65; }
.forum-post__actions { margin:.9rem -1rem -.95rem; padding:.6rem 1rem; border-top:1px solid var(--color-line); background:color-mix(in srgb,var(--color-surface) 96%,var(--color-accent) 1%); }
.forum-manage { border:1px solid var(--color-line); border-radius:var(--radius); background:color-mix(in srgb,var(--color-surface) 96%,var(--color-accent) 1%); }

@media (max-width: 70rem) {
    .forum-filters__grid { grid-template-columns:repeat(3,minmax(0,1fr)); }
    .forum-section { grid-template-columns:auto minmax(0,1fr); }
    .forum-section__last { grid-column:2; padding:.65rem 0 0; border-left:0; border-top:1px solid var(--color-line); }
}

@media (max-width: 48rem) {
    .forum-category { display:block; }
    .forum-category .field__hint { display:block; margin:.2rem 0 0; }
    .forum-section, .forum-topic { grid-template-columns:minmax(0,1fr); }
    .forum-section__icon { display:none; }
    .forum-section--inside { margin-left:.5rem; }
    .forum-section__last, .forum-topic__last { grid-column:auto; padding:.6rem 0 0; border-left:0; border-top:1px solid var(--color-line); }
    .forum-filters__grid { grid-template-columns:repeat(2,minmax(0,1fr)); }
    .forum-filters__grid .button { width:100%; }
}

@media (max-width: 32rem) {
    .forum-filters__head { align-items:flex-start; }
    .forum-filters__grid { grid-template-columns:minmax(0,1fr); }
}

/* ========================================================================
   Comments 1.2 — discussion / reviews
   ======================================================================== */
.comments-v2 { --comments-line:var(--color-line,var(--color-border)); --comments-line-strong:var(--color-line-strong,var(--color-border-strong)); --comments-tint:var(--color-tint,color-mix(in srgb,var(--color-accent) 6%,var(--color-surface))); overflow:visible; }
.comments-v2__header { display:flex; align-items:flex-end; justify-content:space-between; gap:1rem; padding-bottom:1rem; border-bottom:1px solid var(--comments-line); }
.comments-v2__kicker { display:block; margin-bottom:.18rem; color:var(--color-accent); font:600 .68rem/1.2 var(--font-mono,monospace); letter-spacing:.11em; text-transform:uppercase; }
.comments-v2__header h2 { margin:0; display:flex; align-items:center; gap:.55rem; }
.comments-v2__header h2 > span { display:inline-grid; place-items:center; min-width:1.8rem; height:1.45rem; padding:0 .38rem; border:1px solid var(--comments-line); border-radius:999px; color:var(--color-muted); font:500 .7rem var(--font-mono,monospace); }
.comments-rating-summary { display:flex; align-items:center; gap:.65rem; min-width:max-content; }
.comments-rating-summary > strong { font-size:2rem; line-height:1; color:var(--color-text); }
.comments-rating-summary > div { display:grid; }
.comments-rating-summary span { color:var(--color-warning,var(--color-accent-soft)); letter-spacing:.06em; }
.comments-rating-summary small { color:var(--color-muted); }
.comments-sort { display:flex; align-items:center; justify-content:flex-end; gap:.3rem; padding:.65rem 0; color:var(--color-muted); font-size:.8rem; }
.comments-sort > span { margin-right:.2rem; }
.comments-sort a { padding:.3rem .55rem; border:1px solid transparent; border-radius:999px; color:var(--color-muted); text-decoration:none; }
.comments-sort a:hover { color:var(--color-text); }
.comments-sort a.is-active { color:var(--color-accent); border-color:var(--comments-line); background:var(--comments-tint); }
.comments-v2__list { display:grid; gap:.7rem; padding:.45rem 0 .9rem; }
.comment-card { display:grid; grid-template-columns:2.7rem minmax(0,1fr); gap:.75rem; padding:1rem; border:1px solid var(--comments-line); border-radius:var(--radius); background:color-mix(in srgb,var(--color-surface) 94%,transparent); scroll-margin-top:5rem; transition:border-color .15s ease,transform .15s ease; }
.comment-card:target { border-color:var(--color-accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--color-accent) 10%,transparent); }
.comment-card--reply { margin-left:calc(3rem * var(--comment-level, 1)); border-left-color:color-mix(in srgb,var(--color-accent) 45%,var(--comments-line)); background:color-mix(in srgb,var(--comments-tint) 55%,var(--color-surface)); }
.comment-card__avatar { display:grid; place-items:center; width:2.7rem; height:2.7rem; border:1px solid color-mix(in srgb,var(--color-accent) 25%,var(--comments-line)); border-radius:50%; background:color-mix(in srgb,var(--color-accent) 8%,var(--color-surface)); color:var(--color-accent); font:700 .72rem var(--font-mono,monospace); }
.comment-card__content { min-width:0; }
.comment-card__head { display:flex; align-items:flex-start; justify-content:space-between; gap:.7rem; }
.comment-card__author { display:flex; align-items:center; gap:.45rem; flex-wrap:wrap; }
.comment-card__author strong { color:var(--color-text); }
.comment-verified { display:inline-flex; align-items:center; min-height:1.35rem; padding:.15rem .42rem; border:1px solid color-mix(in srgb,var(--color-success) 35%,var(--comments-line)); border-radius:999px; background:color-mix(in srgb,var(--color-success) 7%,transparent); color:var(--color-success); font:600 .64rem var(--font-mono,monospace); white-space:nowrap; }
.comment-card__time { display:flex; align-items:center; gap:.25rem; flex-wrap:wrap; justify-content:flex-end; color:var(--color-muted); font-size:.74rem; }
.comment-permalink { color:var(--color-faint); text-decoration:none; font:700 .75rem var(--font-mono,monospace); }
.comment-permalink:hover { color:var(--color-accent); }
.comment-stars { display:flex; align-items:center; gap:.35rem; margin:.38rem 0; color:var(--color-warning,var(--color-accent-soft)); letter-spacing:.04em; }
.comment-stars i { color:var(--comments-line-strong); font-style:normal; }
.comment-stars b { margin-left:.18rem; color:var(--color-muted); font:600 .7rem var(--font-mono,monospace); letter-spacing:0; }
.comment-card__body { padding:.2rem 0; color:var(--color-text); line-height:1.65; overflow-wrap:anywhere; }
.comment-card__actions { display:flex; align-items:center; gap:.75rem; flex-wrap:wrap; margin-top:.55rem; color:var(--color-muted); font-size:.78rem; }
.comment-card__actions a,.comment-action-link { padding:0; border:0; background:none; color:var(--color-accent); text-decoration:none; font:inherit; cursor:pointer; }
.comment-action-link--danger { color:var(--color-danger); }
.comment-inline-form { display:inline; margin:0; }
.comment-edit-form { display:grid; gap:.55rem; margin-top:.7rem; padding:.7rem; border:1px solid var(--comments-line); border-radius:calc(var(--radius) * .75); background:var(--comments-tint); }
.comment-edit-form[hidden] { display:none!important; }
.comment-edit-form textarea { width:100%; resize:vertical; padding:.7rem; border:1px solid var(--comments-line-strong); border-radius:calc(var(--radius) * .6); background:var(--color-surface); color:var(--color-text); font:inherit; }
.comment-edit-form > div { display:flex; gap:.45rem; flex-wrap:wrap; }
.comment-edit-form small { color:var(--color-muted); }
.comments-empty { display:grid; place-items:center; text-align:center; min-height:10rem; padding:2rem 1rem; color:var(--color-muted); }
.comments-empty > span { display:grid; place-items:center; width:3rem; height:3rem; margin-bottom:.5rem; border:1px solid var(--comments-line); border-radius:50%; color:var(--color-accent); font-size:1.4rem; }
.comments-empty strong { color:var(--color-text); }
.comments-empty p { margin:.3rem 0 0; }
.comments-compose { display:grid; gap:.85rem; margin-top:1rem; padding:1rem; border:1px solid var(--comments-line); border-radius:var(--radius); background:var(--comments-tint); }
.comments-compose__head { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; }
.comments-compose__head h3 { margin:.1rem 0 0; }
.comments-compose__moderation { padding:.28rem .5rem; border:1px solid color-mix(in srgb,var(--color-warning) 35%,var(--comments-line)); border-radius:999px; color:var(--color-warning); font-size:.7rem; white-space:nowrap; }
.comments-compose__guest { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.8rem; }
.comments-replying { display:flex; align-items:center; justify-content:space-between; gap:.7rem; padding:.6rem .7rem; border-left:2px solid var(--color-accent); background:color-mix(in srgb,var(--color-accent) 7%,transparent); color:var(--color-muted); }
.comments-replying[hidden] { display:none!important; }
.comments-rating-input { margin:0; padding:.75rem; border:1px solid var(--comments-line); border-radius:calc(var(--radius) * .75); }
.comments-rating-input legend { padding:0 .25rem; color:var(--color-text); font-weight:600; }
.comments-rating-input__stars { display:flex; gap:.18rem; align-items:center; }
.comments-rating-input__stars label { position:relative; display:grid; place-items:center; min-width:2.45rem; min-height:2.45rem; cursor:pointer; border:1px solid transparent; border-radius:calc(var(--radius) * .7); transition:.12s ease; }
.comments-rating-input__stars input { position:absolute; opacity:0; pointer-events:none; }
.comments-rating-input__stars span { font-size:1.55rem; line-height:1; color:var(--comments-line-strong); transition:.12s ease; }
.comments-rating-input__stars small { position:absolute; inset:auto 0 .12rem; text-align:center; opacity:0; color:var(--color-muted); font-size:.55rem; }
.comments-rating-input__stars label:hover,.comments-rating-input__stars label:focus-within { border-color:var(--comments-line); background:var(--color-surface); }
.comments-rating-input__stars label:hover span,.comments-rating-input__stars label.is-selected span { color:var(--color-warning,var(--color-accent-soft)); transform:scale(1.06); }
.comments-rating-input__stars label:focus-within { outline:2px solid color-mix(in srgb,var(--color-accent) 40%,transparent); outline-offset:2px; }
.comments-rating-input > p { margin:.35rem 0 0; color:var(--color-muted); font-size:.78rem; }
.comments-compose__submit { display:flex; align-items:center; justify-content:space-between; gap:.8rem; }
.comments-compose__submit small { color:var(--color-muted); }
.comments-login-note { margin-top:.8rem; padding:.75rem; border:1px solid var(--comments-line); background:var(--comments-tint); color:var(--color-muted); }
@media (max-width:720px) {
    .comments-v2__header { align-items:flex-start; }
    .comments-rating-summary { align-items:flex-start; }
    .comment-card { grid-template-columns:2.2rem minmax(0,1fr); padding:.8rem; gap:.6rem; }
    .comment-card__avatar { width:2.2rem; height:2.2rem; }
    .comment-card--reply { margin-left:calc(1.3rem * var(--comment-level, 1)); }
    .comment-card__head { flex-direction:column; gap:.25rem; }
    .comment-card__time { justify-content:flex-start; }
    .comments-compose__guest { grid-template-columns:1fr; }
}
@media (max-width:500px) {
    .comments-v2__header { flex-direction:column; }
    .comments-sort { justify-content:flex-start; overflow-x:auto; }
    .comment-card { grid-template-columns:1fr; }
    .comment-card__avatar { display:none; }
    .comment-card--reply { margin-left:calc(.65rem * var(--comment-level, 1)); }
    .comments-compose { padding:.8rem; }
    .comments-compose__head,.comments-compose__submit { align-items:flex-start; flex-direction:column; }
    .comments-rating-input__stars label { min-width:2.2rem; }
}
.comments-v2 .comment-card { box-shadow:var(--shadow-panel); }
.comments-v2 .comment-card:hover { transform:translateY(-1px); box-shadow:var(--shadow-lift); }

/* ========================================================================
   News 1.2 — editorial feed
   ======================================================================== */
.news-hero{position:relative;display:flex;align-items:flex-end;justify-content:space-between;gap:1.5rem;margin:0 0 1.25rem;padding:clamp(1.2rem,3vw,2rem);overflow:hidden;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:var(--radius);background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent) 8%,var(--color-surface)),var(--color-surface) 62%,color-mix(in srgb,var(--color-accent-soft) 5%,var(--color-surface)))}
.news-hero::after{content:"";position:absolute;right:-4rem;top:-6rem;width:14rem;height:14rem;border:1px solid color-mix(in srgb,var(--color-accent) 22%,transparent);border-radius:50%;pointer-events:none}.news-hero__copy{position:relative;z-index:1;max-width:58rem}.news-kicker{display:block;margin-bottom:.45rem;color:var(--color-accent);font-size:.72rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.news-hero h1{margin:0;font-size:clamp(2rem,5vw,3.8rem);line-height:1.02;letter-spacing:-.035em}.news-hero p{max-width:50rem;margin:.75rem 0 0;color:var(--color-muted);font-size:clamp(.95rem,1.7vw,1.1rem);line-height:1.6}.news-rss{position:relative;z-index:1;display:grid;min-width:7.5rem;padding:.8rem .9rem;border:1px solid color-mix(in srgb,var(--color-accent) 28%,transparent);border-radius:calc(var(--radius) + 2px);background:color-mix(in srgb,var(--color-accent) 5%,var(--color-surface));text-decoration:none}.news-rss>span{color:var(--color-accent);font-size:1.05rem;font-weight:900;letter-spacing:.08em}.news-rss small{margin-top:.15rem;color:var(--color-muted);font-size:.72rem}
.news-categories{display:flex;gap:.45rem;margin:0 0 1.15rem;padding-bottom:.25rem;overflow-x:auto;scrollbar-width:thin}.news-category{display:flex;align-items:center;gap:.5rem;flex:0 0 auto;padding:.55rem .75rem;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:999px;background:var(--color-surface);color:var(--color-muted);text-decoration:none;font-size:.82rem}.news-category b{display:grid;place-items:center;min-width:1.35rem;height:1.35rem;padding:0 .3rem;border-radius:999px;background:color-mix(in srgb,var(--color-text) 7%,transparent);color:var(--color-text);font-size:.68rem}.news-category:hover,.news-category.is-active{border-color:color-mix(in srgb,var(--color-accent) 40%,transparent);color:var(--color-accent);background:color-mix(in srgb,var(--color-accent) 6%,var(--color-surface))}.news-category.is-active b{background:color-mix(in srgb,var(--color-accent) 12%,transparent);color:var(--color-accent)}
.news-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(14rem,18rem);gap:1.4rem;align-items:start}.news-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}.news-card{display:flex;min-width:0;overflow:hidden;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:var(--radius);background:var(--color-surface);box-shadow:var(--shadow-panel,none);transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.news-card:hover{transform:translateY(-2px);border-color:color-mix(in srgb,var(--color-accent) 35%,transparent)}.news-card:not(.news-card--lead){flex-direction:column}.news-card--lead{grid-column:1/-1;min-height:20rem}.news-card--lead.has-cover{display:grid;grid-template-columns:minmax(16rem,.9fr) minmax(0,1.1fr)}.news-card__cover{display:block;min-height:10rem;overflow:hidden;background:color-mix(in srgb,var(--color-text) 5%,var(--color-surface))}.news-card--lead .news-card__cover{min-height:100%}.news-card__cover img{width:100%;height:100%;object-fit:cover;transition:transform .3s ease}.news-card:hover .news-card__cover img{transform:scale(1.025)}.news-card__body{display:flex;flex:1;flex-direction:column;padding:1rem 1.05rem}.news-card--lead .news-card__body{justify-content:center;padding:clamp(1.2rem,3vw,2rem)}.news-card__meta{display:flex;align-items:center;flex-wrap:wrap;gap:.35rem .6rem;margin-bottom:.55rem;color:var(--color-faint);font-size:.73rem}.news-card__meta a{color:var(--color-accent);text-decoration:none}.news-badge{display:inline-flex;align-items:center;padding:.24rem .45rem;border-radius:999px;background:color-mix(in srgb,var(--color-accent) 10%,transparent);color:var(--color-accent);font-size:.69rem;font-weight:800;text-decoration:none}.news-card h2{margin:0 0 .55rem;font-size:clamp(1.15rem,2.3vw,1.45rem);line-height:1.24;letter-spacing:-.015em}.news-card--lead h2{font-size:clamp(1.55rem,3.3vw,2.5rem)}.news-card h2 a{color:var(--color-text);text-decoration:none}.news-card p{display:-webkit-box;overflow:hidden;margin:0 0 .9rem;color:var(--color-muted);line-height:1.6;-webkit-line-clamp:3;-webkit-box-orient:vertical}.news-card--lead p{-webkit-line-clamp:4}.news-card__foot{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-top:auto;color:var(--color-faint);font-size:.74rem}.news-card__foot>a{font-weight:700;text-decoration:none}.news-card__foot>a span{display:inline-block;transition:transform .15s ease}.news-card__foot>a:hover span{transform:translateX(.2rem)}
.news-archive{position:sticky;top:1rem;padding:.9rem;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:var(--radius);background:var(--color-surface);box-shadow:var(--shadow-panel,none)}.news-archive__head{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.65rem;align-items:center;padding:.2rem .15rem .75rem;border-bottom:1px solid color-mix(in srgb,var(--color-text) 10%,transparent)}.news-archive__head>span{display:grid;place-items:center;width:2rem;height:2rem;border-radius:50%;background:color-mix(in srgb,var(--color-accent) 9%,transparent);color:var(--color-accent)}.news-archive__head strong,.news-archive__head small{display:block}.news-archive__head small{margin-top:.1rem;color:var(--color-muted);font-size:.68rem}.news-archive__months{display:grid}.news-archive__months a{display:flex;align-items:center;justify-content:space-between;gap:.7rem;padding:.58rem .2rem;border-bottom:1px solid color-mix(in srgb,var(--color-text) 8%,transparent);color:var(--color-muted);font-size:.78rem;text-decoration:none}.news-archive__months a:last-child{border-bottom:0}.news-archive__months a:hover,.news-archive__months a.is-active{color:var(--color-accent)}.news-archive__months b{color:var(--color-faint);font-size:.68rem}.news-empty{display:grid;place-items:center;min-height:18rem;padding:2rem;border:1px dashed color-mix(in srgb,var(--color-text) 16%,transparent);border-radius:var(--radius);text-align:center}.news-empty>span{color:var(--color-accent);font-size:2.2rem}.news-empty h2{margin:.5rem 0 .25rem}.news-empty p{margin:0;color:var(--color-muted)}.news-pager{display:grid;grid-template-columns:1fr auto 1fr;gap:.8rem;align-items:center;margin-top:1.25rem;padding-top:1rem;border-top:1px solid color-mix(in srgb,var(--color-text) 10%,transparent)}.news-pager>a:last-child{text-align:right}.news-pager b{color:var(--color-faint);font-size:.75rem;font-weight:500}
.news-breadcrumbs{display:flex;align-items:center;gap:.4rem;overflow:hidden;margin:0 0 1rem;color:var(--color-faint);font-size:.78rem}.news-breadcrumbs a{flex:0 0 auto;text-decoration:none}.news-breadcrumbs>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.news-article{max-width:62rem;margin:0 auto}.news-article__head{padding:clamp(1rem,3vw,2rem) 0 1.25rem}.news-article__meta{display:flex;align-items:center;flex-wrap:wrap;gap:.35rem .55rem;color:var(--color-faint);font-size:.76rem}.news-article__head h1{max-width:58rem;margin:.75rem 0 0;font-size:clamp(2rem,5.5vw,4rem);line-height:1.02;letter-spacing:-.04em}.news-article__lead{max-width:52rem;margin:1rem 0 0;color:var(--color-muted);font-size:clamp(1rem,2vw,1.2rem);line-height:1.65}.news-article__author{display:flex;align-items:center;gap:.6rem;margin-top:1.05rem}.news-article__author>span{display:grid;place-items:center;width:2.25rem;height:2.25rem;border-radius:50%;background:color-mix(in srgb,var(--color-accent) 10%,transparent);color:var(--color-accent);font-size:.8rem}.news-article__author small,.news-article__author strong{display:block}.news-article__author small{color:var(--color-faint);font-size:.65rem;text-transform:uppercase;letter-spacing:.08em}.news-article__author strong{margin-top:.05rem;font-size:.8rem}.news-article__cover{margin:0 0 1.25rem;overflow:hidden;border-radius:var(--radius);background:var(--color-surface)}.news-article__cover img{display:block;width:100%;max-height:38rem;object-fit:cover}.news-article__cover figcaption{padding:.55rem .75rem;color:var(--color-faint);font-size:.72rem}.news-article__body{font-size:1rem;line-height:1.78}.news-article__body>*:first-child{margin-top:0}.news-article__body p{margin:0 0 1.15rem}.news-article__body h2,.news-article__body h3{margin:1.8rem 0 .7rem;line-height:1.2}.news-article__body blockquote{margin:1.4rem 0;padding:.85rem 1rem;border-inline-start:3px solid var(--color-accent);background:color-mix(in srgb,var(--color-accent) 5%,var(--color-surface));color:var(--color-muted)}.news-neighbours{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.8rem;max-width:62rem;margin:1.6rem auto 0}.news-neighbours>a{display:grid;gap:.28rem;padding:.85rem 1rem;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:var(--radius);background:var(--color-surface);text-decoration:none}.news-neighbours>a:hover{border-color:color-mix(in srgb,var(--color-accent) 35%,transparent)}.news-neighbours span{color:var(--color-faint);font-size:.68rem}.news-neighbours strong{color:var(--color-text);line-height:1.35}.news-neighbours .is-next{text-align:right}.news-back{max-width:62rem;margin:1rem auto 0;font-size:.82rem}
.news-home{margin-bottom:var(--gap)}.news-home__layout{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(15rem,.75fr);gap:1rem}.news-home__lead{display:flex;min-width:0;overflow:hidden;border:1px solid color-mix(in srgb,var(--color-text) 12%,transparent);border-radius:var(--radius);background:var(--color-surface)}.news-home__lead.has-cover{display:grid;grid-template-columns:minmax(12rem,.85fr) minmax(0,1.15fr)}.news-home__cover{display:block;min-height:12rem;overflow:hidden}.news-home__cover img{width:100%;height:100%;object-fit:cover}.news-home__lead-body{display:flex;flex-direction:column;justify-content:center;padding:1rem 1.1rem}.news-home time{color:var(--color-faint);font-size:.68rem}.news-home h3{margin:.35rem 0 .5rem;font-size:clamp(1.2rem,2.5vw,1.65rem);line-height:1.25}.news-home h3 a,.news-home h4 a{color:var(--color-text);text-decoration:none}.news-home p{margin:0 0 .7rem;color:var(--color-muted);font-size:.85rem;line-height:1.5}.news-home__read{margin-top:auto;font-size:.78rem;font-weight:700;text-decoration:none}.news-home__more{display:grid;align-content:start}.news-home__more article{padding:.72rem 0;border-top:1px solid color-mix(in srgb,var(--color-text) 10%,transparent)}.news-home__more article:first-child{padding-top:0;border-top:0}.news-home__more h4{margin:.25rem 0 .35rem;font-size:.95rem;line-height:1.35}.news-home__more p{display:-webkit-box;overflow:hidden;margin:0;font-size:.76rem;-webkit-line-clamp:2;-webkit-box-orient:vertical}
@media(max-width:900px){.news-layout{grid-template-columns:minmax(0,1fr)}.news-archive{position:static}.news-archive__months{grid-template-columns:repeat(3,minmax(0,1fr));gap:0 .7rem}.news-home__layout{grid-template-columns:minmax(0,1fr)}.news-home__more{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 1rem}.news-home__more article:nth-child(2){border-top:0;padding-top:0}}
@media(max-width:680px){.news-hero{align-items:flex-start;flex-direction:column}.news-rss{min-width:0}.news-grid{grid-template-columns:minmax(0,1fr)}.news-card--lead{grid-column:auto;min-height:0}.news-card--lead.has-cover{display:flex;flex-direction:column}.news-card--lead .news-card__cover{min-height:13rem}.news-card--lead h2{font-size:1.5rem}.news-archive__months{grid-template-columns:repeat(2,minmax(0,1fr))}.news-pager{grid-template-columns:1fr 1fr}.news-pager b{grid-row:2;grid-column:1/-1;text-align:center}.news-neighbours{grid-template-columns:minmax(0,1fr)}.news-neighbours .is-next{text-align:left}.news-home__lead.has-cover{display:flex;flex-direction:column}.news-home__cover{min-height:11rem}.news-home__more{grid-template-columns:minmax(0,1fr)}.news-home__more article:nth-child(2){border-top:1px solid color-mix(in srgb,var(--color-text) 10%,transparent);padding-top:.72rem}}
@media(prefers-reduced-motion:reduce){.news-card,.news-card__cover img,.news-card__foot>a span{transition:none}.news-card:hover{transform:none}.news-card:hover .news-card__cover img{transform:none}}

/* Banners 1.2 */
.banners{display:grid;gap:.8rem;margin-bottom:var(--gap)}
.banner{position:relative;max-width:100%;overflow:hidden;border-radius:var(--radius,.5rem)}
.banner img{display:block;width:100%;height:auto;border-radius:inherit}
.banners--header,.banners--footer{margin-inline:auto}
.banner__link{display:block;text-decoration:none}
.banner__label{position:absolute;z-index:2;inset-block-start:.45rem;inset-inline-start:.45rem;padding:.2rem .42rem;border:1px solid color-mix(in srgb,currentColor 14%,transparent);border-radius:.3rem;background:color-mix(in srgb,var(--color-bg,#111) 78%,transparent);color:var(--color-muted);font-size:.66rem;line-height:1.2;backdrop-filter:blur(8px)}
.banner-stub{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:4/1;background:var(--color-panel,rgba(127,127,127,.12));border-radius:inherit;text-decoration:none}.banner-stub__letter{font-size:clamp(1.8rem,8vw,3.2rem);font-weight:700;line-height:1;opacity:.45}.banners--sidebar .banner-stub{aspect-ratio:2/1}
.banner--text{display:grid;gap:.5rem;justify-items:start;padding:1rem 1.05rem;border:1px solid color-mix(in srgb,var(--color-muted) 16%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--color-panel,rgba(127,127,127,.1)) 96%,transparent),color-mix(in srgb,var(--color-accent,currentColor) 5%,transparent));box-shadow:0 .35rem 1.2rem rgba(0,0,0,.05)}.banner--text .banner__label{position:static;margin-bottom:.1rem;background:transparent;backdrop-filter:none;padding:0;border:0;color:var(--color-muted);font-size:.68rem;text-transform:uppercase;letter-spacing:.08em}.banner__title{font-size:1.08rem;line-height:1.3}.banner__text{margin:0;max-width:60ch;color:var(--color-muted);line-height:1.55}.banner__button{margin-top:.15rem}.banner__html{max-width:100%;overflow:hidden}.banner--small img,.banner--small .banner-stub{max-height:6rem;object-fit:cover}.banner--large img,.banner--large .banner-stub{max-height:22rem;object-fit:cover}.banner--small.banner--text{padding:.68rem .8rem;font-size:.92rem}.banner--large.banner--text{padding:1.4rem 1.5rem}.banners--sidebar .banner--text{padding:.85rem}.banners--sidebar .banner__text{font-size:.92rem}
@media(max-width:42rem){.banners{gap:.6rem}.banner--large.banner--text{padding:1rem}.banner__label{font-size:.6rem}}

/* Banners 1.3 responsive creative */
.banner__picture{display:block;width:100%}.banner__picture>img{display:block;width:100%}

/* Downloads 1.2 — release catalog */
.downloads-hero{display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;margin:0 0 1.25rem;padding:clamp(1.3rem,3vw,2.3rem);border:1px solid color-mix(in srgb,var(--color-accent) 22%,transparent);border-radius:calc(var(--radius) + 6px);background:linear-gradient(135deg,color-mix(in srgb,var(--color-surface) 94%,transparent),color-mix(in srgb,var(--color-accent) 7%,var(--color-surface)))}.downloads-hero h1{margin:.15rem 0 .4rem;font-size:clamp(2rem,5vw,3.6rem);line-height:1}.downloads-hero p{margin:0;max-width:48rem;color:var(--color-muted)}.downloads-kicker{display:block;color:var(--color-accent);font:.72rem/1 var(--font-mono);font-weight:800;letter-spacing:.13em;text-transform:uppercase}.downloads-hero__stat{display:grid;min-width:110px;text-align:right}.downloads-hero__stat strong{font-size:2.2rem;line-height:1}.downloads-hero__stat span{color:var(--color-muted);font-size:.72rem}
.downloads-categories{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}.downloads-categories a{display:flex;align-items:center;gap:.45rem;padding:.55rem .8rem;border:1px solid color-mix(in srgb,var(--color-text) 14%,transparent);border-radius:999px;color:var(--color-muted);text-decoration:none;font-size:.82rem}.downloads-categories a span{color:var(--color-faint);font-size:.7rem}.downloads-categories a:hover,.downloads-categories a.is-active{border-color:color-mix(in srgb,var(--color-accent) 45%,transparent);background:color-mix(in srgb,var(--color-accent) 8%,transparent);color:var(--color-accent)}
.downloads-filter{display:grid;grid-template-columns:minmax(180px,1fr) minmax(160px,.4fr) auto auto;align-items:end;gap:.7rem;margin:0 0 1.2rem;padding:1rem;border:1px solid color-mix(in srgb,var(--color-text) 12%,transparent);border-radius:var(--radius);background:color-mix(in srgb,var(--color-surface) 82%,transparent)}.downloads-filter label{display:grid;gap:.35rem}.downloads-filter label>span{color:var(--color-muted);font-size:.7rem;font-weight:700}.downloads-filter input,.downloads-filter select{width:100%;padding:.65rem .75rem;border:1px solid color-mix(in srgb,var(--color-text) 16%,transparent);border-radius:var(--radius);background:var(--color-surface);color:var(--color-text);font:inherit}.downloads-filter__clear{padding:.55rem .7rem;color:var(--color-muted);text-decoration:none}
.downloads-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem}.downloads-card{display:flex;flex-direction:column;min-width:0;border:1px solid color-mix(in srgb,var(--color-text) 13%,transparent);border-radius:calc(var(--radius) + 4px);overflow:hidden;background:color-mix(in srgb,var(--color-surface) 92%,transparent);transition:transform .16s ease,border-color .16s ease}.downloads-card:hover{transform:translateY(-2px);border-color:color-mix(in srgb,var(--color-accent) 40%,transparent)}.downloads-card__visual{display:grid;place-items:center;aspect-ratio:16/7;overflow:hidden;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent) 10%,var(--color-surface)),var(--color-surface));color:var(--color-accent);font:800 1.25rem var(--font-mono);text-decoration:none}.downloads-card__visual img{width:100%;height:100%;object-fit:cover}.downloads-card__body{display:grid;gap:.55rem;padding:1rem;flex:1}.downloads-card__meta{display:flex;gap:.45rem;flex-wrap:wrap}.downloads-card__meta a,.downloads-card__meta span{padding:.2rem .45rem;border-radius:999px;background:color-mix(in srgb,var(--color-accent) 8%,transparent);color:var(--color-accent);font-size:.72rem;text-decoration:none}.downloads-card h2{margin:0;font-size:1.1rem;line-height:1.25}.downloads-card h2 a{color:var(--color-text);text-decoration:none}.downloads-card p{margin:0;color:var(--color-muted);font-size:.86rem;line-height:1.5}.downloads-card__facts{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:auto;color:var(--color-faint);font:.7rem var(--font-mono)}.downloads-card__actions{display:flex;align-items:center;justify-content:space-between;gap:.6rem;padding:.8rem 1rem;border-top:1px solid color-mix(in srgb,var(--color-text) 10%,transparent)}.downloads-card__actions>a:last-child{color:var(--color-muted);font-size:.78rem;text-decoration:none}.downloads-empty{display:grid;place-items:center;text-align:center;padding:4rem 1rem;border:1px dashed color-mix(in srgb,var(--color-text) 20%,transparent);border-radius:var(--radius)}.downloads-empty>span{font-size:2rem;color:var(--color-accent)}.downloads-empty h2{margin:.6rem 0 .2rem}.downloads-empty p{margin:0;color:var(--color-muted)}
.downloads-breadcrumbs{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem;color:var(--color-muted);font-size:.76rem}.downloads-breadcrumbs a{color:var(--color-accent);text-decoration:none}.download-release{display:grid;gap:1.2rem}.download-release__head{display:grid;grid-template-columns:minmax(0,1fr) minmax(220px,34%);gap:1.5rem;align-items:stretch;padding:clamp(1.25rem,3vw,2.2rem);border:1px solid color-mix(in srgb,var(--color-accent) 22%,transparent);border-radius:calc(var(--radius) + 6px);background:linear-gradient(135deg,color-mix(in srgb,var(--color-surface) 96%,transparent),color-mix(in srgb,var(--color-accent) 6%,var(--color-surface)))}.download-release__head figure{margin:0;min-height:220px;border-radius:var(--radius);overflow:hidden}.download-release__head figure img{width:100%;height:100%;object-fit:cover}.download-release__copy{align-self:center}.download-release__meta{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.65rem}.download-release__meta>*{padding:.25rem .5rem;border-radius:999px;background:color-mix(in srgb,var(--color-accent) 8%,transparent);color:var(--color-accent);font-size:.7rem}.download-release__head h1{margin:0 0 .65rem;font-size:clamp(2rem,5vw,3.6rem);line-height:1.02}.download-release__head p{margin:0;color:var(--color-muted);font-size:1rem;line-height:1.65}.download-release__stats{display:flex;gap:1.3rem;margin-top:1rem}.download-release__stats span{display:grid;color:var(--color-muted);font-size:.68rem}.download-release__stats b{color:var(--color-text);font-size:1.35rem;line-height:1.1}.download-release__files,.download-release__details>section{padding:1.15rem;border:1px solid color-mix(in srgb,var(--color-text) 12%,transparent);border-radius:calc(var(--radius) + 3px);background:color-mix(in srgb,var(--color-surface) 90%,transparent)}.download-release__sectionhead h2{margin:.25rem 0 1rem;font-size:1.25rem}.download-file-list{display:grid;gap:.55rem}.download-file-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:.8rem;padding:.85rem;border:1px solid color-mix(in srgb,var(--color-text) 11%,transparent);border-radius:var(--radius);color:var(--color-text);text-decoration:none;background:color-mix(in srgb,var(--color-background) 20%,var(--color-surface))}.download-file-row:hover{border-color:color-mix(in srgb,var(--color-accent) 42%,transparent)}.download-file-row__icon{display:grid;place-items:center;min-width:44px;height:44px;padding:0 .45rem;border-radius:calc(var(--radius) - 1px);background:color-mix(in srgb,var(--color-accent) 10%,transparent);color:var(--color-accent);font:800 .72rem var(--font-mono)}.download-file-row__main{display:grid;min-width:0}.download-file-row__main small{color:var(--color-muted);font-size:.72rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.download-file-row__hits{color:var(--color-muted);font:.7rem var(--font-mono)}.download-file-row__go{color:var(--color-accent);font-size:.78rem;font-weight:800}.download-release__details{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}.download-release__text{color:var(--color-muted);line-height:1.7}.download-release__text>:first-child{margin-top:0}.download-release__text>:last-child{margin-bottom:0}.downloads-back{margin-top:1rem}.downloads-back a{color:var(--color-muted);text-decoration:none}
.home-files__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem}.home-files__card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:.7rem;padding:.75rem;border:1px solid color-mix(in srgb,var(--color-text) 11%,transparent);border-radius:var(--radius);background:color-mix(in srgb,var(--color-surface) 78%,transparent)}.home-files__icon{display:grid;place-items:center;min-width:38px;height:38px;padding:0 .35rem;border-radius:calc(var(--radius) - 2px);background:color-mix(in srgb,var(--color-accent) 10%,transparent);color:var(--color-accent);font:800 .72rem var(--font-mono);text-decoration:none}.home-files__card>div{min-width:0}.home-files__name{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.home-files__meta{margin:.1rem 0 0!important}.home-files__download{display:grid;place-items:center;width:34px;height:34px;border-radius:999px;background:color-mix(in srgb,var(--color-accent) 9%,transparent);color:var(--color-accent);text-decoration:none;font-weight:900}
@media(max-width:60rem){.downloads-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.download-release__head{grid-template-columns:1fr}.download-release__head figure{order:-1;max-height:340px}.download-release__details{grid-template-columns:1fr}}
@media(max-width:42rem){.downloads-hero{align-items:flex-start;flex-direction:column}.downloads-hero__stat{text-align:left}.downloads-filter{grid-template-columns:1fr}.downloads-grid,.home-files__grid{grid-template-columns:1fr}.download-file-row{grid-template-columns:auto minmax(0,1fr) auto}.download-file-row__hits{grid-column:2}.download-file-row__go{grid-row:1/3;grid-column:3}.download-release__stats{flex-wrap:wrap}}


/*
 * Порядок в поиске по магазину: слово, цена, и только потом «Найти».
 *
 * На широком экране поле и кнопка стоят в строку, и это привычно: нажал
 * рядом с полем — искал по слову. На телефоне ряд разворачивается в
 * колонку, и кнопка оказывается посередине формы: слово, «Найти», цена
 * от и до. Человек доходит до кнопки раньше, чем до цены, жмёт её — и
 * отбор по цене остаётся незаполненным, хотя стоял прямо под ней.
 *
 * Кнопка отправляет всю форму разом, поэтому её место — в конце, под
 * последним полем. Ряд убираем из раскладки через display: contents:
 * поле и кнопка становятся детьми самой формы, и порядок им можно
 * назначить прямо. Разметку при этом не трогаем — на широком экране
 * ряд остаётся рядом.
 */
@media (max-width: 42rem) {
    .shop-search {
        display: flex;
        flex-direction: column;
        gap: 0.6rem;
    }

    .shop-search__label { order: 1; margin-bottom: 0; }
    .shop-search__row { display: contents; }
    .shop-search__row .input { order: 2; }
    .shop-search__price { order: 3; margin-top: 0; }
    .shop-search__row .button { order: 4; width: 100%; }

    /*
     * Цена — две строки «подпись : поле», а не текучая лента.
     *
     * В ряд «Цена от [поле] до [поле]» на узком экране не влезает, и
     * перенос рвёт его где придётся: подпись «до» уезжала вниз, а поле
     * оставалось наверху одиноким прямоугольником без объяснения, что в
     * него писать. Сетка держит подпись при своём поле всегда.
     */
    .shop-search__price {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        gap: 0.5rem 0.6rem;
        align-items: center;
    }

    .shop-search__price .input--small { max-width: none; }
    .shop-search__price .button { grid-column: 1 / -1; }
}

/* Подсказки поиска: список под полем, поверх страницы. */
.search-suggest {
    position: fixed;
    z-index: 90;
    max-height: 60vh;
    margin: 0;
    padding: .3rem;
    overflow-y: auto;
    list-style: none;
    border: 1px solid var(--color-border);
    border-radius: var(--radius, .6rem);
    background: var(--color-surface);
    box-shadow: 0 1.2rem 2.4rem rgba(0, 0, 0, .18);
}

.search-suggest li { margin: 0; }

.search-suggest a {
    display: flex;
    align-items: baseline;
    gap: .6rem;
    justify-content: space-between;
    padding: .5rem .65rem;
    border-radius: calc(var(--radius, .6rem) - .2rem);
    color: var(--color-text);
    text-decoration: none;
}

.search-suggest a:hover,
.search-suggest a:focus-visible { background: var(--color-surface-2, rgba(127, 127, 127, .12)); }

.search-suggest__section {
    flex: 0 0 auto;
    color: var(--color-muted);
    font-size: .78rem;
}


/* ==================================================================
   Shop 1.14 — catalogue + product detail
   ------------------------------------------------------------------
   Layout is shared, appearance still comes from the active theme tokens.
   ================================================================== */
.shop-breadcrumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .45rem;
    margin: .4rem 0 1.2rem;
    color: var(--color-faint);
    font-size: .84rem;
}
.shop-breadcrumbs a { color: var(--color-muted); }
.shop-breadcrumbs a:hover { color: var(--color-accent); }
.shop-breadcrumbs span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.shop-catalog-head {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: 2rem;
    margin-bottom: 1.35rem;
}
.shop-catalog-head h1 { margin-bottom: .35rem; font-size: clamp(2rem, 5vw, 3.35rem); }
.shop-catalog-head__intro { max-width: 54rem; color: var(--color-muted); }
.shop-catalog-head__intro > :last-child { margin-bottom: 0; }
.shop-catalog-head__count {
    display: grid;
    min-width: 8rem;
    text-align: right;
    color: var(--color-muted);
}
.shop-catalog-head__count strong { color: var(--color-text); font-size: 1.65rem; line-height: 1; }
.shop-catalog-head__count span { margin-top: .3rem; font-size: .78rem; }

.shop-benefits {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .65rem;
    margin: 0 0 1.35rem;
    padding: 0;
    list-style: none;
}
.shop-benefits li {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-width: 0;
    padding: .78rem .9rem;
    border: 1px solid var(--color-border);
    border-radius: calc(var(--radius) + 2px);
    background: color-mix(in srgb, var(--color-surface) 76%, transparent);
}
.shop-benefits__dot {
    width: .55rem;
    height: .55rem;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--color-accent);
    box-shadow: 0 0 0 .28rem color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.shop-benefits strong,
.shop-benefits small { display: block; }
.shop-benefits strong { font-size: .9rem; }
.shop-benefits small { margin-top: .1rem; color: var(--color-faint); font-size: .75rem; }

/*
 * Отбор — справа от товара, а не слева.
 *
 * Слева он съедал начало страницы: сперва человек видел «Цена от — до» и
 * список разделов, а товар начинался ниже. Владелец так и сказал: «блок
 * закрывает пол экрана». В новостях мы это уже проходили — архив стоял
 * врезкой посреди ленты и сужал её вдвое; место списков, по которым
 * ищут, — сбоку, а не перед тем, ради чего пришли.
 *
 * Меняем не разметку, а порядок в сетке: товар первым, отбор вторым.
 * Разметку трогать нельзя — в ней отбор идёт первым нарочно, чтобы тот,
 * кто ходит клавишами и читалкой, добирался до него без блужданий по
 * всему каталогу.
 *
 * На узком экране колонка одна, и тот же порядок кладёт отбор ПОД товар:
 * там это и нужно. Раньше на телефоне первым экраном была форма отбора.
 */
/* Без колонки отбора — во всю ширину. Двойной класс сильнее базового правила ниже: иначе
   «последний побеждает» и справа остаётся пустая невидимая колонка на 230px. */
.shop-catalog-layout.shop-catalog-layout--solo { grid-template-columns: 1fr; }
.shop-catalog-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(190px, 230px);
    gap: 1.35rem;
    align-items: start;
}
.shop-catalog-main { order: 1; }
.shop-filter-panel { order: 2; }
.shop-filter-panel {
    position: sticky;
    top: 5.3rem;
    display: grid;
    gap: 1.15rem;
    padding: 1rem;
    border: 1px solid var(--color-border);
    border-radius: calc(var(--radius) + 4px);
    background: color-mix(in srgb, var(--color-surface) 82%, transparent);
}
.shop-filter-group { display: grid; gap: .65rem; }
.shop-filter-group + .shop-filter-group { padding-top: 1rem; border-top: 1px solid var(--color-border); }
.shop-filter-group h2 { margin: 0; font-size: .86rem; letter-spacing: .02em; }
.shop-category-list { display: grid; gap: .15rem; }
.shop-category-list a {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 2.25rem;
    padding: .4rem .65rem;
    color: var(--color-muted);
    border-radius: max(6px, calc(var(--radius) - 2px));
    text-decoration: none;
}
.shop-category-list a:hover { color: var(--color-text); background: color-mix(in srgb, var(--color-accent) 7%, transparent); }
.shop-category-list a.is-active {
    color: var(--color-text);
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
    font-weight: 700;
}
.shop-category-list a.is-active::before {
    content: "";
    position: absolute;
    left: 0;
    top: .45rem;
    bottom: .45rem;
    width: 2px;
    border-radius: 9px;
    background: var(--color-accent);
}
.shop-filter-form { display: grid; gap: 1rem; }
.shop-price-range {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: .45rem;
    align-items: end;
}
.shop-price-range label { min-width: 0; }
.shop-price-range label > span { display: block; margin-bottom: .28rem; color: var(--color-faint); font-size: .7rem; }
.shop-price-range > span { padding-bottom: .65rem; color: var(--color-faint); }
.shop-price-range .input { min-width: 0; width: 100%; }
.shop-filter-form__actions { display: grid; gap: .45rem; }
.shop-filter-form__actions .button { width: 100%; }

.shop-catalog-main { min-width: 0; }
.shop-results-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    min-height: 3.65rem;
    margin-bottom: 1rem;
    padding: .65rem .8rem;
    border-bottom: 1px solid var(--color-border);
}
.shop-results-toolbar > div > strong { font-size: .88rem; }
.shop-active-filters { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .3rem; }
.shop-active-filters span {
    padding: .2rem .5rem;
    border-radius: 999px;
    color: var(--color-muted);
    background: color-mix(in srgb, var(--color-accent) 9%, transparent);
    font-size: .7rem;
}
.shop-sort-form label { display: flex; align-items: center; gap: .55rem; }
.shop-sort-form label > span { color: var(--color-faint); font-size: .76rem; white-space: nowrap; }
.shop-sort-form .input { width: auto; min-width: 11.5rem; }

.goods--catalog {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--good-min, 15rem)), 1fr));
    gap: 1rem .8rem;
}
.good--catalog {
    min-width: 0;
    overflow: visible;
    border: 0;
    background: transparent;
    box-shadow: none;
    clip-path: none;
}
.good--catalog::before,
.good--catalog::after { display: none; }
.good--catalog .good__cover {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: var(--good-ratio, 1 / 1);
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--color-border) 78%, transparent);
    border-radius: calc(var(--radius) + 6px);
    background: color-mix(in srgb, var(--color-surface) 88%, transparent);
}
.good--catalog .good__cover > img {
    width: 100%;
    height: 100%;
    object-fit: var(--good-fit, contain);
    padding: 0;
    transition: transform .22s ease;
}
.good--catalog:hover .good__cover > img { transform: scale(1.025); }
.good--catalog:hover,
.good--catalog:focus-within { box-shadow: none; }
.good--catalog .good__body {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    min-height: 0;
    padding: .7rem .15rem .4rem;
    border: 0;
    background: transparent;
}
.good--catalog .price { margin: 0; line-height: 1.15; }
.good--catalog .price__now { font-size: 1.22rem; font-weight: 800; }
.good--catalog .price__old { font-size: .82rem; }
.good--catalog .good__title { margin: 0; font-size: .94rem; line-height: 1.32; font-weight: 650; }
.good--catalog .good__lead {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    margin: 0;
    color: var(--color-faint);
    font-size: .78rem;
    line-height: 1.45;
}
.good-card-rating {
    display: inline-flex;
    align-items: center;
    gap: .28rem;
    width: max-content;
    color: var(--color-muted);
    font-size: .76rem;
    text-decoration: none;
}
.good-card-rating > span { color: var(--color-warning); }
.good-card-rating strong { color: var(--color-text); }
.good-card-rating small { color: var(--color-faint); }
.good-card-meta { min-height: 1.1rem; color: var(--color-faint); font-size: .72rem; }
.good-card-meta .is-ok { color: var(--color-success); }
.good-card-meta .is-out { color: var(--color-danger); }
.good--catalog .buy,
.good--catalog .buy__choose { margin-top: auto; }
.good--catalog .buy .button,
.good--catalog .buy__choose { width: 100%; min-height: 2.65rem; }

.shop-empty-state {
    display: grid;
    justify-items: center;
    gap: .55rem;
    padding: 3rem 1.5rem;
    text-align: center;
    border: 1px dashed var(--color-border-strong);
    border-radius: calc(var(--radius) + 6px);
    color: var(--color-muted);
}
.shop-empty-state > span { font-size: 2.2rem; color: var(--color-accent); }
.shop-empty-state h2,
.shop-empty-state p { margin: 0; }

/* Product detail --------------------------------------------------- */
.shop-product-head { margin-bottom: 1.3rem; }
.shop-product-head__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem 1rem; margin-bottom: .5rem; color: var(--color-faint); font-size: .76rem; }
.shop-product-head h1 { max-width: 58rem; margin-bottom: .5rem; font-size: clamp(1.9rem, 4vw, 3rem); }
.shop-product-head__lead { max-width: 58rem; margin: 0; color: var(--color-muted); }
.shop-product-rating { display: inline-flex; align-items: center; gap: .32rem; text-decoration: none; }
.shop-product-rating > span:first-child { color: var(--color-warning); }
.shop-product-rating strong { color: var(--color-text); }
.shop-product-jumps { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: .7rem; }
.shop-product-jumps a { color: var(--color-muted); font-size: .78rem; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--color-accent) 35%, transparent); text-underline-offset: .22em; }

.shop-product-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(200px, .62fr) minmax(290px, .78fr);
    grid-template-areas: "media summary buy";
    gap: 1.2rem;
    align-items: start;
}
.shop-product-media {
    grid-area: media;
    position: relative;
    min-width: 0;
    padding: .85rem;
    border: 1px solid var(--color-border);
    border-radius: calc(var(--radius) + 7px);
    background: color-mix(in srgb, var(--color-surface) 88%, transparent);
}
.shop-product-media > img,
/*
 * Заглушке хватает своей пропорции.
 *
 * Жёсткие 28rem задуманы под настоящий снимок, но буква под них не
 * растягивается: в узкой колонке выходил пустой столб в полтора экрана
 * с маленькой буквой посередине, а рядом — короткий список фактов.
 */
.shop-product-media > .good-stub { width: 100%; min-height: 0; }
.shop-product-media .gallery {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    gap: .8rem;
    align-items: start;
}
.shop-product-media .gallery__big {
    grid-column: 2;
    grid-row: 1;
    width: 100%;
    height: min(58vw, 34rem);
    object-fit: contain;
    border-radius: calc(var(--radius) + 2px);
    background: color-mix(in srgb, var(--color-background) 22%, transparent);
}
.shop-product-media .gallery__strip {
    grid-column: 1;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    gap: .45rem;
    margin: 0;
}
.shop-product-media .gallery__thumb {
    width: 64px;
    aspect-ratio: 1;
    flex: 0 0 auto;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: max(6px, calc(var(--radius) - 1px));
    background: var(--color-surface);
}
.shop-product-media .gallery__thumb.is-current { border-color: var(--color-accent); box-shadow: 0 0 0 1px var(--color-accent); }

.shop-product-summary {
    grid-area: summary;
    min-width: 0;
    padding: .9rem .25rem;
}
.shop-product-summary h2 { font-size: 1rem; }
.shop-product-facts { display: grid; gap: 0; margin: 0; }
.shop-product-facts > div { display: grid; gap: .15rem; padding: .65rem 0; border-bottom: 1px solid var(--color-border); }
.shop-product-facts dt { color: var(--color-faint); font-size: .7rem; }
.shop-product-facts dd { margin: 0; color: var(--color-text); font-size: .84rem; font-weight: 650; }
.shop-product-summary__text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    overflow: hidden;
    margin: .9rem 0 0;
    color: var(--color-muted);
    font-size: .83rem;
}

.shop-purchase-card {
    grid-area: buy;
    position: sticky;
    top: 5.3rem;
    display: grid;
    gap: .85rem;
    min-width: 0;
    padding: 1.1rem;
    border: 1px solid var(--color-border-strong);
    border-radius: calc(var(--radius) + 8px);
    background: color-mix(in srgb, var(--color-surface) 94%, transparent);
    box-shadow: var(--shadow-panel, 0 16px 40px -26px rgb(0 0 0 / .5));
}
.shop-purchase-card__price .price { margin: 0; }
.shop-purchase-card__price .price__now { font-size: clamp(1.55rem, 3vw, 2.05rem); font-weight: 850; }
.shop-purchase-card__price .price__old { font-size: .9rem; }
.shop-stock-state { display: flex; align-items: center; gap: .45rem; font-size: .78rem; font-weight: 650; }
.shop-stock-state > span { width: .52rem; height: .52rem; border-radius: 50%; background: currentColor; }
.shop-stock-state.is-ok { color: var(--color-success); }
.shop-stock-state.is-out { color: var(--color-danger); }
.shop-purchase-card .buy { display: grid; gap: .8rem; }
.shop-purchase-card .buy > .button { width: 100%; min-height: 3rem; font-size: .95rem; font-weight: 750; }
.shop-purchase-card .buy__count { display: grid; grid-template-columns: 1fr 5rem; align-items: center; gap: .6rem; }
.shop-purchase-card .buy__count .field__hint { margin: 0; }
.shop-purchase-card .buy__count .input { width: 100%; }
.shop-purchase-card .buy__variants { margin: 0; padding: 0; border: 0; }
.shop-purchase-card .buy__variants legend { margin-bottom: .5rem; }
.shop-purchase-card .buy__variant { border-radius: max(7px, var(--radius)); }

.shop-purchase-delivery,
.shop-purchase-benefits { padding-top: .85rem; border-top: 1px solid var(--color-border); }
.shop-purchase-delivery h3 { margin: 0 0 .6rem; font-size: .82rem; }
.shop-purchase-delivery__row { display: flex; gap: .55rem; padding: .45rem 0; }
.shop-purchase-delivery__row > span { color: var(--color-accent); }
.shop-purchase-delivery__row strong,
.shop-purchase-delivery__row small { display: block; }
.shop-purchase-delivery__row strong { font-size: .76rem; }
.shop-purchase-delivery__row small { color: var(--color-faint); font-size: .68rem; }
.shop-purchase-benefits { display: grid; gap: .55rem; margin: 0; list-style: none; }
.shop-purchase-benefits li { display: flex; gap: .55rem; }
.shop-purchase-benefits li > span { color: var(--color-success); }
.shop-purchase-benefits strong,
.shop-purchase-benefits small { display: block; }
.shop-purchase-benefits strong { font-size: .74rem; }
.shop-purchase-benefits small { color: var(--color-faint); font-size: .67rem; }

.shop-product-section {
    margin-top: 2rem;
    padding-top: 1.4rem;
    border-top: 1px solid var(--color-border);
    scroll-margin-top: 6rem;
}
.shop-product-section > header { margin-bottom: 1rem; }
.shop-product-section > header h2 { margin-bottom: 0; font-size: clamp(1.35rem, 3vw, 2rem); }
.shop-product-description { max-width: 52rem; color: var(--color-muted); }
.shop-product-description p { margin: 0 0 1rem; }
.goods--nearby { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.good--nearby .good__body { gap: .35rem; }
.good--nearby .price { margin: 0; }

@media (max-width: 1050px) {
    .shop-product-layout {
        grid-template-columns: minmax(0, 1.2fr) minmax(280px, .8fr);
        grid-template-areas: "media buy" "summary summary";
    }
    .shop-product-summary { padding: .5rem 0 0; }
}

@media (max-width: 820px) {
    .shop-catalog-layout { grid-template-columns: 1fr; }
    .shop-filter-panel { position: static; grid-template-columns: minmax(0, 1fr) minmax(240px, .85fr); }
    .shop-filter-form { align-content: start; }
    .shop-category-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .shop-results-toolbar { padding-inline: 0; }
    .goods--nearby { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
    .shop-catalog-head { align-items: start; }
    .shop-catalog-head__count { display: none; }
    .shop-filter-panel { grid-template-columns: 1fr; padding: .85rem; }
    .shop-category-list { display: flex; overflow-x: auto; gap: .35rem; padding-bottom: .15rem; scrollbar-width: thin; }
    .shop-category-list a { flex: 0 0 auto; border: 1px solid var(--color-border); padding-inline: .8rem; }
    .shop-category-list a.is-active::before { display: none; }
    .shop-results-toolbar { align-items: flex-start; }
    .shop-sort-form label { display: grid; gap: .25rem; }
    .shop-sort-form .input { min-width: 10rem; max-width: 12.5rem; }
    .shop-product-layout { grid-template-columns: 1fr; grid-template-areas: "media" "summary" "buy"; }
    .shop-purchase-card { position: static; }
    .shop-product-media .gallery { grid-template-columns: 1fr; }
    .shop-product-media .gallery__big { grid-column: 1; grid-row: 1; height: min(92vw, 31rem); }
    .shop-product-media .gallery__strip { grid-column: 1; grid-row: 2; flex-direction: row; overflow-x: auto; }
    .shop-product-media > img,
    .shop-product-media > .good-stub { min-height: min(90vw, 30rem); }
}

@media (max-width: 560px) {
    .shop-benefits { grid-template-columns: 1fr 1fr; }
    .shop-benefits li { align-items: flex-start; padding: .65rem; }
    .shop-results-toolbar { display: grid; }
    .shop-sort-form,
    .shop-sort-form label,
    .shop-sort-form .input { width: 100%; max-width: none; }
    .goods--catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .85rem .55rem; }
    .good--catalog .good__body { padding-inline: 0; }
    .good--catalog .good__lead { display: none; }
    .good--catalog .good__title { font-size: .83rem; }
    .good--catalog .price__now { font-size: 1.02rem; }
    .good--catalog .button { padding-inline: .45rem; font-size: .75rem; }
    .shop-product-head h1 { font-size: 1.65rem; }
    .shop-product-media { padding: .55rem; }
    .goods--nearby { gap: .65rem; }
}

@media (max-width: 390px) {
    .shop-benefits { grid-template-columns: 1fr; }
}

/* Shop catalogue 2.0: specifications, compare and expandable purchase details */
.shop-compare-action { display: grid; gap: .35rem; margin-top: .2rem; }
.shop-compare-action .button { width: 100%; }
.shop-compare-action--product { padding-top: .15rem; }
.shop-compare-link { justify-self: center; color: var(--color-muted); font-size: .74rem; text-decoration: none; }
.shop-compare-link:hover { color: var(--color-accent); }

.shop-purchase-more { padding-top: .35rem; border-top: 1px dashed color-mix(in srgb, var(--color-border) 80%, transparent); }
.shop-purchase-more > summary { cursor: pointer; color: var(--color-accent); font-size: .74rem; font-weight: 700; list-style-position: inside; }
.shop-purchase-more[open] > summary { margin-bottom: .45rem; }
.shop-purchase-more .shop-purchase-benefits { padding-top: .25rem; border-top: 0; }

.shop-attributes-table { display: grid; max-width: 56rem; margin: 0; border: 1px solid var(--color-border); border-radius: calc(var(--radius) + 4px); overflow: hidden; background: color-mix(in srgb, var(--color-surface) 84%, transparent); }
.shop-attributes-table > div { display: grid; grid-template-columns: minmax(10rem, .8fr) minmax(0, 1.2fr); gap: 1rem; padding: .75rem .9rem; }
.shop-attributes-table > div + div { border-top: 1px solid var(--color-border); }
.shop-attributes-table dt { color: var(--color-faint); font-size: .78rem; }
.shop-attributes-table dd { margin: 0; color: var(--color-text); font-size: .84rem; font-weight: 650; }

.shop-compare-scroll { overflow-x: auto; padding-bottom: .4rem; }
.shop-compare-table { width: 100%; min-width: 760px; border-collapse: separate; border-spacing: 0; border: 1px solid var(--color-border); border-radius: calc(var(--radius) + 6px); overflow: hidden; background: color-mix(in srgb, var(--color-surface) 88%, transparent); }
.shop-compare-table th, .shop-compare-table td { min-width: 170px; padding: .8rem .9rem; vertical-align: top; text-align: left; border-bottom: 1px solid var(--color-border); }
.shop-compare-table th + th, .shop-compare-table td + td { border-left: 1px solid var(--color-border); }
.shop-compare-table tbody tr:last-child th, .shop-compare-table tbody tr:last-child td { border-bottom: 0; }
.shop-compare-table tbody th { width: 13rem; min-width: 13rem; color: var(--color-faint); font-size: .78rem; font-weight: 600; }
.shop-compare-product { display: grid; gap: .45rem; color: var(--color-text); text-decoration: none; }
.shop-compare-product > img, .shop-compare-product > .good-stub { width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: var(--radius); background: color-mix(in srgb, var(--color-background) 24%, transparent); }
.shop-compare-product strong { font-size: .88rem; line-height: 1.35; }
.shop-compare-product .price { margin: 0; }
.shop-compare-table thead form { margin-top: .55rem; }

@media (max-width: 700px) {
    .shop-attributes-table > div { grid-template-columns: 1fr; gap: .25rem; }
    .shop-compare-action--product { grid-template-columns: 1fr; }
}
.shop-results-toolbar__actions { display:flex; align-items:center; gap:.55rem; }
.shop-results-toolbar__actions > .button { white-space:nowrap; }
/*
 * На узком экране равняем по НИЗУ, а не по середине.
 *
 * Друг прислал: «две кнопки, которые должны быть на одном уровне, — на
 * разных». Здесь их две: ссылка «Открыть сравнение» и список сортировки.
 *
 * До семисот точек подпись сортировки встаёт НАД списком (иначе строка
 * не помещается), и форма делается выше кнопки на высоту подписи. А ряд
 * равняет по середине — кнопка и уезжает вниз на двенадцать точек.
 *
 *     ряд, собранный из разного по высоте,
 *     выравнивается по середине только на вид:
 *     сойдётся, пока соседи одного роста.
 *
 * По низу они встают на одну линию: подпись остаётся сверху сама по
 * себе, а нажимаемое — рядом, как и ждёт глаз.
 */
@media (max-width:700px){
    .shop-results-toolbar__actions{ width:100%; justify-content:space-between; align-items:flex-end; }
}

/*
 * Акцент на подложке из того же акцента.
 *
 * Значок «PNG» у файла, выбранная рубрика загрузок, метки карточки файла:
 * зелёный текст стоял на бледно-зелёной подложке и давал 4,2–4,45 при
 * нужных 4,5 — проверка контраста ловила это на шести страницах. Чернила
 * — тот же акцент, чуть смешанный с цветом текста: на светлой теме он
 * темнеет, на тёмной светлеет, оттенок остаётся своим.
 */
:root { --color-accent-ink: color-mix(in srgb, var(--color-accent) 78%, var(--color-text)); }

.home-files__icon,
.downloads-categories a:hover,
.downloads-categories a.is-active,
.downloads-card__meta a,
.downloads-card__meta span { color: var(--color-accent-ink); }
