/* ========================================
   SERVICES OVERVIEW PAGE STYLES
   Prefix: sv-
   ======================================== */

/* Hero */
/* Высота, кегли и отступы — те же, что у «Турниров» и категорий:
   один сайт, шапки разделов должны читаться одинаково */
.sv-hero {
    position: relative;
    /* ПОЛ, ВОЗДУХ И ЛЕСТНИЦА ЖИВУТ В ОДНОМ МЕСТЕ — css/tokens.css, раздел
       «ОБЛОЖКА РАЗДЕЛА», решение Кости 04.10 и доска 482:9 блок N.
       Здесь своих чисел больше нет. Было: пол 460 при 360 у «Турниров» и
       «Рейтинга», воздух --section-y сверху и снизу, и на телефоне лёжа
       обложка выходила 460 при экране 390 — выше самого экрана. */
    min-height: var(--oblozhka-pol);
    padding: var(--oblozhka-vozduh) var(--pad-x) var(--oblozhka-vozduh-niz);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.sv-hero-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
}

.sv-hero-bg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Затемнение мягче: нижний край гасил снимок в сплошной чёрный, и от
   фотографии оставалась только верхняя полоска */
.sv-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        var(--alpha-black-50) 0%,
        rgba(10, 10, 10, 0.88) 100%
    );
    z-index: 1;
}

.sv-hero-content {
    position: relative;
    z-index: 2;
}

/* СТУПЕНЬ, А НЕ ДОЛЯ ШИРИНЫ. `clamp(1.9rem, 4.4vw, 3.1rem)` давал
   26 · 37.1 · 26 · 45.1 · 49.6 — три значения из пяти мимо шкалы кеглей.
   `--fs-hero` даёт 26 · 32 · 32 · 40 · 40, и это те же числа, что на
   «Турнирах» и «Рейтинге»: раздел один, шапки должны читаться одинаково. */
.sv-hero h1 {
    font-size: var(--fs-hero);
    font-weight: var(--fw-extrabold);
    color: var(--text-primary);
    margin-bottom: var(--space-4);
    line-height: var(--lh-tight);
}

.sv-hero h1 span {
    color: var(--accent);
}

/* Подзаголовок — та же крутилка, что у «Турниров»: 16 · 18 · 18 · 21 · 21.
   Было 14 · 18.6 · 16.9 · 20.8 · 20.8 — четыре значения из пяти мимо шкалы. */
.sv-hero p {
    font-size: var(--fs-hero-sub);
    font-weight: var(--fw-semibold);
    color: var(--text-secondary);
    max-width: 720px;
    margin: 0 auto;
    line-height: var(--lh-normal);
}

/* Two columns layout */
.sv-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-xl);
    padding: var(--space-md) var(--pad-x) var(--section-y);
}

/* Заголовок колонки едет вместе с содержимым, а не липнет к шапке:
   липкая плашка наезжала на карточки и закрывала метки со скидкой */
.sv-column-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-md);
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: 0 0 12px;
    border-bottom: var(--bw-hair) solid var(--border-subtle);
}

/* ЗАГОЛОВОК КОЛОНКИ СТОИТ ВЫШЕ ИМЕНИ КАРТОЧКИ ПОД НИМ. Замер 06.10: h2
   был 18, а h3 главной карточки — 21, то есть лестница перевёрнута на
   самом видном месте страницы. Ступень 21 против 18 у имени. */
.sv-column-title {
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--text-primary);
}

.sv-column-title span {
    color: var(--accent);
}

/* ЦЕЛЬ НАЖАТИЯ — НАСТОЯЩЕЙ ВЫСОТОЙ, А МЕСТО В ПОТОКЕ ОСТАЁТСЯ ПРЕЖНИМ.
   Замер 06.10: ссылка отдавала 21 при норме 44, и таких на странице три.
   Поле растит коробку до 45, отрицательная отбивка возвращает строку на
   место — заголовок колонки не едет. */
.sv-view-all {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding-block: var(--space-3);
    margin-block: calc(-1 * var(--space-3));
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    transition: opacity 0.2s;
}

.sv-view-all:hover {
    opacity: 0.8;
}

.sv-view-all svg {
    transition: transform 0.2s;
}

.sv-view-all:hover svg {
    transform: translateX(3px);
}

/* Prevent grid children from overflowing columns */
.sv-section {
    min-width: 0;
}

/* Card grid: featured on top, carousel below */
.sv-card-grid {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    min-width: 0;
}

/* Featured card (big) */
.sv-featured {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    /* Одна высота у корта и тренера: у тренера на строку больше данных,
       и колонки стояли уступом */
    height: 340px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    border: var(--bw-hair) solid var(--border-subtle);
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}

.sv-featured:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 40px var(--alpha-black-30);
}

.sv-featured-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
}

.sv-featured-bg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.sv-featured-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, var(--alpha-black-85) 0%, var(--alpha-black-50) 50%, var(--alpha-black-20) 100%);
    z-index: 1;
}

.sv-featured-content {
    position: relative;
    z-index: 2;
    padding: var(--space-lg);
}

.sv-featured-content h3 {
    font-size: var(--fs-md);
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.sv-featured-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: var(--fs-sm);
    color: var(--text-secondary);
    margin-bottom: var(--space-sm);
}

.sv-featured-meta span {
    display: flex;
    align-items: center;
    gap: 5px;
}

.sv-featured-meta svg {
    flex-shrink: 0;
    color: var(--text-muted);
}

.sv-featured-details {
    display: flex;
    gap: var(--space-md);
    flex-wrap: wrap;
    margin-bottom: var(--space-md);
}

.sv-featured-detail {
    font-size: var(--fs-xs);
}

.sv-featured-detail .sv-label {
    color: var(--text-muted);
    text-transform: uppercase;
    font-size: var(--fs-2xs);
    letter-spacing: 0.5px;
    display: block;
    margin-bottom: 2px;
}

.sv-featured-detail .sv-value {
    color: var(--text-primary);
    font-weight: 600;
}

.sv-featured-detail .sv-value.accent {
    color: var(--accent);
}

/* ВЫСОТА КНОПКИ — СТУПЕНЬ, А НЕ ПОЛЯ. Замер 07.10: ссылка главной карточки
   отдавала 41, кнопка игрока 35 — ни то, ни другое не стоит на шкале кнопок
   (28 · 36 · 44 · 52) и обе ниже цели нажатия 44 (`Button 17:82`, md). */
.sv-featured-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--btn-h-md);
    padding: 0 28px;
    background: var(--accent);
    color: var(--neutral-black);
    font-size: var(--fs-sm);
    font-weight: 700;
    border-radius: var(--radius-md);
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: background 0.2s, transform 0.2s;
}

.sv-featured-link:hover {
    background: var(--accent-hover);
    transform: translateY(-1px);
}

/* Coach avatar in featured */
.sv-coach-avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    border: var(--bw-thick) solid var(--accent);
    margin-bottom: var(--space-sm);
}

/* ========================================
   CAROUSEL — horizontal scroll with arrows
   ======================================== */

.sv-carousel-wrap {
    position: relative;
    overflow: hidden;
}

/* ТО ЖЕ, ЧТО У ЛЕНТЫ ЛОГОТИПОВ: лента везёт карточки услуг, и родитель
   режет всё за краем. Движение снимается, прокрутка отдаётся пальцу,
   затемнение краёв гасится — иначе оно прячет то, что теперь листают. */
@media (prefers-reduced-motion: reduce) {
    .sv-carousel {
        animation: none !important;
        transform: none !important;
    }
    .sv-carousel-wrap {
        overflow-x: auto;
    }
    .sv-carousel-wrap::before,
    .sv-carousel-wrap::after {
        display: none;
    }
}

/* Fade edges */
.sv-carousel-wrap::before,
.sv-carousel-wrap::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 30px;
    z-index: 3;
    pointer-events: none;
}

.sv-carousel-wrap::before {
    left: 0;
    background: linear-gradient(to right, var(--bg-primary), transparent);
}

.sv-carousel-wrap::after {
    right: 0;
    background: linear-gradient(to left, var(--bg-primary), transparent);
}

.sv-carousel {
    align-items: stretch;
    display: flex;
    gap: var(--space-md);
    width: max-content;
    /* СКОРОСТЬ — ЭТО ВРЕМЯ НА ОДНУ КАРТОЧКУ, А НЕ ВРЕМЯ НА ЛЕНТУ.
       Замерено на ленте спонсоров лендинга (css/style.css:4659 и 4748):
       путь 2480 / 90 с при шаге плитки 248 — ровно 9 с на плитку на
       широких видах, и 1920 / 110 с при шаге 192 — 11 с на узких.
       Время на ленту задавать нельзя: оно привязано к числу кортов,
       и с одним кортом лента летела за 12 с (js/services.js:393
       считал `children.length / 2`, а детей стало два прохода). */
    --sv-shag: 9s;
    --sv-karto4ek: 1;
    animation: svScroll calc(var(--sv-shag) * var(--sv-karto4ek)) linear infinite;
}


.sv-carousel-wrap:hover .sv-carousel {
    animation-play-state: paused;
}

/* Compact card — fixed width for carousel */
.sv-compact {
    display: flex;
    flex-direction: column;
    /* Один размер у кортов и тренеров: у корта широкое фото, у тренера
       круглый портрет, и ленты стояли уступом и разной ширины */
    width: 220px;
    min-width: 220px;
    max-width: 220px;
    /* ВЫСОТА — СЛЕДСТВИЕ СОДЕРЖИМОГО, А НЕ ЧИСЛО. Было 244 намертво, и при
       фото 170×123 карточка читалась приплюснутой: отношение 1.4 вместо
       эталонных 4:3. Ровность ряда даёт сам ряд, а не число у карточки. */
    padding: var(--space-md);
    background: var(--bg-card);
    border: var(--bw-hair) solid var(--border-subtle);
    border-radius: var(--radius-lg);
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s;
    scroll-snap-align: start;
    flex-shrink: 0;
}

.sv-compact:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px var(--alpha-black-30);
    border-color: var(--accent);
}

/* ОТНОШЕНИЕ ФОТО ОБЪЯВЛЕНО ОДИН РАЗ — 4:3, как на лендинге и на кортах.
   Слово Кости 07.10. При ширине полосы 170 это 128 вместо 100: карточка
   подрастает ровно настолько, насколько фото перестаёт быть сплющенным. */
.sv-compact-photo {
    width: 100%;
    aspect-ratio: 4 / 3;
    height: auto;
    display: block;
    object-fit: cover;
    border-radius: var(--radius-md);
    margin-bottom: var(--space-sm);
}

/* Портрет тренера занимает ту же полосу, что фото корта: карточки в лентах
   стоят рядом и должны выглядеть одинаково */
.sv-compact-avatar {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    object-fit: cover;
    border: var(--bw-thick) solid var(--border-subtle);
    margin: 14px auto var(--space-sm);
    display: block;
}

/* Портрет тренера стоит в коробке того же отношения, что фото корта:
   ленты идут рядом и должны быть одного роста */
.sv-carousel[data-type="coaches"] .sv-compact-img-wrap {
    aspect-ratio: 4 / 3;
    height: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-sm);
}

.sv-compact-icon {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-md);
    background: var(--alpha-lime-12);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    margin-bottom: var(--space-sm);
}

/* ДВЕ ЛЕНТЫ ЧИТАЮТСЯ КАК ОДИН РЯД — слово Кости 07.10: «Корты и Тренеры
   должны быть идентичны». Ширина, поля, радиус и коробка фото у них и так
   одни: это один компонент. Расходилась только ВЫСОТА, и расходилась она
   не сама — её давало число строк имени. Замер 07.10: у кортов имя
   укладывалось в строку, у пробной карточки тренера шло в две, и карточка
   выходила 266 против 245 на 1440 и 238 против 217 на 390.
   Замораживается ОТНОШЕНИЕ, а не число: имени ВСЕГДА отведены две строки —
   короткое имя их держит пустыми, длинное занимает обе и не обрывается
   многоточием. Высота обеих лент становится одинаковой по построению. */
.sv-compact h4 {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 4px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: var(--lh-snug);
    min-height: calc(2 * var(--lh-snug) * 1em);
    overflow: hidden;
}

.sv-compact-sub {
    font-size: var(--fs-xs);
    color: var(--text-muted);
    margin-bottom: var(--space-xs);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sv-compact-sub svg {
    vertical-align: -2px;
    margin-right: 3px;
}

.sv-compact-price {
    font-size: var(--fs-sm);
    font-weight: 700;
    color: var(--accent);
    white-space: nowrap;
    margin-top: auto;
}

@keyframes svScroll {
    0% { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}

/* ========================================
   PARTNERS SECTION — centered below columns
   ======================================== */

/* Раздел во всю ширину и по левому краю, как корты и тренеры: он был
   зажат в половину и центрирован, отчего заголовок и поиск стояли
   посреди страницы, ни с чем не совпадая */
.sv-partners-section {
    grid-column: 1 / -1;
    max-width: none;
    margin: 0;
}

/* Partner initials (featured) */

/* Partner online/offline status */






/* Empty state */
.sv-empty {
    text-align: center;
    padding: var(--space-xl) var(--space-lg);
    color: var(--text-muted);
    font-size: var(--fs-base);
}

.sv-empty svg {
    display: block;
    margin: 0 auto var(--space-sm);
    opacity: 0.3;
}

/* ========================================
   DISCOUNT BADGES
   ======================================== */

.sv-discount-overlay {
    position: absolute;
    top: 14px;
    right: 14px;
    /* скидка говорит лаймом — см. разбор в courts.css */
    background: var(--accent);
    color: var(--neutral-black);
    font-size: var(--fs-xs);
    font-weight: 700;
    padding: 5px 12px;
    border-radius: 100px;
    z-index: 3;
    backdrop-filter: blur(4px);
}

.sv-compact-img-wrap {
    position: relative;
}

.sv-discount-overlay-sm {
    position: absolute;
    top: 6px;
    right: 6px;
    /* скидка говорит лаймом — см. разбор в courts.css */
    background: var(--accent);
    color: var(--neutral-black);
    font-size: var(--fs-2xs);
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 100px;
    z-index: 2;
}

/* ========================================
   SPONSORS
   ======================================== */


/* ========================================
   RESPONSIVE
   ======================================== */

/* ДВА БЛОКА ≤992 СВЕДЕНЫ В ОДИН 13.10. Они стояли подряд, без единого
   объявления между ними, то есть второй ничего не перебивал — просто
   второе определение одного условия. Два блока ≤640 ниже НЕ сводятся, и
   это проверено чтением: между ними лежат объявления компонента
   `.sv-player-*`, и правило из середины файла проигрывало бы им молча
   (замер 07.10). Там разделение — приём, здесь было дублирование.

   ГРАНИЦА 768 СВЕДЕНА К 992 — ширины в медиа только 640 и 992.
   Единственный вид, который от этого менялся, — телефон лёжа 844: он стоял
   в двух колонках и ушёл бы в одну. Он возвращается себе ниже, по ВЫСОТЕ И
   ПОВОРОТУ, а не новой шириной.
   Кегли обложки из этого блока убраны: их держит `--fs-hero` в tokens.css,
   и своё объявление спорило бы с общей крутилкой. */
@media (max-width: 992px) {

    .sv-columns {
        gap: var(--space-lg);
        grid-template-columns: 1fr;
        padding: var(--section-y-sm) var(--pad-x);
    }

    .sv-partners-section {
        max-width: 100%;
    }

    .sv-featured {
        min-height: 260px;
    }

    /* Правило имени главной карточки на ≤992 снято: оно ставило `--fs-md`,
       то же, что теперь стоит в самом компоненте. ОДНО ОПРЕДЕЛЕНИЕ НА ОДНО
       ПОНЯТИЕ — проверено чтением, объявление было мёртвым. */

    .sv-compact {
        min-width: 170px;
        max-width: 190px;
    }

    /* ШАГ ЛЕНТЫ КАК НА ЛЕНДИНГЕ. У спонсоров узкий вид едет 11 с на
       плитку: `css/style.css:4203` даёт дорожке 110 с, проход — половина
       из двадцати плиток, то есть 11 с на плитку.
       ГРАНИЦА У СПОНСОРОВ — 992, А НЕ 768 (правка 27.10, кусок 198):
       прежняя запись здесь называла 768, и на этой ошибке ниже выросла
       вторая — перебивка шага для телефона лёжа. ИСТОЧНИК: файл и строка,
       а не память. */
    .sv-carousel {
        --sv-shag: 11s;
    }
}

/* ГРАНИЦЫ 480 И 375 СВЕДЕНЫ К 640. Из них убрано всё, что теперь держат
   крутилки обложки, и лестница колонки собрана в одну ступень: заголовок
   18, имя карточки 16 — шаг между ними сохраняется и на телефоне. */
@media (max-width: 640px) {

    .sv-column-title {
        font-size: var(--fs-md);
    }

    .sv-featured {
        min-height: 240px;
    }

    .sv-featured-content {
        padding: var(--space-md);
    }

    .sv-featured-content h3 {
        font-size: var(--fs-base);
    }

    .sv-featured-details {
        gap: var(--space-sm);
    }

    .sv-compact {
        min-width: 150px;
        max-width: 170px;
        padding: var(--space-sm);
    }

    /* Правило имени на ≤640 снято: оно ставило `--fs-sm`, то же, что стоит
       в самом компоненте. Проверено чтением, а не по виду — объявление
       было мёртвым. */

    /* Третья строка имени — только там, где колонка узкая. Замер 06.10:
       на телефоне обрезано 5 имён из 10 при двух строках */
    .sv-player-name {
        -webkit-line-clamp: 3;
    }
}


/* ==== Игроки: две ленты навстречу друг другу ==== */
/* Десять игроков в рамке, ровными рядами: карточки того же размера, что
   в лентах кортов и тренеров */
.sv-players-box {
    display: grid;
    /* Пять в ряд, когда людей много. Но жёсткие пять оставляли дыру справа,
       если нашлось трое: пустые колонки всё равно занимали ширину, и блок
       выглядел недорисованным. Теперь колонок ровно столько, сколько карточек,
       но не больше пяти */
    /* ПЯТЬ В РЯД — слово Кости 07.10. Минимум поднят с 210 до 220, то есть
       до ширины карточки карусели: при коробке 1338 это даёт ровно пять
       колонок вместо шести, а ниже — четыре, три и две, без единой новой
       границы. Зазор со шкалы: было 14, стало 16. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    justify-items: center;
    gap: var(--space-sm);
    border: var(--bw-hair) solid var(--border-subtle);
    border-radius: var(--radius-xl);
    background: var(--surface-glass);
    padding: 18px;
    margin-top: 14px;
}

/* Одна карточка в ряду — рамку и фон убираем: пустая коробка во всю
   ширину читается как поломка, будто остальное не загрузилось.
   Появится второй игрок — рамка вернётся сама */
.sv-players-box:has(> :only-child) {
    border: none;
    background: none;
    padding: 0;
}

/* ─────────────────────────────────────────────────────────────────────
   ДВА РЯДА — ЭТО ОТНОШЕНИЕ, А НЕ ЧИСЛО.
   Слово Кости 07.10: «только 2 ряда». Правило то же, что у новостей
   лендинга (css/style.css:10621): показываем столько, сколько заполняет
   ряды ЦЕЛИКОМ, — то есть колонок × 2. Число колонок у `auto-fit` —
   следствие ширины, а не вида: замер 07.10 дал 5 · 4 · 3 при одной и
   той же границе 992. Поэтому колонки считает js и пишет сюда
   `data-vidno`, а css держит отношение. Останова по ширине не заведено.
   ───────────────────────────────────────────────────────────────────── */
.sv-players-box[data-vidno="2"] > .sv-player:nth-child(n+3),
.sv-players-box[data-vidno="4"] > .sv-player:nth-child(n+5),
.sv-players-box[data-vidno="6"] > .sv-player:nth-child(n+7),
.sv-players-box[data-vidno="8"] > .sv-player:nth-child(n+9),
.sv-players-box[data-vidno="10"] > .sv-player:nth-child(n+11) {
    display: none;
}

/* ГРАНИЦЫ 1100 И 700 СНЯТЫ ЦЕЛИКОМ: число колонок — следствие ширины
   карточки, а не экрана. Остался один вид, который решали числом, —
   телефон: его блок стоит В КОНЦЕ ФАЙЛА, после самих компонентов.
   Замер 07.10: правило на портрет и мету, стоявшее здесь, проигрывало
   объявлениям компонента ниже по файлу — медиа цепкости не добавляет. */
.sv-player {
    position: relative;
    width: 100%;
    /* Шире этого карточка пустеет: внутри аватар, имя и кнопка по центру, и
       на растянутой колонке они повисают в воздухе */
    max-width: 260px;
    /* Высота от содержимого и поля карусельной карточки: две витрины стоят
       на одной странице и не должны выглядеть разными компонентами */
    min-height: 244px;
    display: flex;
    flex-direction: column;
    padding: var(--space-md);
    background: var(--bg-card);
    border: var(--bw-hair) solid var(--border-subtle);
    border-radius: var(--radius-lg);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.2s, transform 0.2s;
}

.sv-player:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}

/* Категория — главное, что человек читает: он ищет ровню */
/* Ряд вместо двух углов: NTRP слева, разряд справа, и между ними зазор,
   который не даёт им встретиться. Пустая левая клетка держит разряд
   справа у тех, у кого NTRP нет */
.sv-player-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-xs);
    margin-bottom: var(--space-xs);
    min-height: 32px;
}

.sv-player-ntrp-net {
    visibility: hidden;
}

.sv-player-cat {
    text-align: right;
    font-size: var(--fs-2xs);
    font-weight: 800;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--accent);
}

/* Рейтинг — то, по чему ищут ровню: крупно и слева, напротив категории */
.sv-player-ntrp {
    font-size: var(--fs-md);
    font-weight: 800;
    line-height: 1;
    color: var(--accent);
    letter-spacing: -0.02em;
}

.sv-player-ntrp small {
    display: block;
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 1px;
    /* 3.21 при норме 4.5 — тихий текст не получает скидки у WCAG */
    color: var(--text-muted);
    margin-top: 2px;
}

.sv-player-ava-wrap {
    position: relative;
    width: 64px;
    margin: 6px auto 10px;
}

.sv-player-ava {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    border: var(--bw-thick) solid var(--border-light);
    display: block;
}

.sv-player-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-elevated);
    color: var(--text-muted);
    font-weight: 700;
}

.sv-player-dot {
    position: absolute;
    right: 2px;
    bottom: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--success);
    border: var(--bw-thick) solid var(--bg-card);
}

.sv-player-name {
    font-size: var(--fs-sm);
    font-weight: 700;
    margin-bottom: 4px;
    /* Длинное имя переносим на вторую строку, а не обрезаем многоточием:
       «Татьяна Неча…» не говорит, кому предлагаешь игру. Дальше двух строк
       не пускаем — иначе карточки в ряду разъедутся по высоте */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
    line-height: var(--lh-snug);
}

.sv-player-level {
    font-size: var(--fs-xs);
    color: var(--text-secondary);
    margin-bottom: 2px;
}

/* Когда человек заходил в последний раз: по этому решают, писать ли */
.sv-player-seen {
    font-size: var(--fs-xs);
    /* было --text-dim: 3.21 при норме 4.5 */
    color: var(--text-muted);
    margin-bottom: 12px;
}

.sv-player-seen.is-online {
    color: var(--success);
}

.sv-player-btn {
    width: 100%;
    margin-top: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--btn-h-md);
    padding: 0 var(--space-xs);
    border-radius: var(--radius-full);
    border: var(--bw-hair) solid var(--border-subtle);
    background: transparent;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: var(--fs-xs);
    font-weight: 600;
    /* Межстрочный у кнопки задан, а не оставлен браузеру: `normal` зависит
       от шрифта и съезжает вместе с ним. Замер 13.10 поймал два таких
       места — здесь и у кнопки страницы спонсоров. */
    line-height: var(--lh-none);
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s;
}

.sv-player-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* На телефоне и планшете однострочная подпись обрезалась почти вдвое: от
   «ТЕСТ второй категории — Tour мужской одиночный» оставалось меньше
   половины. Даём две строки, многоточие остаётся */
/* Правило ≤992 здесь было: две строки имени вместо одной. Теперь две
   строки стоят в самом компоненте на всех видах, и второе объявление
   того же понятия снято. */


/* ─────────────────────────────────────────────────────────────────────
   ТЕЛЕФОН СТОЯ: ДВЕ КАРТОЧКИ В РЯД, ДВА РЯДА.
   Слово Кости 07.10. `auto-fit` с минимумом 220 давал на телефоне ОДНУ
   колонку и девять рядов: коробка 2518 при экране 844 — шесть экранов на
   одну витрину (замер 07.10). Две в ряд и ступень текста взяты с новостей
   лендинга: там на телефоне две в ряд, зазор 12, имя 14, мета 11
   (css/style.css:10615 и замер 390 × 844).
   БЛОК СТОИТ ЗДЕСЬ, А НЕ ВЫШЕ: объявления компонента `.sv-player-*` лежат
   между, и медиа цепкости не добавляет — правило из середины файла
   проигрывало им молча (замер 07.10: портрет оставался 64, мета 12).
   ───────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
    .sv-players-box {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-3);
        padding: var(--space-3);
    }

    /* Ширину колонки задаёт сетка, высоту — содержимое */
    .sv-player {
        max-width: none;
        min-height: 0;
        padding: var(--space-3);
    }

    /* Портрет с 64 до 48: при колонке 160 круг в 64 забирал больше трети
       ширины карточки */
    .sv-player-ava-wrap {
        width: 48px;
        margin: 4px auto var(--space-2);
    }

    .sv-player-ava {
        width: 48px;
        height: 48px;
    }

    .sv-player-top {
        min-height: 0;
    }

    .sv-player-ntrp {
        font-size: var(--fs-base);
    }

    .sv-player-level,
    .sv-player-seen {
        font-size: var(--fs-2xs);
    }

    .sv-player-seen {
        margin-bottom: var(--space-2);
    }
}

/* ─────────────────────────────────────────────────────────────────────
   ТЕЛЕФОН ЛЁЖА: ДВЕ КОЛОНКИ ОСТАЮТСЯ.
   Граница 768 сведена к 992, и 844 в ширину попал бы в одну колонку.
   Вид делится ВЫСОТОЙ И ПОВОРОТОМ — ширин в медиа по-прежнему две.
   ───────────────────────────────────────────────────────────────────── */
@media (max-height: 500px) and (orientation: landscape) {
    .sv-columns {
        grid-template-columns: 1fr 1fr;
    }

    /* ПЕРЕБИВКА ШАГА СНЯТА 27.10, КУСКОМ 198. Здесь стояло 9 с со
       ссылкой на «правило 110 с на max-width: 768, а 844 шире» — и это
       было неверно: у спонсоров граница 992 (`css/style.css:4192`), и
       844 попадает ВНУТРЬ неё. То есть на телефоне лёжа лента спонсоров
       едет 11 с на плитку, а лента услуг — 9 с: расхождение, которое
       поймала проба 63 на phone-landscape.
       Теперь шаг приходит от `max-width: 992` выше и равен 11 с, как у
       спонсоров на том же виде. ЗАМОРАЖИВАЕТСЯ ОТНОШЕНИЕ, А НЕ ЧИСЛО:
       «столько же, сколько у спонсоров», а не «девять». */

    /* ─────────────────────────────────────────────────────────────────
       ВИТРИНА ИГРОКОВ ЛЁЖА — ЛЕНТА, КАК НОВОСТИ ЛЕНДИНГА.
       Слово Кости 07.10: «в горизонтальном положении также как на
       лендинге». Там это полоса с прилипанием (css/style.css:10641).
       Замер до правки: три колонки, три ряда, коробка 869 при экране
       390 — две с лишним высоты экрана на одну витрину. Дефицит здесь
       ВЫСОТА, поэтому вид делится высотой и поворотом, а не шириной.
       Ширина карточки 220 — та же, что у карточки карусели выше на этой
       же странице: две витрины не должны выглядеть разными размерами.
       Плитки «все» в конце нет: ссылка «смотреть всех» стоит в шапке
       раздела и в ленте видна — у новостей в сетке ту же роль играет
       та же ссылка (css/style.css:10692).
       ───────────────────────────────────────────────────────────────── */
    .sv-players-box {
        display: flex;
        grid-template-columns: none;
        gap: var(--space-3);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding: var(--space-3);
    }

    .sv-players-box::-webkit-scrollbar {
        display: none;
    }

    /* В ЛЕНТЕ ПОКАЗЫВАЕМ ВСЕХ: прятать нечего, вниз она не растёт.
       Цепкость :nth-child(n) НАРОЧНО — ровно та же, что у потолка в два
       ряда выше по файлу, и побеждает порядком. Приём взят у новостей
       лендинга (css/style.css:10653). */
    .sv-players-box[data-vidno] > .sv-player:nth-child(n) {
        display: flex;
        flex: 0 0 220px;
        width: 220px;
        max-width: 220px;
        scroll-snap-align: start;
    }
}


                                                                        
                                           
                                                                      
                                                           
                                                                           
.sv-compact:focus-visible,
.sv-player:focus-visible,
.sv-featured:focus-visible,
.sv-view-all:focus-visible,
.sv-featured-link:focus-visible,
.sv-player-btn:focus-visible{
    outline: var(--bw-heavy) solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-md);
}


/* ─────────────────────────────────────────────────────────────────────
   КАРТОЧКА — ССЫЛКА, И ЭТО ВИДНО ДЕРЕВУ ДОСТУПНОСТИ.
   Замер 06.10: на странице 57 нажимаемых мест и 15 фокусируемых. 42
   карточки были `div` с обработчиком: ни с клавиатуры, ни в новую вкладку.
   ───────────────────────────────────────────────────────────────────── */
.sv-compact {
    color: inherit;
}

/* Второй проход ленты — только для глаза. `display: contents` растворяет
   обёртку: её карточки остаются детьми той же ленты, и раскладка не
   меняется, а `aria-hidden` на обёртке убирает из оглавления 16 лишних
   заголовков */
.sv-carousel-pass {
    display: contents;
}

/* Клон не берётся клавиатурой: иначе обход шёл бы по карточкам дважды */
.sv-carousel-pass[aria-hidden="true"] .sv-compact {
    pointer-events: none;
}

/* СЛОЙ-ССЫЛКА КАРТОЧКИ ИГРОКА.

   ПОПРАВКА К СОБСТВЕННОЙ ЗАПИСИ, 13.10. Здесь стояло «лежит ПОД содержимым
   (z-index 0), поэтому кнопка остаётся нажимаемой». Замер показал цену:
   нажатие на фотографию попадало в `IMG`, на имя — в `DIV`, и ссылка
   срабатывала ТОЛЬКО на пустых полях карточки. Обработчика на карточке нет
   вовсе — значит половина карточки не вела никуда.

   Правило, выведенное 04.10 на полосе турнира, здесь не было применено:
   СОДЕРЖИМОЕ СЪЕДАЕТ СЛОЙ, ЕСЛИ СЛОЙ ПОД НИМ. Слой поднят над содержимым,
   а кнопка «Предложить игру» — над слоем. */
.sv-player > * {
    position: relative;
    z-index: 1;
}

.sv-player > .sv-player-cover {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    text-decoration: none;
}

/* Своё действие выше ссылки — иначе слой съел бы кнопку */
.sv-player > .sv-player-btn {
    z-index: 3;
}

/* КОЛЬЦО ФОКУСА У СЛОЯ. Нашла заморозка 13.10: слой — единственное, что
   берёт фокус в карточке, и своего кольца у него не было ни одного.
   Человек, идущий Tab, не видел, какую карточку выбрал. */
.sv-player > .sv-player-cover:focus-visible {
    outline: var(--bw-thick) solid var(--accent);
    outline-offset: 2px;
}
