/* Публичный сайт: то, чего нет в дизайн-системе.

   Коробки, сетки, шапка, подвал, карточки, кнопки, печати и плашки
   приходят из `eddy/styles.css` (полного, со сбросом `base.css` — здесь
   вся разметка наша). Ниже — только раскладка конкретных блоков: то,
   что в макетах написано инлайновыми стилями и в компонент не вынесено.

   Прежний файл был переписан целиком: он держал одностраничник со
   своими классами `.site-*`, `.btn`, `.card` и собственной палитрой
   `--c-*`. Страниц теперь шесть, и они собраны из компонентов марки. */

/* ── Шапка ───────────────────────────────────────────────────────── */

/* Полный лок-ап «ЭДДИ · школа китайского языка» — пропорция 7,8:1.
   Высота задаётся ЧИСЛОМ, а не max-height с width:auto: знак лежит во
   флекс-ряду шапки, и тогда `max-width:100%` считается от родителя,
   ширина которого сама берётся из картинки — круг разрешается в нуль, и
   логотип исчезает со страницы совсем (проверено в браузере: rect 0×0
   при загруженной картинке 3143×404). По той же причине `flex: none`:
   иначе ряд сжимает знак, когда пунктов меню становится много. */
.site-brand { flex: none; }
.site-brand img {
    display: block;
    /* 28, а не 38: в подвале лок-ап рисуется 26 по высоте (его сужает
       колонка сетки), и знак в шапке вдвое крупнее подвального читался
       как две разные марки на одной странице. */
    height: 28px;
    width: auto;
}
.site-footer__logo { display: block; height: 44px; width: auto; }

.site-header__phone {
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    color: var(--text-body);
    white-space: nowrap;
    text-decoration: none;
}

/* Меню на телефоне: галочка + подписи, без единой строки JS. Сама
   галочка уведена за экран, а не спрятана `display: none`, — спрятанная
   выпадает из обхода с клавиатуры. */
.site-menu-toggle {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
}

.site-menu { display: none; }
.site-burger { display: none; }

/* Ряд шапки — пять пунктов: всё про учёбу свёрнуто под «Обучение», а
   отзывы ушли в подвал. Прежняя промежуточная ступень (телефон прятался
   на 1200–1439) больше не нужна: ряду хватает места. */
@media (min-width: 1200px) and (max-width: 1359px) {
    .eddy-header .eddy-nav { gap: var(--sp-4); }
}

@media (max-width: 1199px) {
    .eddy-header .eddy-nav,
    .eddy-header .eddy-header__actions { display: none; }
    /* Лок-ап ниже: рядом с ним на телефоне только кнопка меню, но при
       38 px он занимает 296 точек из 375, и подпись всё равно не
       читается — за неё платить шириной экрана незачем. */
    .site-brand img { height: 26px; }
    /* Кнопка меню. Размер задаётся ПОД ИМЯ КЛАССА, в котором лежит
       значок: инлайновый SVG приходит 0×0, если правила на его контейнер
       нет — кнопка была на месте, но шириной в ноль. Площадь нажатия не
       меньше 44 точек: это палец, а не курсор. */
    .eddy-header .site-burger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        margin-left: auto;
        border: var(--border-w) solid var(--border-default);
        border-radius: var(--r-md);
        color: var(--text-body);
        cursor: pointer;
    }

    .eddy-header .site-burger svg { width: 22px; height: 22px; }

    .site-menu-toggle:checked ~ .eddy-header .site-menu { display: block; }

    .site-menu__inner {
        display: flex;
        flex-direction: column;
        gap: var(--sp-2);
        padding-bottom: var(--sp-6);
        border-top: var(--border-w) solid var(--border-subtle);
        padding-top: var(--sp-5);
    }

    .site-menu__inner a {
        padding: var(--sp-4) 0;
        font-size: var(--fs-base);
        font-weight: var(--fw-semibold);
        color: var(--text-body);
        text-decoration: none;
    }

    .site-menu__inner a.is-active { color: var(--accent); }
}

/* ── Герой ───────────────────────────────────────────────────────── */

.site-hero__inner {
    position: relative;
    padding-top: 72px;
    padding-bottom: 72px;
}

.site-hero__title {
    margin-top: var(--sp-6);
    max-width: 640px;
}

.site-hero__lead {
    margin-top: var(--sp-7);
    font-size: var(--fs-site-lead);
    line-height: 1.6;
    max-width: 540px;
    color: rgba(255, 255, 255, .9);
}

.site-hero__actions {
    display: flex;
    gap: var(--sp-5);
    margin-top: var(--sp-9);
    flex-wrap: wrap;
}

/* Обводка на красном фоне: у кита вариант `outline` рассчитан на светлую
   подложку, и на красном он читался бы как выключенная кнопка. */
.site-btn--onred,
.site-btn--onred:hover {
    background: transparent;
    color: #fff;
    border-color: rgba(255, 255, 255, .5);
}

/* Знак 艾迪 на первом экране — кистью: `--font-hanzi` это наборный Noto
   Sans SC, у него ровные машинные штрихи, а на красном поле нужен живой
   росчерк. Тем же начертанием набраны печати и награды. */
.site-hero .eddy-brandblock__hanzi {
    font-family: var(--font-hanzi-brush);
    font-weight: 400;
}

/* Первый экран: групповой снимок школы вместо одиночного маскота.
   Круга и рамки здесь нет намеренно. Картинка вырезана по контуру, фон у
   неё прозрачный — она ложится прямо на красное поле, и границы у неё не
   возникает вовсе. Круг же обрезал бы широкий кадр по бокам: за рамкой
   остались бы лев и половина дракона. */
.site-hero__art img {
    width: 100%;
    height: auto;
    display: block;
    /* Нижний край кадра проходит по фигурам, и на ровном фоне это была бы
       отрезанная по линейке полоса. Растворяем последние проценты высоты:
       снимок уходит в фон, а не обрывается. */
    -webkit-mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
}

/* Кадр широкий (3:2), и в колонке кита на 360 точек он превратился бы в
   марку: лица в ней уже неразличимы. Отдаём под него больше места. */
@media (min-width: 1024px) {
    .site-hero .eddy-hero {
        grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
        gap: var(--sp-8);
    }
}
/* На одной колонке кит сжимает картинку до 260 и 180 точек — это верно
   для маскота и бессмысленно для группового снимка. */
@media (max-width: 1023px) {
    .site-hero .eddy-hero__art { max-width: 560px; margin: var(--sp-8) auto 0; }
}
@media (max-width: 767px) {
    .site-hero .eddy-hero__art { max-width: 100%; margin-top: var(--sp-7); }
}

.site-hero__facts {
    display: flex;
    gap: var(--sp-9);
    margin-top: 40px;
    flex-wrap: wrap;
}

.site-fact__value {
    display: block;
    font-family: var(--font-display);
    font-size: var(--fs-xl);
}

.site-fact__cap {
    display: block;
    font-size: var(--fs-xs);
    color: rgba(255, 255, 255, .72);
}

/* ── Заголовок раздела и страницы ────────────────────────────────── */

.site-section__head {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-8);
    margin-bottom: var(--sp-9);
    flex-wrap: wrap;
}

.site-section__head .eddy-h2,
.site-section__head .eddy-lead { max-width: 660px; }
.site-section__head .eddy-h2 { margin-top: var(--sp-3); }
.site-section__head .eddy-lead { margin-top: var(--sp-5); }
.site-section__action { margin-left: auto; }

.site-pagehead {
    background: var(--surface-card);
    border-bottom: var(--border-w) solid var(--border-subtle);
    padding: 48px 0 40px;
}

.site-pagehead .eddy-h1 { margin-top: var(--sp-5); max-width: 760px; }
.site-pagehead .eddy-lead { margin-top: var(--sp-6); max-width: 660px; }

/* ── Общие мелочи страниц ────────────────────────────────────────── */

.site-body {
    font-size: var(--fs-site-body);
    line-height: 1.7;
    color: var(--ink-700);
}

.site-body + .site-body { margin-top: var(--sp-5); }

.site-badges {
    display: flex;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-top: var(--sp-5);
}

.site-chips {
    display: flex;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-top: var(--sp-5);
}

.site-row--after {
    display: flex;
    gap: var(--sp-5);
    align-items: center;
    flex-wrap: wrap;
    margin-top: var(--sp-8);
}

.site-note--after { margin-top: var(--sp-5); }
.site-card__btn { margin-top: var(--sp-6); }
.site-grid--middle { align-items: center; }
.site-grid--start { align-items: start; }
.site-num { text-align: right; }

.site-stack {
    display: grid;
    gap: var(--sp-4);
    margin-top: var(--sp-6);
}

.site-btn__icon {
    display: inline-flex;
    width: 18px;
    height: 18px;
}

.site-btn__icon svg { width: 100%; height: 100%; }

/* ── Карточка возраста ───────────────────────────────────────────── */

.site-age { text-decoration: none; color: inherit; display: block; }
.site-age__title { margin-top: var(--sp-5); }

.site-age__text {
    margin-top: var(--sp-4);
    font-size: var(--fs-site-small);
    color: var(--ink-600);
    line-height: 1.6;
}

/* ── Основатель, шаги, признаки ──────────────────────────────────── */

.site-photo--tall { height: 380px; border-radius: var(--r-card); margin: 0; }
.site-photo--tall img { width: 100%; height: 100%; object-fit: cover; }

.site-note {
    margin-top: var(--sp-7);
    padding: var(--sp-6);
    background: var(--paper-200);
    border-radius: var(--r-card);
    display: flex;
    gap: var(--sp-5);
    align-items: flex-start;
}

.site-note p {
    font-size: var(--fs-site-small);
    line-height: 1.7;
    color: var(--ink-700);
}

.site-steps { display: grid; gap: var(--sp-5); margin-top: var(--sp-7); }

.site-step {
    display: flex;
    gap: var(--sp-5);
    align-items: flex-start;
    font-size: var(--fs-site-small);
    line-height: 1.6;
}

.site-step__no {
    width: 26px;
    height: 26px;
    border-radius: var(--r-pill);
    background: var(--jade-500);
    color: #fff;
    display: grid;
    place-items: center;
    font-size: 13px;
    font-weight: var(--fw-bold);
    flex: none;
}

.site-checklist { display: grid; gap: var(--sp-4); margin-top: var(--sp-5); }

.site-checklist > div {
    display: flex;
    gap: var(--sp-4);
    align-items: center;
    font-size: var(--fs-site-small);
}

.site-check {
    display: inline-flex;
    width: 18px;
    height: 18px;
    color: var(--secondary);
    flex: none;
}

.site-check svg { width: 100%; height: 100%; }

.site-features { display: grid; gap: var(--sp-8); }
.site-features--row { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

.site-feature { display: flex; gap: var(--sp-5); }

.site-feature__icon {
    color: var(--accent);
    flex: none;
    margin-top: 2px;
    width: 22px;
    height: 22px;
    display: inline-flex;
}

.site-feature__icon svg { width: 100%; height: 100%; }
.site-feature__title { font-weight: var(--fw-bold); font-size: var(--fs-base); }

.site-feature p {
    margin-top: var(--sp-3);
    font-size: var(--fs-site-small);
    color: var(--ink-600);
    line-height: 1.6;
}

/* ── Яндекс, программы, отзывы ───────────────────────────────────── */

.site-yandex { display: flex; gap: var(--sp-6); align-items: flex-start; }
.site-yandex img { width: 64px; height: auto; flex: none; }
.site-yandex__name { font-weight: var(--fw-bold); font-size: var(--fs-base); }
.site-yandex__link { margin-top: var(--sp-5); font-size: var(--fs-site-small); }

.site-program__name {
    margin-top: var(--sp-5);
    font-weight: var(--fw-bold);
    font-family: var(--font-display);
    font-size: var(--fs-base);
}

.site-program__text {
    margin-top: var(--sp-3);
    font-size: var(--fs-xs);
    color: var(--ink-600);
    line-height: 1.55;
}

.site-stars { display: flex; gap: 3px; color: var(--yellow-400); }
.site-stars svg { width: 15px; height: 15px; }
.site-review__name { margin-top: var(--sp-5); font-weight: var(--fw-bold); font-size: var(--fs-site-small); }

.site-review__text {
    margin-top: var(--sp-4);
    font-size: var(--fs-site-small);
    line-height: 1.7;
    color: var(--ink-700);
}

/* ── Цены ────────────────────────────────────────────────────────── */

.site-pricegroup + .site-pricegroup { margin-top: var(--sp-9); }
.site-pricegroup .eddy-h3 { margin-bottom: var(--sp-6); }
.site-price__head { display: flex; align-items: center; gap: var(--sp-4); }
.site-price__pack { font-size: var(--fs-lg); font-weight: var(--fw-bold); }

.site-price__total {
    margin-top: var(--sp-6);
    font-size: var(--fs-3xl);
    font-weight: 800;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.site-price__meta { font-size: var(--fs-xs); color: var(--text-muted); }

.site-price__row {
    margin-top: var(--sp-7);
    padding-top: var(--sp-5);
    border-top: var(--border-w) solid var(--border-subtle);
    display: flex;
    justify-content: space-between;
    font-size: var(--fs-site-small);
}

.site-price__row span { color: var(--text-muted); }
.site-priceempty { max-width: 720px; }
.site-qa { display: grid; gap: var(--sp-6); margin-top: var(--sp-5); }
.site-qa b { font-size: var(--fs-site-small); }

.site-qa p {
    margin-top: var(--sp-3);
    font-size: var(--fs-site-small);
    line-height: 1.7;
    color: var(--ink-600);
}

/* ── Локации и контакты ──────────────────────────────────────────── */

.site-place__name { font-weight: var(--fw-bold); }

.site-place__addr {
    font-size: var(--fs-site-small);
    color: var(--ink-600);
    margin-top: var(--sp-4);
    line-height: 1.6;
}

.site-place__note { font-size: var(--fs-xs); color: var(--text-muted); margin-top: var(--sp-4); }
.site-place__link { margin-top: var(--sp-5); font-size: var(--fs-site-small); }

.site-contacts { display: grid; gap: var(--sp-6); margin-top: var(--sp-8); }
.site-contact { display: flex; gap: var(--sp-5); align-items: flex-start; }

.site-contact__icon {
    color: var(--accent);
    margin-top: 2px;
    width: 20px;
    height: 20px;
    display: inline-flex;
    flex: none;
}

.site-contact__icon svg { width: 100%; height: 100%; }

.site-contact__value {
    font-weight: var(--fw-bold);
    color: var(--text-body);
    text-decoration: none;
}

.site-contact__cap { font-size: var(--fs-xs); color: var(--text-muted); }

/* ── Педагоги ────────────────────────────────────────────────────── */

.site-teacher__photo { height: 240px; margin: 0 0 var(--sp-6); border-radius: var(--r-card); }
.site-teacher__photo img { width: 100%; height: 100%; object-fit: cover; }
.site-teacher__name { font-weight: var(--fw-bold); font-size: var(--fs-lg); letter-spacing: var(--ls-snug); }

.site-teacher__about {
    margin-top: var(--sp-5);
    font-size: var(--fs-site-small);
    line-height: 1.65;
    color: var(--ink-600);
}

/* ── Финальная плашка ────────────────────────────────────────────── */

.site-cta__inner {
    position: relative;
    padding-top: 56px;
    padding-bottom: 56px;
    display: flex;
    align-items: center;
    gap: var(--sp-9);
    flex-wrap: wrap;
}

/* Печать 艾迪 — вширь: у кита `--wide` переключает письмо на
   горизонтальное, но ширину коробки не трогает, и два знака не влезали
   в квадрат 72×72 — печать читалась в два этажа. */
.eddy-seal--stamp.eddy-seal--wide { width: auto; padding: 0 var(--sp-6); }
.site-cta__seal { color: #fff; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5); }
.site-cta__text { flex: 1; min-width: 260px; }
.site-cta__title { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; }
.site-cta__text p { margin-top: var(--sp-3); color: rgba(255, 255, 255, .85); font-size: var(--fs-site-small); }
.site-cta__btn { background: #fff; color: var(--red-700); border-color: #fff; }
.site-cta__btn:hover { background: var(--paper-100); color: var(--red-700); }

/* ── Подвал ──────────────────────────────────────────────────────── */

/* Знак в подвале ставится по ВЫСОТЕ. `width: auto` тут не помогает:
   колонка подвала — флекс-контейнер со `stretch`, и растянутый элемент
   считает `auto` шириной колонки — марка выходила 422 точки вместо 127.
   Лечит `align-self: start`; тот же случай, что с плашкой «не задано» в
   списке определений. */
.eddy-footer__col img {
    display: block;
    height: 26px;
    width: auto;
    align-self: start;
    max-width: 100%;
}

.site-footer__lead { font-size: var(--fs-sm); line-height: 1.6; max-width: 300px; margin-top: var(--sp-4); }
.site-footer__legal { font-size: var(--fs-2xs); line-height: 1.6; margin-top: var(--sp-5); opacity: .6; }
.site-footer__hours { font-size: var(--fs-2xs); opacity: .6; }

/* ── Окно заявки и сообщения ─────────────────────────────────────── */

/* Та же ловушка, что и в кабинетах: `.eddy-modal` объявляет
   `display: flex` безусловно, а правило браузера `dialog:not([open])`
   обычной силы — без строки ниже видимым становится закрытое окно. */
dialog.eddy-modal:not([open]) { display: none; }

dialog.eddy-modal {
    border: none;
    padding: 0;
    color: inherit;
}

dialog.eddy-modal::backdrop { background: rgba(22, 24, 26, .48); }

dialog.eddy-modal form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1 1 auto;
}

.eddy-modal__close {
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    color: var(--text-subtle);
    cursor: pointer;
    padding: 2px 6px;
    border-radius: var(--r-sm);
}

.eddy-modal__close:hover { background: var(--paper-200); color: var(--text-body); }
.site-modal .eddy-field + .eddy-field { margin-top: var(--sp-5); }
.site-consent { margin-top: var(--sp-6); }

/* Приманка для роботов: поле есть в разметке, но человек его не видит и
   не может сфокусировать. `display: none` не годится — часть роботов
   такие поля пропускает. */
.site-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.site-messages {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 60;
    display: grid;
    gap: var(--sp-4);
    width: min(560px, calc(100vw - 24px));
}

.site-message {
    padding: var(--sp-5) var(--sp-6);
    border-radius: var(--r-card);
    background: var(--surface-card);
    border: var(--border-w) solid var(--border-default);
    box-shadow: var(--sh-md);
    font-size: var(--fs-sm);
}

.site-message--success { border-color: var(--status-success); }
.site-message--error { border-color: var(--status-danger); }

/* ── Телефон ─────────────────────────────────────────────────────── */

@media (max-width: 767px) {
    .site-hero__inner { padding-top: 48px; padding-bottom: 48px; }
    .site-hero__facts { gap: var(--sp-7); margin-top: var(--sp-8); }
    .site-pagehead { padding: 32px 0 28px; }
    .site-photo--tall { height: 260px; }
    .site-section__action { margin-left: 0; }

    /* Главная кнопка формы — во всю ширину: правило кита для 375. */
    .eddy-modal__foot .eddy-btn { width: 100%; }
    .eddy-modal__foot { flex-direction: column-reverse; }

    /* Ряд чипов прокручивается вбок, а не переносится: перенесённые, они
       занимают три строки и отжимают содержимое вниз. */
    .site-chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: var(--sp-3);
    }

    .site-chips .eddy-chip { flex: none; }
}

/* ── Страница оплаты ─────────────────────────────────────────────── */

/* Вкладки по возрастам без единой строки JS: радиокнопка уведена за
   экран, панель показывается правилом `:checked ~`. Скрипт на этой
   странице нужен только окну оплаты — и без него карточки всё равно
   видны, просто все сразу. */
.site-paytab__radio {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
}

.site-paytabs__row {
    display: flex;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-bottom: var(--sp-8);
}

.site-paytab { cursor: pointer; }
.site-paypanel { display: none; }

/* Пары «радиокнопка — её панель» перечислены поимённо и по НОМЕРУ В
   КЛАССЕ, а не через `nth-of-type` у панели: тот считает среди всех
   соседей-`div`, а первым таким соседом идёт ряд вкладок — и правило
   показывало ряд вместо карточек. Вкладок на странице оплаты не бывает
   много: четыре у города, ноль у партнёров. */
.site-paypanel--1, .site-paypanel--2, .site-paypanel--3,
.site-paypanel--4, .site-paypanel--5, .site-paypanel--6 { display: none; }

.site-paytab__radio:nth-of-type(1):checked ~ .site-paypanel--1,
.site-paytab__radio:nth-of-type(2):checked ~ .site-paypanel--2,
.site-paytab__radio:nth-of-type(3):checked ~ .site-paypanel--3,
.site-paytab__radio:nth-of-type(4):checked ~ .site-paypanel--4,
.site-paytab__radio:nth-of-type(5):checked ~ .site-paypanel--5,
.site-paytab__radio:nth-of-type(6):checked ~ .site-paypanel--6 { display: block; }

.site-paytab__radio:nth-of-type(1):checked ~ .site-paytabs__row .site-paytab--1,
.site-paytab__radio:nth-of-type(2):checked ~ .site-paytabs__row .site-paytab--2,
.site-paytab__radio:nth-of-type(3):checked ~ .site-paytabs__row .site-paytab--3,
.site-paytab__radio:nth-of-type(4):checked ~ .site-paytabs__row .site-paytab--4,
.site-paytab__radio:nth-of-type(5):checked ~ .site-paytabs__row .site-paytab--5,
.site-paytab__radio:nth-of-type(6):checked ~ .site-paytabs__row .site-paytab--6 {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.site-offer { display: flex; flex-direction: column; }
.site-offer__img { width: 100%; height: 140px; object-fit: cover; border-radius: var(--r-md); margin-bottom: var(--sp-5); }
.site-offer__head { display: flex; align-items: flex-start; gap: var(--sp-4); }
.site-offer__title { flex: 1; }

.site-offer__list {
    list-style: none;
    margin: var(--sp-5) 0 0;
    padding: 0;
    display: grid;
    gap: 2px;
    font-size: var(--fs-site-small);
    color: var(--ink-600);
}

.site-offer__prices {
    display: flex;
    align-items: baseline;
    gap: var(--sp-4);
    margin-top: var(--sp-6);
    flex-wrap: wrap;
}

.site-offer__price {
    font-size: var(--fs-2xl);
    font-weight: 800;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.site-offer__old { color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.site-offer__per { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 2px; }
.site-offer .site-card__btn { margin-top: auto; }

/* ── Окно оплаты ─────────────────────────────────────────────────── */

.site-order {
    border-top: var(--border-w) solid var(--border-subtle);
    border-bottom: var(--border-w) solid var(--border-subtle);
    padding: var(--sp-5) 0;
    margin-bottom: var(--sp-6);
}

.site-order__row { display: flex; align-items: center; gap: var(--sp-5); }
.site-order__name { flex: 1; font-weight: var(--fw-semibold); font-size: var(--fs-site-small); }
.site-order__qty { display: flex; align-items: center; gap: var(--sp-4); }

.site-qty {
    width: 28px;
    height: 28px;
    border-radius: var(--r-pill);
    border: var(--border-w) solid var(--border-default);
    background: none;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    color: var(--text-body);
}

.site-qty:hover { border-color: var(--border-strong); background: var(--paper-100); }
.site-order__price { font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; white-space: nowrap; }

.site-promo { display: flex; gap: var(--sp-4); }
.site-promo .eddy-input { flex: 1; }
.site-promo .eddy-btn { flex: none; }
#pay-promo-note.is-error { color: var(--status-danger); }
#pay-promo-note.is-ok { color: var(--secondary); }

.site-order__total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-top: var(--sp-7);
    padding-top: var(--sp-5);
    border-top: var(--border-w) solid var(--border-subtle);
    font-size: var(--fs-base);
}

.site-order__total b { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }

/* ── Виджет 2ГИС ─────────────────────────────────────────────────── */

/* Чужой iframe с фиксированной вёрсткой внутри: снаружи задаём только
   рамку и высоту, а на телефоне отдаём ему всю ширину. Высота нужна
   явная — у iframe нет содержимого, по которому её можно вывести. */
.site-2gis__frame {
    width: 100%;
    max-width: 528px;
    height: 824px;
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    display: block;
}

@media (max-width: 599px) {
    .site-2gis__frame { height: 640px; }
}

/* Экзамены — такой же сеткой, как блок про клуб: ряд с прокруткой вбок
   на широком экране показывал три картинки в полный рост и занимал его
   целиком, оттесняя кнопку записи. */
.site-photogrid--exams { grid-auto-rows: 200px; }

@media (max-width: 599px) {
    .site-photogrid--exams { grid-template-rows: auto; }
}

/* Плашка-ссылка: у кита `eddy-badge` это `<span>`, и ссылке нужно снять
   подчёркивание и вернуть свой цвет — иначе `a:link` (0,1,1) красит её
   поверх компонента. */
a.site-badge-link,
a.site-badge-link:link,
a.site-badge-link:visited {
    text-decoration: none;
    color: inherit;
}

a.site-badge-link:hover { text-decoration: underline; }

/* Блок про платформу: снимок кабинета и фотография занятия друг под
   другом — один показывает, что видит родитель, вторая, что происходит
   в классе. */
.site-platform { display: grid; gap: var(--sp-6); }
.site-platform__shot { height: 240px; margin: 0; border-radius: var(--r-card); }
.site-platform__shot img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
/* Каллиграфия показывается целиком: `cover` кадрировал снимок, и знак
   爱 — то единственное, ради чего фотография тут стоит, — уходил за
   край. Отсюда `contain` и подложка под поля. */
.site-platform .site-photo--tall { height: 420px; background: var(--paper-200); }
.site-platform .site-photo--tall img { object-fit: contain; }

/* ── Кабинет рисунком: блок про платформу ────────────────────────── */

/* Ни одной картинки и ни строчки JS: снимок экрана пришлось бы
   переснимать после каждой правки интерфейса, а рисунок показывает то,
   что не меняется, — опыт за занятия, награды за серии и проверенную
   домашнюю работу. */

.site-anim {
    position: relative;
    display: grid;
    place-items: center;
    padding: var(--sp-8) 0;
}

.site-anim__screen {
    position: relative;
    width: min(360px, 100%);
    background: var(--surface-card);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-xl, 20px);
    box-shadow: var(--sh-lg);
    padding: var(--sp-7);
    display: grid;
    gap: var(--sp-6);
}

.site-anim__head { display: flex; align-items: center; gap: var(--sp-5); }

.site-anim__ava {
    width: 40px;
    height: 40px;
    border-radius: var(--r-pill);
    background: var(--secondary);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: var(--fw-bold);
    flex: none;
}

.site-anim__name { font-weight: var(--fw-bold); }

.site-anim__lvl {
    margin-left: auto;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    color: var(--text-muted);
}

.site-anim__xpbar {
    height: 8px;
    border-radius: var(--r-pill);
    background: var(--paper-300);
    overflow: hidden;
}

.site-anim__xpfill {
    display: block;
    height: 100%;
    width: 18%;
    border-radius: var(--r-pill);
    background: var(--secondary);
    animation: site-xp 6s var(--ease, ease-in-out) infinite;
}

.site-anim__xptext {
    margin-top: var(--sp-3);
    font-size: var(--fs-2xs);
    color: var(--text-muted);
}

.site-anim__xptext b { color: var(--secondary); }

.site-anim__row { display: flex; gap: var(--sp-5); }

/* Награды — те же китайские знаки, что и в кабинете: 奖 награда,
   册 книга, 笔 кисть. Появляются по очереди, а не разом: смысл в том,
   что их зарабатывают одну за другой. */
.site-anim__medal {
    width: 44px;
    height: 44px;
    border-radius: var(--r-md);
    display: grid;
    place-items: center;
    font-family: var(--font-hanzi-brush);
    font-size: 22px;
    color: #fff;
    opacity: 0;
    transform: scale(.6);
    animation: site-medal 6s var(--ease, ease-in-out) infinite;
}

.site-anim__medal--gold { background: var(--yellow-400, #E8B004); animation-delay: .2s; }
.site-anim__medal--jade { background: var(--secondary); animation-delay: 1.1s; }
.site-anim__medal--paper { background: var(--accent); animation-delay: 2s; }

.site-anim__medal--ghost {
    background: var(--paper-200);
    color: var(--text-subtle);
    opacity: 1;
    transform: none;
    animation: none;
    border: 1px dashed var(--border-default);
}

.site-anim__hw {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: var(--sp-5);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-md);
}

.site-anim__hwline {
    height: 8px;
    border-radius: var(--r-pill);
    background: var(--paper-300);
    flex: 1;
}

.site-anim__hwline--short { flex: .5; }

.site-anim__check {
    color: var(--secondary);
    font-weight: var(--fw-bold);
    opacity: 0;
    animation: site-check 6s var(--ease, ease-in-out) infinite;
    animation-delay: 2.6s;
}

.site-anim__grade {
    width: 26px;
    height: 26px;
    border-radius: var(--r-pill);
    background: var(--secondary-soft, #E7F3EC);
    color: var(--jade-700, #1E7D32);
    display: grid;
    place-items: center;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    opacity: 0;
    animation: site-check 6s var(--ease, ease-in-out) infinite;
    animation-delay: 3s;
}

/* Серия посещений: неделя клетками, последняя загорается. */
.site-anim__streak { display: flex; gap: 6px; }

.site-anim__streak span {
    flex: 1;
    height: 26px;
    border-radius: var(--r-sm);
    background: var(--paper-200);
}

.site-anim__streak span:nth-child(-n+5) { background: var(--visit-attended-bg, #E3F4E6); }

.site-anim__streak span:nth-child(6) {
    background: var(--visit-attended-bg, #E3F4E6);
    animation: site-streak 6s var(--ease, ease-in-out) infinite;
    animation-delay: 3.4s;
}

.site-anim__spark {
    position: absolute;
    font-size: 18px;
    color: var(--yellow-400, #E8B004);
    opacity: 0;
    animation: site-spark 6s var(--ease, ease-in-out) infinite;
}

.site-anim__spark--1 { top: 12%; left: 6%; animation-delay: .6s; }
.site-anim__spark--2 { top: 26%; right: 8%; animation-delay: 1.6s; font-size: 14px; }
.site-anim__spark--3 { bottom: 16%; left: 12%; animation-delay: 3.2s; font-size: 22px; }

@keyframes site-xp {
    0%, 8% { width: 18%; }
    45%, 100% { width: 76%; }
}

@keyframes site-medal {
    0%, 5% { opacity: 0; transform: scale(.6); }
    14% { opacity: 1; transform: scale(1.12); }
    22%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes site-check {
    0%, 40% { opacity: 0; transform: translateY(4px); }
    50%, 100% { opacity: 1; transform: none; }
}

@keyframes site-streak {
    0%, 50% { background: var(--paper-200); }
    60%, 100% { background: var(--visit-attended-bg, #E3F4E6); }
}

@keyframes site-spark {
    0%, 10% { opacity: 0; transform: translateY(6px) scale(.7); }
    18% { opacity: 1; transform: translateY(0) scale(1); }
    34%, 100% { opacity: 0; transform: translateY(-8px) scale(.9); }
}

/* Просили не двигать — не двигаем: анимация тут украшение, а не смысл,
   и всё, что она показывает, читается и в покое. */
@media (prefers-reduced-motion: reduce) {
    .site-anim__xpfill,
    .site-anim__medal,
    .site-anim__check,
    .site-anim__grade,
    .site-anim__streak span,
    .site-anim__spark {
        animation: none;
    }

    .site-anim__xpfill { width: 76%; }
    .site-anim__medal { opacity: 1; transform: none; }
    .site-anim__check, .site-anim__grade { opacity: 1; }
    .site-anim__spark { opacity: .8; }
}

/* Основатель и руководитель школы: карточка заметнее остальных — тенью и
   рамкой, а не полосой сверху (её в системе больше нет). */
.site-teacher--lead {
    box-shadow: var(--sh-md);
    border-color: var(--border-default);
}

.site-teacher__role {
    margin-top: 2px;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-caps, .04em);
    text-transform: uppercase;
    color: var(--accent);
}

/* Цена и кнопка в карточке тарифа не липнут друг к другу на телефоне,
   где карточка короткая и `margin-top: auto` ничего не отодвигает. */
.site-offer__per { margin-bottom: var(--sp-5); }

@media (max-width: 767px) {
    /* Ссылки-строчки на телефоне — это цель для пальца, а не для курсора.
       У кита есть свой размер минимальной цели (`--tap-min`), им и
       пользуемся: в подвале и в карточках ссылки были высотой в строку
       текста, попасть по ним получалось не с первого раза. */
    .eddy-footer__col a,
    .site-place__link a,
    .site-yandex__link a,
    .site-2gis a,
    .site-note--after a {
        display: inline-flex;
        align-items: center;
        min-height: var(--tap-min, 44px);
    }
}

/* --- Юридические документы ------------------------------------------ */
/* Такую страницу открывают, чтобы что-то в ней НАЙТИ, а не прочесть
   подряд. Отсюда узкая колонка (мера строки, а не ширина экрана),
   крупный интервал и видимые издалека заголовки разделов. */
.legal-doc { max-width: 720px; font-size: var(--fs-site-small); line-height: 1.75; color: var(--text-body); }
.legal-doc h2 {
    margin: var(--sp-8) 0 var(--sp-5);
    font-size: var(--fs-lg);
    font-weight: var(--fw-bold);
    line-height: 1.3;
    color: var(--text-body);
}
.legal-doc h2:first-child { margin-top: 0; }
.legal-doc p { margin: 0 0 var(--sp-5); }
/* Номер пункта — первое, за что цепляется глаз при поиске «а что там в
   3.4». Табличных цифр в шрифте нет, поэтому просто выделяем абзац
   отступом, а не выносим номер в поле. */
.legal-doc__clause { padding-left: var(--sp-4); border-left: 2px solid var(--border-subtle); }
.legal-doc ul { margin: 0 0 var(--sp-5); padding-left: var(--sp-6); }
.legal-doc li { margin-bottom: var(--sp-2); }
.legal-doc__updated {
    max-width: 720px;
    margin-top: var(--sp-8);
    padding-top: var(--sp-5);
    border-top: var(--border-w) solid var(--border-subtle);
    font-size: var(--fs-2xs);
    color: var(--text-muted);
}

/* --- 404 -------------------------------------------------------------- */
/* Страница, на которую попадают по ошибке, обязана предлагать выход, а
   не сообщать код ошибки. Отсюда ссылки на разделы прямо под текстом. */
.site-404 { padding: 96px 0 120px; text-align: center; }
.site-404__code { font-size: 64px; font-weight: var(--fw-bold); color: var(--accent); line-height: 1; }
.site-404__links { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-8); }
@media (max-width: 767px) { .site-404 { padding: 56px 0 72px; } .site-404__code { font-size: 48px; } }
/* Ссылки на документы в нижней строке подвала — тем же цветом, что и
   копирайт рядом: это сноска, а не навигация. */
.site-footer__docs a { color: inherit; text-decoration: underline; }

/* --- Учебные материалы (пять каталогов шапки) ------------------------- */
/* Ряд соседних каталогов под заголовком: разделы читают подряд, и «а что
   ещё есть» — следующий вопрос после первого материала. */
.study-switch { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-7); }
.study-switch a { text-decoration: none; }

.study-section + .study-section { margin-top: var(--sp-9); }
.study-section__title { margin-bottom: var(--sp-6); }
/* auto-fill, а не auto-fit: в разделе бывает одна карточка (видео уровня
   A1), и auto-fit растянул бы её во всю ширину экрана — читается как
   баннер, а не как элемент списка. */
.study-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-4); }

.study-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    min-height: 64px;
    padding: var(--sp-4) var(--sp-5);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    text-decoration: none;
    color: inherit;
    transition: var(--transition-control);
}
a.study-card:hover { border-color: var(--accent); text-decoration: none; }
.study-card__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Гарнитуру здесь не переопределяем: у части материалов русского
   названия нет вовсе («花园种菜»), и такое название помечено в разметке
   `lang="zh"` — дизайн-система сама даёт ему иероглифическую гарнитуру
   правилом `:lang(zh)` в tokens/base.css. */
.study-card__title { font-size: var(--fs-site-small); font-weight: var(--fw-semibold); color: var(--text-body); }
/* Иероглифы — своей гарнитурой и крупнее подписи: в наборе латиницей они
   мельчают до нечитаемости при одинаковом кегле. */
.study-card__zh { font-family: var(--font-hanzi); font-size: var(--fs-site-small); color: var(--text-muted); }
.study-card__go { flex: none; color: var(--accent); font-size: var(--fs-lg); line-height: 1; }
.study-card--soon { background: var(--surface-sunken); border-style: dashed; }
.study-card--soon .study-card__title { color: var(--text-muted); }

/* --- Перевод ---------------------------------------------------------- */
.site-pagehead__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-7); }
.translate-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-5); }
@media (max-width: 1023px) { .translate-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) {
    .translate-grid { grid-template-columns: 1fr; }
    .study-grid { grid-template-columns: 1fr; }
}

/* --- Выпадающий раздел «Материалы» в шапке ---------------------------- */
/* <details>, а не :hover-панель: наведения на сенсорном экране нет, и
   меню, которое на телефоне не открывается, прячет пять страниц целиком.
   Работает без единой строки JS. */
.site-drop { position: relative; }
/* Подпись раздела повторяет пункт меню во всём, кроме того, что она не
   ссылка: правила кита написаны на `.eddy-nav a` и до <summary> не
   достают, поэтому набор, цвет и подчёркивание активного состояния
   заданы здесь заново — иначе, зайдя в «Песни», человек видит шапку, в
   которой не отмечено ничего. */
.site-drop > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    padding: var(--sp-3) 0;
    border-bottom: 2px solid transparent;
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    color: var(--ink-700);
}
.site-drop > summary:hover { color: var(--accent); }
.site-drop > summary.is-active { color: var(--text-body); border-bottom-color: var(--accent); }
.site-drop > summary::-webkit-details-marker { display: none; }
/* Стрелка — своя, а не маркер браузера: у него она разная в каждом и
   в Safari не убирается ничем, кроме list-style: none выше. */
.site-drop > summary::after {
    content: "";
    width: 6px; height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .15s ease;
}
.site-drop[open] > summary::after { transform: translateY(1px) rotate(-135deg); }
.site-drop__panel {
    position: absolute;
    top: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 190px;
    padding: var(--sp-3);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    box-shadow: var(--sh-lg);
}
.site-drop__panel a {
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r-sm);
    white-space: nowrap;
}
.site-drop__panel a:hover { background: var(--surface-sunken); }

/* Подвал вырос до пяти колонок — правило кита рассчитано на четыре. */
.eddy-footer .eddy-footer__grid { grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; }
@media (max-width: 1023px) { .eddy-footer .eddy-footer__grid { grid-template-columns: 1fr 1fr 1fr; } }
@media (max-width: 767px) { .eddy-footer .eddy-footer__grid { grid-template-columns: 1fr 1fr; } }

@media (max-width: 1199px) {
    /* В выехавшем меню телефона панель раскрывать некуда — просто список
       с подзаголовком. */
    .site-menu__group {
        margin-top: var(--sp-5);
        font-size: var(--fs-2xs);
        font-weight: var(--fw-semibold);
        letter-spacing: var(--ls-wide, .04em);
        text-transform: uppercase;
        color: var(--text-subtle);
    }
    .site-menu__sub { padding-left: var(--sp-4); }
}

/* Подзаголовок группы внутри раскрывающегося раздела шапки: «Материалы»
   отделяют семь пунктов от двух, а не добавляют восьмую строку списка —
   поэтому это не ссылка и оно не нажимается. */
.site-drop__group {
    display: block;
    margin: var(--sp-3) var(--sp-4) 2px;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--text-subtle);
}
.site-drop__group:first-child { margin-top: 0; }
@media (max-width: 1199px) {
    .site-menu__group--sub { margin-left: var(--sp-4); text-transform: none; }
}

/* --- Статья: лонгриды и поисковые посадочные ------------------------- */
/* Оглавление слева, текст в колонке под меру строки. Сетка, а не флекс:
   колонка текста должна остаться 720 независимо от длины пунктов
   оглавления, иначе статья с длинными заголовками сжимается в лапшу. */
.article-layout { display: grid; grid-template-columns: 240px minmax(0, 720px); gap: var(--sp-9); align-items: start; }
/* Короткая статья идёт без оглавления, и колонка под него не просто
   пустует: единственный элемент сетки встаёт в ПЕРВУЮ колонку, то есть
   текст сжимается до 240 точек. Видно только на живой странице. */
.article-layout--single { grid-template-columns: minmax(0, 720px); }
.article-toc {
    position: sticky;
    top: var(--sp-6);
    padding: var(--sp-5);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
}
.article-toc > summary { list-style: none; cursor: default; font-size: var(--fs-2xs); font-weight: var(--fw-semibold); letter-spacing: var(--ls-wide); text-transform: uppercase; color: var(--text-subtle); }
.article-toc > summary::-webkit-details-marker { display: none; }
/* Отступ под номер задан в em, а не в шаге сетки: у пункта «12.» номер
   шире, чем у «1.», и при фиксированном отступе первая цифра
   уезжала за край рамки — в статье с тринадцатью разделами это
   каждый третий пункт. */
.article-toc ol { margin: var(--sp-4) 0 0; padding-left: 2em; display: flex; flex-direction: column; gap: var(--sp-2); }
.article-toc li { font-size: var(--fs-2xs); line-height: 1.4; }
.article-toc a { color: var(--text-muted); text-decoration: none; }
.article-toc a:hover { color: var(--accent); }

.article-body { font-size: var(--fs-site-small); line-height: 1.7; color: var(--text-body); }
.article-body > :first-child { margin-top: 0; }
.article-body h2 { margin: var(--sp-9) 0 var(--sp-5); font-size: var(--fs-xl); font-weight: var(--fw-bold); line-height: 1.25; }
.article-body h3 { margin: var(--sp-7) 0 var(--sp-4); font-size: var(--fs-lg); font-weight: var(--fw-semibold); line-height: 1.3; }
.article-body h4 { margin: var(--sp-6) 0 var(--sp-3); font-size: var(--fs-md); font-weight: var(--fw-semibold); }
/* Якорь — под липкой шапкой: без отступа переход по оглавлению ставит
   заголовок ровно ПОД неё, и читатель попадает на середину абзаца. */
.article-body h2[id] { scroll-margin-top: 88px; }
.article-body p { margin: 0 0 var(--sp-5); }
.article-body ul, .article-body ol { margin: 0 0 var(--sp-5); padding-left: var(--sp-6); }
.article-body li { margin-bottom: var(--sp-2); }
.article-body blockquote { margin: 0 0 var(--sp-5); padding-left: var(--sp-5); border-left: 2px solid var(--accent); color: var(--text-muted); }
.article-body a { color: var(--text-link); }
/* Таблица шире колонки прокручивается внутри себя, а не растягивает
   страницу: в статьях есть таблицы на пять колонок. */
.article-body table { display: block; width: 100%; overflow-x: auto; margin: 0 0 var(--sp-6); border-collapse: collapse; font-size: var(--fs-2xs); }
.article-body th, .article-body td { padding: var(--sp-3) var(--sp-4); border: var(--border-w) solid var(--border-subtle); text-align: left; vertical-align: top; }
.article-body th { background: var(--surface-sunken); font-weight: var(--fw-semibold); }
.article-body td p:last-child, .article-body th p:last-child { margin-bottom: 0; }

@media (max-width: 1023px) {
    .article-layout { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
    /* На узком экране оглавление из тринадцати пунктов занимает первый
       экран целиком. Ограничиваем высоту прокруткой, а не сворачиванием:
       содержимое <details> прячет БРАУЗЕР по атрибуту `open`, и
       обратное правило CSS ведёт себя по-разному в разных движках. */
    .article-toc { position: static; }
    .article-toc ol { max-height: 40vh; overflow-y: auto; }
}
.site-footer__contacts { margin: var(--sp-5) 0 0; line-height: 1.9; }
.site-footer__contacts a { color: inherit; }

/* --- Карточки слов ---------------------------------------------------- */
.cards-shell { max-width: 720px; margin: 0 auto; }
.cards-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.cards-counter { font-size: var(--fs-2xs); color: var(--text-muted); }
.cards-counter b { color: var(--text-body); font-variant-numeric: tabular-nums; }
.cards-modes { display: flex; gap: var(--sp-3); }

/* Карточка — кнопка: её нажимают, и она обязана работать с клавиатуры и
   читаться экранным диктором как то, что нажимают. */
.flashcard {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-4);
    width: 100%;
    min-height: 280px;
    padding: var(--sp-8) var(--sp-6);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    font-family: inherit;
    text-align: center;
    cursor: pointer;
    transition: var(--transition-control);
}
.flashcard:hover { border-color: var(--border-strong); }
.flashcard__front { font-size: 34px; font-weight: var(--fw-semibold); line-height: 1.25; color: var(--text-body); }
/* Иероглифы крупнее любого текста: в них смысл карточки, и на 34 px
   различить черты сложнее, чем прочитать слово. */
.flashcard__front.is-hanzi { font-family: var(--font-hanzi); font-size: 64px; line-height: 1.15; }
.flashcard__back { font-size: var(--fs-lg); color: var(--text-muted); white-space: pre-line; }
.flashcard__back.is-hanzi { font-family: var(--font-hanzi); font-size: 40px; color: var(--text-body); }
.flashcard__hint { font-size: var(--fs-2xs); color: var(--text-subtle); }
.cards-actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-6); }
.cards-note { margin-top: var(--sp-5); text-align: center; color: var(--text-subtle); }

/* --- Тест на уровень -------------------------------------------------- */
.test-pick__title { margin-bottom: var(--sp-6); }
.test-levels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
.test-level {
    display: flex; flex-direction: column; gap: 2px;
    padding: var(--sp-5) var(--sp-6);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    text-decoration: none;
    transition: var(--transition-control);
}
.test-level:hover { border-color: var(--accent); text-decoration: none; }
.test-level__num { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--accent); }
.test-level__name { font-size: var(--fs-site-small); font-weight: var(--fw-semibold); color: var(--text-body); }
.test-level__words { font-size: var(--fs-2xs); color: var(--text-muted); }

.test-shell { max-width: 720px; margin: 0 auto; }
.test-question { font-size: var(--fs-lg); font-weight: var(--fw-semibold); line-height: 1.4; margin-bottom: var(--sp-6); }
.test-pinyin { display: block; margin-top: var(--sp-2); font-size: var(--fs-site-small); font-weight: var(--fw-regular); color: var(--text-muted); }
/* `display` от класса перебивает правило браузера для [hidden]:
   авторская таблица стилей выигрывает у UA-стилей при любой
   специфичности. Без этой строки скрытые скриптом варианты остаются на
   экране вместе с итогом теста — видно только на живой странице. */
.test-options[hidden], .test-question[hidden], .test-explain[hidden],
.test-progress[hidden], .cards-actions[hidden] { display: none; }
.test-options { display: flex; flex-direction: column; gap: var(--sp-3); }
.test-option {
    padding: var(--sp-4) var(--sp-5);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-control);
    background: var(--surface-card);
    font-family: inherit;
    font-size: var(--fs-site-small);
    color: var(--text-body);
    text-align: left;
    cursor: pointer;
    transition: var(--transition-control);
}
.test-option:hover:not(:disabled) { border-color: var(--border-strong); }
.test-option:disabled { cursor: default; }
/* Верный ответ подсвечивается ВСЕГДА, даже когда выбран верно: иначе
   после ошибки непонятно, каким он был. */
.test-option.is-right { border-color: var(--jade-500, var(--secondary)); background: var(--status-success-soft); }
.test-option.is-wrong { border-color: var(--red-400); background: var(--status-danger-soft); }
.test-explain { margin-top: var(--sp-5); padding: var(--sp-4) var(--sp-5); border-radius: var(--r-md); font-size: var(--fs-2xs); }
.test-explain.is-right { background: var(--status-success-soft); color: var(--jade-700); }
.test-explain.is-wrong { background: var(--status-danger-soft); color: var(--red-700); }
.test-result { text-align: center; padding: var(--sp-8) 0; }
.test-result__score { font-size: 44px; font-weight: var(--fw-bold); color: var(--accent); line-height: 1; }
.test-result__percent { margin-top: var(--sp-3); font-size: var(--fs-lg); color: var(--text-body); }
.test-result__note { margin-top: var(--sp-5); color: var(--text-muted); }

@media (max-width: 767px) {
    .test-levels { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .flashcard { min-height: 220px; }
    .flashcard__front.is-hanzi { font-size: 52px; }
    .cards-actions .eddy-btn { flex: 1 1 auto; }
}

/* --- Получение сертификата -------------------------------------------- */
.cert-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5); align-items: start; }
.cert-form .eddy-field { margin-top: var(--sp-4); }
.cert-form .eddy-btn { margin-top: var(--sp-6); }
.cert-done { margin-bottom: var(--sp-6); border-color: var(--jade-200, var(--border-strong)); }
.cert-done .eddy-btn { margin-top: var(--sp-5); }
@media (max-width: 767px) { .cert-grid { grid-template-columns: 1fr; } }

/* --- Личная визитка ---------------------------------------------------- */
/* Страницу открывают по QR-коду с телефона: одна колонка под меру
   большого пальца, ссылки высотой не меньше площади нажатия. */
.card-page { max-width: 480px; padding-top: var(--sp-9); padding-bottom: var(--sp-9); }
.card-person { text-align: center; }
.card-person__name { font-size: var(--fs-xl); font-weight: var(--fw-bold); }
.card-person__role { margin: var(--sp-3) 0 var(--sp-6); color: var(--text-muted); font-size: var(--fs-2xs); line-height: 1.5; }
.card-links { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-5); }
.card-link {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-4);
    min-height: var(--tap-min, 44px);
    padding: var(--sp-3) var(--sp-5);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-control);
    background: var(--surface-card);
    font-size: var(--fs-site-small);
    color: var(--text-body);
    text-decoration: none;
    transition: var(--transition-control);
}
.card-link:hover { border-color: var(--accent); text-decoration: none; }
.card-link__go { color: var(--accent); }

/* --- Блоки внутри статьи ---------------------------------------------- */
/* Перенесённые со старого сайта страницы без этих блоков читались как
   сплошной текст: пропадали карточки, шаги и вопрос-ответ — всё, за что
   цепляется глаз и что нажимают. Классы наши (`article-*`) и объявлены
   только здесь: чужие имена столкнулись бы с правилами кита. */
.article-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); margin: 0 0 var(--sp-6); }
.article-card {
    padding: var(--sp-5) var(--sp-6);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
}
.article-card h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-md); font-weight: var(--fw-semibold); }
.article-card p:last-child { margin-bottom: 0; }
.article-card ul { margin-bottom: 0; }
/* Число или диапазон над заголовком карточки: «120+», «9–13». Красным и
   крупным — это то, ради чего карточку и читают. */
.article-card__num { display: block; margin-bottom: var(--sp-2); font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--accent); line-height: 1; }
.article-hanzi { display: block; margin-bottom: var(--sp-3); font-family: var(--font-hanzi); font-size: 32px; line-height: 1; color: var(--accent); }

.article-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); margin: 0 0 var(--sp-7); }
.article-stat { display: flex; flex-direction: column; gap: 2px; padding: var(--sp-4) var(--sp-5); border-left: 2px solid var(--accent); }
.article-stat__num { font-size: var(--fs-xl); font-weight: var(--fw-bold); line-height: 1.1; }
.article-stat span:last-child { font-size: var(--fs-2xs); color: var(--text-muted); line-height: 1.4; }

/* Врезка — мысль, которую автор вынес из потока. Отличает её от абзаца
   светлая подложка, и этого достаточно: полоса слева поверх заливки —
   второй раз то же самое, а на странице с карточками и таблицами лишний
   акцент делает шумной каждую из них. Полоса остаётся у цитаты
   (blockquote), где подложки нет и различать нечем. */
.article-note {
    margin: 0 0 var(--sp-6);
    padding: var(--sp-5) var(--sp-6);
    background: var(--accent-soft);
    border-radius: var(--r-md);
    font-size: var(--fs-site-small);
}

/* Вопрос-ответ раскрывается нажатием: список из десяти вопросов подряд
   с ответами занимает три экрана, и его перестают читать на четвёртом. */
.article-faq { margin: 0 0 var(--sp-7); border-top: var(--border-w) solid var(--border-subtle); }
.article-faq details { border-bottom: var(--border-w) solid var(--border-subtle); }
.article-faq summary {
    position: relative;
    list-style: none;
    padding: var(--sp-5) var(--sp-8) var(--sp-5) 0;
    cursor: pointer;
    font-size: var(--fs-site-small);
    font-weight: var(--fw-semibold);
    line-height: 1.4;
}
.article-faq summary::-webkit-details-marker { display: none; }
.article-faq summary::after {
    content: "";
    position: absolute; right: 6px; top: 50%;
    width: 8px; height: 8px;
    margin-top: -6px;
    border-right: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(45deg);
    transition: transform .15s ease;
}
.article-faq details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }
.article-faq details p { margin: 0 0 var(--sp-5); color: var(--text-muted); }

/* Путь ученика: «Китайский в детстве → Разговорная база → HSK». Стрелки
   рисует CSS, а не текст: в разметке они были отдельными <b>, и при
   переносе строки стрелка оставалась висеть в начале следующей. */
.article-path { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin: 0 0 var(--sp-6); }
.article-path span {
    padding: var(--sp-2) var(--sp-4);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-pill);
    background: var(--surface-card);
    font-size: var(--fs-2xs);
}
.article-path span + span::before { content: "→"; margin-right: var(--sp-3); color: var(--accent); }

@media (max-width: 767px) {
    .article-cards { grid-template-columns: 1fr; }
    .article-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Страница песни ---------------------------------------------------- */
.song-native { margin-top: var(--sp-4); font-size: var(--fs-xl); font-family: var(--font-hanzi); color: var(--text-body); }
.song-native__pinyin { font-family: var(--font-brand); font-size: var(--fs-md); color: var(--text-muted); margin-left: var(--sp-3); }
.song-block__title { margin-bottom: var(--sp-6); }

/* Проигрыватель ВКонтакте и Rutube — соотношение 16:9 держит обёртка:
   у iframe нет своего внутреннего размера, и без неё он схлопывается в
   полосу высотой 150 точек. */
.song-videos { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); max-width: 900px; }
.song-videos--two { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
.song-video { position: relative; padding-top: 56.25%; border-radius: var(--r-card); overflow: hidden; background: var(--ink-900); }
.song-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Строка песни: иероглифы, чтение, перевод — рядом, а не тремя
   колонками текста. Своей сеткой, а не <table>: на телефоне таблица
   уезжает в горизонтальную прокрутку, а строка песни должна просто
   переноситься. */
.song-lyrics { max-width: 900px; border-top: var(--border-w) solid var(--border-subtle); }
.song-line {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1.2fr);
    gap: var(--sp-4);
    padding: var(--sp-4) 0;
    border-bottom: var(--border-w) solid var(--border-subtle);
}
.song-line__hanzi { font-family: var(--font-hanzi); font-size: var(--fs-md); color: var(--text-body); }
.song-line__pinyin { font-size: var(--fs-site-small); color: var(--text-muted); }
.song-line__ru { font-size: var(--fs-site-small); color: var(--text-body); }

.song-words { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3) var(--sp-6); max-width: 900px; }
.song-word { display: grid; grid-template-columns: auto auto 1fr; gap: var(--sp-3); align-items: baseline; padding: var(--sp-2) 0; border-bottom: var(--border-w) solid var(--border-subtle); }
.song-word__hanzi { font-family: var(--font-hanzi); font-size: var(--fs-md); font-weight: var(--fw-semibold); }
.song-word__pinyin { font-size: var(--fs-2xs); color: var(--accent); white-space: nowrap; }
.song-word__ru { font-size: var(--fs-2xs); color: var(--text-muted); }

.song-about { max-width: 720px; font-size: var(--fs-site-small); line-height: 1.7; }
.song-nav { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; }

@media (max-width: 899px) {
    .song-videos--two { grid-template-columns: minmax(0, 1fr); }
    .song-line { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    /* На телефоне три колонки в строке дают по восемь знаков в каждой —
       строка песни рассыпается. Ставим одну под другой, а разделяет их
       та же линия снизу. */
    .song-words { grid-template-columns: minmax(0, 1fr); }
    .song-word { grid-template-columns: auto 1fr; }
    .song-word__ru { grid-column: 1 / -1; }
}

/* --- Учебник: список уроков ------------------------------------------- */
.lesson-list { display: flex; flex-direction: column; border-top: var(--border-w) solid var(--border-subtle); }
.lesson-row {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    gap: var(--sp-4);
    align-items: center;
    padding: var(--sp-4) var(--sp-3);
    border-bottom: var(--border-w) solid var(--border-subtle);
    text-decoration: none;
    color: inherit;
    transition: var(--transition-control);
}
.lesson-row:hover { background: var(--surface-card); text-decoration: none; }
.lesson-row__num { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--accent); line-height: 1; text-align: center; }
.lesson-row__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lesson-row__zh { font-family: var(--font-hanzi); font-size: var(--fs-md); color: var(--text-body); }
.lesson-row__ru { font-size: var(--fs-2xs); color: var(--text-muted); }
.lesson-row__meta { display: flex; gap: var(--sp-3); font-size: var(--fs-2xs); color: var(--text-subtle); white-space: nowrap; }

.lesson-audio { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }

/* --- Диалог с разбором по словам -------------------------------------- */
.dialogue + .dialogue { margin-top: var(--sp-8); }
.dialogue__title { margin-bottom: var(--sp-4); }
.dialogue__zh { max-width: 760px; font-family: var(--font-hanzi); font-size: var(--fs-xl); line-height: 2; }
/* Слово — кнопка: его нажимают, и оно обязано работать с клавиатуры.
   Пунктир снизу говорит, что здесь есть что открыть, но не спорит с
   текстом: сплошное подчёркивание на каждом слове превратило бы
   диалог в сетку. */
.dialogue .hz {
    padding: 0 1px;
    border: 0;
    border-bottom: 1px dashed var(--border-strong);
    background: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
    border-radius: 2px;
}
.dialogue .hz:hover { background: var(--accent-soft); }
.dialogue .hz.is-open { background: var(--accent); color: var(--text-inverse); border-bottom-color: transparent; }
.dialogue__ru { margin-top: var(--sp-5); max-width: 760px; }
.dialogue__ru summary { cursor: pointer; font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--text-muted); }
.dialogue__ru p { margin: var(--sp-3) 0 0; font-size: var(--fs-site-small); }

.hz-tip {
    position: absolute;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-width: 260px;
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r-md);
    background: var(--ink-900);
    color: var(--text-inverse);
    font-size: var(--fs-2xs);
    line-height: 1.4;
    box-shadow: var(--sh-lg);
}
.hz-tip b { font-family: var(--font-brand); color: var(--red-200, #f5b8b8); }

@media (max-width: 767px) {
    .lesson-row { grid-template-columns: 36px minmax(0, 1fr); }
    /* На телефоне пометки уходят под название, а не жмут его в лапшу. */
    .lesson-row__meta { grid-column: 2; }
    .dialogue__zh { font-size: var(--fs-lg); line-height: 2.1; }
}

/* --- Словарь HSK ------------------------------------------------------- */
.hsk-levels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
.hsk-level {
    display: flex; flex-direction: column; gap: 2px;
    padding: var(--sp-5) var(--sp-6);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    text-decoration: none;
    transition: var(--transition-control);
}
.hsk-level:hover { border-color: var(--accent); text-decoration: none; }
.hsk-level__num { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--accent); line-height: 1.1; }
.hsk-level__count { font-size: var(--fs-2xs); color: var(--text-muted); }
.hsk-level__name { margin-top: var(--sp-3); font-size: var(--fs-site-small); font-weight: var(--fw-semibold); color: var(--text-body); }
.hsk-level__about { font-size: var(--fs-2xs); color: var(--text-muted); line-height: 1.45; }

.hsk-tools { display: flex; align-items: center; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.hsk-search {
    flex: 1 1 auto;
    max-width: 420px;
    height: 44px;
    padding: 0 var(--sp-5);
    border: var(--border-w) solid var(--border-default);
    border-radius: var(--r-control);
    background: var(--surface-card);
    font-family: inherit;
    font-size: var(--fs-site-small);
}
.hsk-search:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring-focus); }
/* Счётчик показывает, сколько строк осталось после отбора: без него
   непонятно, поиск ничего не нашёл или список просто длинный. */
.hsk-count { font-size: var(--fs-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.hsk-note { margin-bottom: var(--sp-5); color: var(--text-subtle); }

.hsk-list { border-top: var(--border-w) solid var(--border-subtle); }
.hsk-word {
    display: grid;
    grid-template-columns: 48px 120px 130px minmax(0, 1fr) auto;
    gap: var(--sp-4);
    align-items: baseline;
    padding: var(--sp-3) var(--sp-2);
    border-bottom: var(--border-w) solid var(--border-subtle);
}
.hsk-word__n { font-size: var(--fs-2xs); color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.hsk-word__hanzi { font-family: var(--font-hanzi); font-size: var(--fs-lg); color: var(--text-body); }
.hsk-word__pinyin { font-size: var(--fs-2xs); color: var(--accent); }
.hsk-word__ru { font-size: var(--fs-site-small); color: var(--text-body); }
.hsk-word__pos { font-size: var(--fs-2xs); color: var(--text-subtle); white-space: nowrap; }
/* Без этой строки поиск по списку не работает ВООБЩЕ: скрипт ставит
   строке `hidden`, но правило браузера `[hidden]{display:none}` обычной
   силы, а наш `display:grid` — авторское, и оно выигрывает. Счётчик при
   этом честно показывал «6 найдено», а список оставался прежним, то
   есть поломка выглядела как работающая страница. */
.hsk-word[hidden], .hsk-group[hidden] { display: none; }
.hsk-empty { padding: var(--sp-8) 0; text-align: center; color: var(--text-muted); }

/* Разделы ступени 7–9. Открываются нажатием: пять тысяч строк подряд
   не листают. Первый раздел открыт — иначе страница встречает набором
   закрытых полос, по которым не видно, что внутри вообще есть слова. */
.hsk-group { border-bottom: var(--border-w) solid var(--border-subtle); }
.hsk-group__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-4) var(--sp-2);
    cursor: pointer;
    list-style: none;
    font-weight: var(--fw-semibold);
    color: var(--text-body);
}
.hsk-group__head::-webkit-details-marker { display: none; }
/* Своя стрелка, а не маркер браузера: у него он разного вида в разных
   браузерах и не выравнивается с текстом. */
.hsk-group__head::after {
    content: "";
    width: 8px; height: 8px;
    border-right: 2px solid var(--text-subtle);
    border-bottom: 2px solid var(--text-subtle);
    transform: rotate(45deg);
    margin-left: auto;
    transition: transform .15s ease;
}
.hsk-group[open] > .hsk-group__head::after { transform: rotate(-135deg); }
.hsk-group__name { font-size: var(--fs-site-small); }
.hsk-group__count {
    font-size: var(--fs-2xs);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.hsk-group__body { border-top: var(--border-w) solid var(--border-subtle); }
.hsk-group .hsk-word:last-child { border-bottom: 0; }

@media (max-width: 1023px) { .hsk-levels { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) {
    .hsk-levels { grid-template-columns: 1fr; }
    /* Пять колонок на телефоне дают по шесть знаков в каждой: номер и
       часть речи уходят, остальное встаёт в две строки. */
    .hsk-word { grid-template-columns: auto minmax(0, 1fr); gap: 2px var(--sp-4); padding: var(--sp-4) var(--sp-2); }
    .hsk-word__n, .hsk-word__pos { display: none; }
    .hsk-word__hanzi { grid-row: span 2; }
    .hsk-word__pinyin, .hsk-word__ru { grid-column: 2; }
}

/* --- Грамматика HSK ---------------------------------------------------- */
.gram-list { border-top: var(--border-w) solid var(--border-subtle); }
.gram-row {
    display: grid;
    grid-template-columns: 76px minmax(0, 1fr) auto;
    gap: var(--sp-5);
    align-items: center;
    padding: var(--sp-4) var(--sp-3);
    border-bottom: var(--border-w) solid var(--border-subtle);
    text-decoration: none;
    color: inherit;
    transition: var(--transition-control);
}
.gram-row:hover { background: var(--surface-card); text-decoration: none; }
/* Китайский термин слева — по нему тему узнают в учебнике, где она
   названа именно так, а не по русскому переводу. */
.gram-row__zh { font-family: var(--font-hanzi); font-size: var(--fs-md); color: var(--accent); }
.gram-row__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gram-row__title { font-size: var(--fs-site-small); font-weight: var(--fw-semibold); color: var(--text-body); }
.gram-row__sum { font-size: var(--fs-2xs); color: var(--text-muted); line-height: 1.45; }
.gram-row__meta { display: flex; gap: var(--sp-3); font-size: var(--fs-2xs); color: var(--text-subtle); white-space: nowrap; }

.gram-rule + .gram-rule { margin-top: var(--sp-9); padding-top: var(--sp-8); border-top: var(--border-w) solid var(--border-subtle); }
.gram-rule__title { margin-bottom: var(--sp-4); }
.gram-rule__text { max-width: 720px; font-size: var(--fs-site-small); line-height: 1.7; }
/* Схема конструкции — то, что уносят со страницы: правило словами
   забывается, схема остаётся. Поэтому она набрана крупно и стоит до
   объяснения. */
.gram-formula {
    display: inline-block;
    margin: 0 0 var(--sp-5);
    padding: var(--sp-3) var(--sp-5);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    font-family: var(--font-hanzi);
    font-size: var(--fs-md);
    line-height: 1.5;
}
.gram-examples { display: flex; flex-direction: column; gap: var(--sp-4); margin-top: var(--sp-5); max-width: 760px; }
/* Пример отличается от объяснения подложкой, и этого довольно: полоса
   слева поверх заливки — второй раз то же самое, а примеров на странице
   по три подряд, и лишний акцент делает шумной всю колонку. */
.gram-example {
    display: flex; flex-direction: column; gap: 2px;
    padding: var(--sp-4) var(--sp-5);
    background: var(--surface-card);
    border-radius: var(--r-md);
}
.gram-example__hanzi { font-family: var(--font-hanzi); font-size: var(--fs-lg); line-height: 1.5; }
.gram-example__pinyin { font-size: var(--fs-2xs); color: var(--accent); }
.gram-example__ru { font-size: var(--fs-site-small); color: var(--text-muted); }

@media (max-width: 767px) {
    .gram-row { grid-template-columns: 56px minmax(0, 1fr); }
    .gram-row__meta { grid-column: 2; }
    .gram-example__hanzi { font-size: var(--fs-md); }
}

/* --- Выбор теста ------------------------------------------------------- */
.test-choice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5); align-items: start; }
.test-choice__card {
    display: flex; flex-direction: column; gap: var(--sp-3);
    padding: var(--sp-7);
    border: var(--border-w) solid var(--border-subtle);
    border-radius: var(--r-card);
    background: var(--surface-card);
    text-decoration: none;
    color: inherit;
    transition: var(--transition-control);
}
.test-choice__card:hover { border-color: var(--accent); text-decoration: none; }
/* Новый стандарт — то, что нужно почти всем: он и выделен рамкой. */
.test-choice__card--main { border-color: var(--red-200, var(--accent)); }
.test-choice__card .eddy-badge { align-self: flex-start; }
.test-choice__title { font-size: var(--fs-xl); font-weight: var(--fw-bold); line-height: 1.2; }
.test-choice__sub { font-size: var(--fs-2xs); color: var(--text-muted); }
.test-choice__text { margin: var(--sp-3) 0 0; font-size: var(--fs-site-small); line-height: 1.6; }
.test-choice__list { margin: 0; padding-left: var(--sp-6); font-size: var(--fs-2xs); color: var(--text-muted); }
.test-choice__list li { margin-bottom: var(--sp-2); }
.test-choice__btn { align-self: flex-start; margin-top: var(--sp-5); }
.test-choice__note { margin-top: var(--sp-7); }

/* --- Тест по HSK 3.0 --------------------------------------------------- */
.site-pagehead--tight { padding-bottom: var(--sp-7); }
.test-shell--new { max-width: 760px; }
.test-progress { margin-bottom: var(--sp-7); }
/* Полоса показывает и пройденное, и до какой ступени человек дошёл: в
   тесте по возрастанию это и есть промежуточный результат. */
.test-progress__bar { height: 6px; border-radius: var(--r-pill); background: var(--surface-sunken); overflow: hidden; }
/* Растяжением, а не шириной: ширина заставляет браузер пересчитывать
   раскладку на каждом кадре, а transform живёт на слое композитора.
   Скруглённый левый край даёт обёртка (у неё overflow: hidden), поэтому
   своего радиуса полоске не нужно — растянутый, он всё равно исказился
   бы по горизонтали. */
.test-progress__bar span { display: block; height: 100%; width: 100%; transform: scaleX(0); transform-origin: left; background: var(--accent); transition: transform .25s ease; }
.test-progress__meta { display: flex; justify-content: space-between; gap: var(--sp-4); margin-top: var(--sp-3); font-size: var(--fs-2xs); color: var(--text-muted); }
.test-progress__meta b { color: var(--text-body); font-variant-numeric: tabular-nums; }

.test-result__level { font-size: 40px; font-weight: var(--fw-bold); color: var(--accent); line-height: 1.1; }
.test-result__links { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-7); }

@media (max-width: 767px) {
    .test-choice { grid-template-columns: 1fr; }
    .test-choice__card { padding: var(--sp-6); }
    .test-result__level { font-size: 32px; }
    .test-result__links .eddy-btn { flex: 1 1 auto; }
}

/* --- Разбор стандарта HSK ---------------------------------------------- */

.article { max-width: 860px; }
.article h2 { margin-top: var(--sp-9); margin-bottom: var(--sp-4); }
.article p { margin-bottom: var(--sp-4); line-height: 1.6; }
.article-facts, .article-steps { margin: 0 0 var(--sp-5); padding-left: var(--sp-6); }
.article-facts li, .article-steps li { margin-bottom: var(--sp-3); line-height: 1.6; }

/* Таблица шире экрана прокручивается ВНУТРИ своей обёртки: без неё
   вбок разъезжается вся страница, а на телефоне это ломает шапку. */
.table-scroll { overflow-x: auto; margin-bottom: var(--sp-6); }
.article-table { width: 100%; border-collapse: collapse; font-size: var(--fs-site-small); }
.article-table caption {
    caption-side: top;
    text-align: left;
    padding-bottom: var(--sp-3);
    font-size: var(--fs-2xs);
    color: var(--text-muted);
}
.article-table th, .article-table td {
    padding: var(--sp-3) var(--sp-4);
    border-bottom: var(--border-w) solid var(--border-subtle);
    text-align: left;
    vertical-align: top;
}
.article-table thead th {
    border-bottom: 2px solid var(--border-default);
    font-weight: var(--fw-semibold);
    white-space: nowrap;
}
.article-table .th-note { display: block; font-weight: var(--fw-regular); font-size: var(--fs-2xs); color: var(--text-muted); }
.article-table tbody tr:hover { background: var(--surface-subtle); }

.article-faq { margin-bottom: var(--sp-6); }
.faq-item { border-bottom: var(--border-w) solid var(--border-subtle); }
.faq-item > summary {
    padding: var(--sp-4) 0;
    cursor: pointer;
    list-style: none;
    font-weight: var(--fw-semibold);
    color: var(--text-body);
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
    content: "+";
    float: right;
    color: var(--text-subtle);
    font-weight: var(--fw-regular);
}
.faq-item[open] > summary::after { content: "−"; }
.faq-item > p { padding-bottom: var(--sp-4); color: var(--text-muted); }
