/* ========================================
   PLAYERS / RANKINGS PAGE STYLES
   Prefix: pl-
   ======================================== */

/* === HERO === */
/* Высота, кегли и отступы — те же, что у «Турниров» и категорий:
   один сайт, шапки разделов должны читаться одинаково */
.pl-hero {
    position: relative;
    /* ПОЛ, ВОЗДУХ И ЛЕСТНИЦА ЖИВУТ В ОДНОМ МЕСТЕ — css/tokens.css, раздел
       «ОБЛОЖКА РАЗДЕЛА». Здесь своих чисел больше нет. Было: пол 460 и
       воздух --section-y с обеих сторон — четвёртое семейство обложек в
       продукте со своими числами. */
    padding: var(--oblozhka-vozduh) var(--pad-x) var(--oblozhka-vozduh-niz);
    /* ОДНА ЧЕРТА ПОСЛЕ ОБЛОЖКИ — и она принадлежит ОБЛОЖКЕ, а не первой
       секции. Пьедестал в режиме поиска скрывается (js/players.js:569), и
       черта, повешенная на него, уезжала бы вместе с ним; нижняя граница
       обложки есть всегда. Обзорная и категория рисуют одну и ту же обложку
       в #playersHero, поэтому одно объявление закрывает обе страницы. */
    border-bottom: var(--bw-hair) solid var(--border-subtle);
    text-align: center;
    overflow: hidden;
    min-height: var(--oblozhka-pol);
    display: flex;
    align-items: center;
    justify-content: center;
}

.pl-hero-bg {
    position: absolute;
    inset: 0;
    background: url('https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=1600&q=80') center/cover no-repeat;
    z-index: 0;
}

.pl-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, var(--modal-bg-heavy) 0%, var(--bg-primary) 100%);
    z-index: 1;
}

.pl-hero-content {
    position: relative;
    z-index: 2;
    max-width: 700px;
    margin: 0 auto;
}

/* ТА ЖЕ КРУТИЛКА, ЧТО У ОБЛОЖКИ РАЗДЕЛА ТУРНИРОВ: 40 → 32 → 21.
   Было clamp(1.9rem, 4.4vw, 3.1rem) — замер пяти видов дал 49.6 · 45.1 ·
   37.1 · 33.8 · 26, и ни одно число, кроме последнего, не стоит на шкале. */
/* ОДНА ОБЛОЖКА НА ДВА ЭКРАНА РЕЙТИНГА. Обзорная и страница категории —
   один и тот же разворот: название раздела и сезон. До 06.10 у категории
   был СВОЙ заголовок на `clamp(2rem, 5vw, 3.2rem)` — замер дал 51 · 42 ·
   38 · 26, ни одно число не ступень шкалы и ни одно не совпадало с
   крутилкой обложки. Теперь оба имени ведут на одно определение, и правило
   «заголовок обложки — крутилка раздела, а не clamp» держит их обоих. */
.pl-hero-title,
.pl-cat-title {
    font-size: var(--fs-hero);
    font-weight: var(--fw-extrabold);
    line-height: var(--lh-tight);
    color: var(--text-primary);
    margin-bottom: 18px;
}

.pl-hero-subtitle,
.pl-cat-subtitle {
    font-size: var(--fs-hero-sub);
    font-weight: var(--fw-semibold);
    color: var(--text-secondary);
    max-width: 720px;
    margin: 0 auto var(--space-lg);
    line-height: var(--lh-normal);
    letter-spacing: 0;
}

/* ПОИСКОВОЙ СТРОКИ НА ОБЗОРНОЙ РЕЙТИНГА НЕТ — И CSS ПОД НЕЁ УБРАН.
   06.10 замер показал: `.pl-search-wrap`, `.pl-search-icon`,
   `.pl-search-input` и `.pl-cat-search-wrap` не встречаются ни в одном html
   и ни в одном js продукта — проверено поиском по всему дереву, а не на
   глаз. Пятьдесят строк оформления ждали разметку, которой нет.
   Слово Кости 06.10: «на обзорной давай уберём, там всё равно обрезанная
   версия стоит и всех не отображает — для чего там поиск тогда».
   Поиск по имени живёт на отдельной странице `partners.html`, в меню он
   зовётся «Поиск игрока». Модалка поиска для гостя (`.pl-search-modal*`)
   ЖИВАЯ — её строит `js/players.js:1245`, и она остаётся. */

/* Search auth modal (guest) */
.pl-search-modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: var(--modal-bg-heavy);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.pl-search-modal-overlay.visible {
    opacity: 1;
}

.pl-search-modal {
    background: var(--neutral-800);
    border: var(--bw-hair) solid var(--border-subtle);
    border-radius: var(--radius-xl);
    padding: 40px 32px;
    max-width: 400px;
    width: 100%;
    text-align: center;
    position: relative;
    transform: translateY(20px);
    transition: transform 0.3s ease;
}

.pl-search-modal-overlay.visible .pl-search-modal {
    transform: translateY(0);
}

.pl-search-modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: var(--fs-xl);
    cursor: pointer;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: color var(--transition-fast), background var(--transition-fast);
}

.pl-search-modal-close:hover {
    color: var(--text-primary);
    background: var(--surface-glass);
}

.pl-search-modal-icon {
    margin-bottom: 16px;
}

.pl-search-modal h3 {
    font-size: var(--fs-md);
    font-weight: 700;
    margin-bottom: 8px;
}

.pl-search-modal p {
    color: var(--text-secondary);
    font-size: var(--fs-sm);
    margin-bottom: 24px;
    line-height: 1.5;
}

.pl-search-modal-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--accent);
    color: var(--neutral-black);
    font-size: var(--fs-base);
    font-weight: 700;
    padding: 12px 32px;
    border: none;
    border-radius: var(--radius-full);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.pl-search-modal-btn:hover {
    background: var(--accent-hover);
    transform: translateY(-2px);
}

/* === PODIUM (Pedestal) === */


/* Base card */


/* Card inner (above pedestal) */


/* === 1st Place (center) — tallest === */


/* === 2nd Place (left) === */


/* === 3rd Place (right) === */


/* Pedestal base line */


/* Medal */


/* Photo */


/* 1st — large photo */


/* Инициалы вместо фото: диаметр берётся из правил выше, кегль — отсюда.
   Одно объявление размера на фото и на заглушку, поэтому здесь только кегль. */


/* 2nd */


/* 3rd */


/* Name */


/* Points */


/* Badges */


/* Podium container needs relative for base line */


/* === FILTERS === */
.pl-filters-section {
    padding: 12px var(--pad-x) var(--space-md);
    position: sticky;
    top: var(--header-h);
    z-index: 30;
    background: var(--bg-primary);
}

.pl-gender-tabs {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: var(--space-md);
}

/* ЦЕЛЬ НАЖАТИЯ — НАСТОЯЩЕЙ ВЫСОТОЙ, КЕГЛЬ — СО ШКАЛЫ. Замер 06.10: на
   768 и 390 чип отдавал 37 — такой ступени на шкале кнопок нет вовсе
   (28 · 36 · 44 · 52), а кегль 16 расходился с чипами турниров. Вид взят
   у компонента Filter chip 49:77, как и на доске рейтинга. */
/* ВЫБОР ПОЛА — ОДИН ЭЛЕМЕНТ НА ДВА ЭКРАНА РЕЙТИНГА. На обзорной он был
   `.pl-gender-tab` (14 · 500), на странице категории — `.trn-chip` из
   общего листа (12 · 600). Замер 06.10: одна и та же кнопка выглядела
   по-разному в зависимости от того, с какого экрана на неё смотрят. Теперь
   оба имени ведут на одно определение; высота у обоих была 44 и осталась. */
.pl-gender-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--btn-h-md);
    line-height: var(--lh-none);
    padding: 8px 24px;
    background: transparent;
    border: var(--bw-thick) solid var(--border-subtle);
    border-radius: var(--radius-full);
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    cursor: pointer;
    transition: all 0.2s;
}

.pl-gender-tab:hover {
    border-color: var(--border-light);
    color: var(--text-primary);
}

.pl-gender-tab.active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--neutral-black);
}

/* Три колонки поровну: центральная всегда ровно по середине страницы —
   там же, где пьедестал и вкладки полов. Раньше края стояли на absolute,
   и категории уезжали от центра тем сильнее, чем шире поиск */
.pl-category-row {
    position: relative;
    display: grid;
    /* minmax(0, 1fr), а не голый 1fr: иначе колонка не может стать уже
       своего содержимого, поле поиска раздвигает левую сторону и центр
       уезжает вправо от вершины пьедестала */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: 24px;
}

/* Поиск слева, «Показать всех» справа, категории по центру. Поле того же
   размера, что в полосе фильтров на страницах категорий: одна мерка на
   весь сайт */
.pl-category-row .trn-search-wrap {
    position: relative;
    justify-self: start;
    width: 100%;
    max-width: 320px;
}

/* Во время поиска ищем по всем игрокам сразу, поэтому вкладки полов и
   категории уходят — иначе они обещают фильтр, которого нет */
.pl-filters-searching .pl-gender-tabs,
.pl-filters-searching .pl-category-pills,
.pl-view-all::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: var(--btn-h-md);
}

.pl-filters-searching .pl-view-all {
    display: none;
}

/* В поиске центральная и правая колонки пусты — поле занимает всю строку
   и встаёт по центру */
.pl-filters-searching .pl-category-row {
    grid-template-columns: 1fr;
}

.pl-filters-searching .pl-category-row .trn-search-wrap {
    justify-self: center;
}

/* ПИЛЮЛИ СТОЯТ В СВОЕЙ КОЛОНКЕ, А НЕ В ПЕРВОЙ СВОБОДНОЙ. Строка — три
   колонки: слева было поле поиска, по центру пилюли, справа «Показать
   всех». Поиск снят по слову Кости — и пилюли с ссылкой уехали влево,
   заняв освободившиеся места. Колонка называется явно: состав строки
   может меняться, а место каждого элемента — нет. */
.pl-category-pills {
    grid-column: 2;
    display: flex;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ССЫЛКА БЫЛА ВЫСОТОЙ 21 — ЦЕЛЬ НАЖАТИЯ ВТРОЕ МЕНЬШЕ НОРМЫ. Высоту строки
   не трогаем: ссылка стоит в ряду с пилюлями и выросла бы над ними. Слой
   цели 44, как у «Назад» в полосе фильтров. */
.pl-view-all {
    position: relative;
    grid-column: 3;
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    white-space: nowrap;
    transition: opacity 0.2s;
}

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

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

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

/* ВЫСОТУ ДАЁТ СТУПЕНЬ, А НЕ ПОЛЯ. Замер 06.10: пилюля 34 на десктопе и 32
   на узких — таких ступеней на шкале кнопок нет (28 · 36 · 44 · 52), и обе
   меньше цели нажатия. Ступень 36 плюс прозрачный слой цели 44: КНОПКА 36
   ЗАКОННА, ЕСЛИ У НЕЁ ЕСТЬ СЛОЙ ЦЕЛИ 44. */
.pl-category-pill {
    position: relative;
    display: inline-flex;
    align-items: center;
    min-height: var(--btn-h-sm);
    padding: 0 20px;
    background: transparent;
    border: var(--bw-hair) solid var(--border-subtle);
    border-radius: var(--radius-full);
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    line-height: var(--lh-none);
    cursor: pointer;
    transition: all 0.2s;
}

/* Слой цели нажатия: сама пилюля 36, попадать в неё можно как в 44 */
.pl-category-pill::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: var(--btn-h-md);
}

.pl-category-pill:hover {
    border-color: var(--border-light);
    color: var(--text-primary);
}

.pl-category-pill.active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--neutral-black);
    font-weight: 600;
}

/* === TABLE === */
.pl-table-section {
    padding: 0 var(--pad-x) var(--section-y-sm);
}

/* ТАБЛИЦА ЖИВЁТ В КОЛОНКЕ, А НЕ ВО ВСЮ ШИРИНУ ОКНА. Замер 06.10: ряд
   1398 при окне 1512 — глаз теряет строку между именем слева и очками
   справа. ATP, WTA и ITF держат рейтинг в узкой колонке; 1100 — та же
   мера, что у содержимого страницы турнира. */
.pl-table {
    width: 100%;
    max-width: 1100px;
    margin-inline: auto;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: var(--bw-hair) solid var(--border-subtle);
    background: var(--bg-card);
}

/* КОЛОНКИ РЕЙТИНГА ОБЪЯВЛЕНЫ ОДИН РАЗ — И ОДНИ НА ОБА ЭКРАНА.
   Слово Кости 06.10: «таблицу надо привести к стандарту как на обзорной».
   Было две сетки: девять колонок на обзорной и семь на разряде, шестнадцать
   чисел ширин на одно понятие — и ширины 1100 против 860.
   «Онлайн» снята по слову Кости («не нужна на рейтингах»), осталось восемь:
   место · игрок · страна · NTRP · очки · В/П · форма · Δ.
   Колонка действий есть только у вошедшего и только на обзорной — она
   ДОПИСЫВАЕТСЯ к набору, а не переобъявляет его. */
.pl-table {
    --колонки-рейтинга: 50px 1fr 60px 78px 80px 70px 100px 60px;
}

.pl-table-actions .pl-row {
    grid-template-columns: var(--колонки-рейтинга) 90px;
}

.pl-row {
    display: grid;
    grid-template-columns: var(--колонки-рейтинга);
    align-items: center;
    /* Ряд 52 — ступень шкалы кнопок. Было 65: высоту давали поля 12,
       а не содержимое.

       ПОПРАВКА 13.10: ряд выходил 53, а не 52, и ПОСЛЕДНИЙ был 52 — то есть
       ряды в одной таблице не равны между собой. Померено: содержимое 40
       плюс поля 12 — это ровно 52, а один лишний пиксель давала РАЗДЕЛЬНАЯ
       ЛИНИЯ: `border-bottom` занимает место в потоке, а у последнего ряда
       его нет. Линия переведена во внутреннюю тень — она рисуется, но
       высоты не занимает. Правило дома: ВЫСОТУ РЯДА ДЕРЖИТ СВОЙСТВО, А НЕ
       СУММА ПОЛЕЙ (куплено на админке 08.10). */
    min-height: var(--btn-h-lg);
    padding: 6px 16px;
    gap: 8px;
    box-shadow: inset 0 -1px 0 var(--border-subtle);
    transition: all 0.2s;
    opacity: 0;
    transform: translateY(10px);
}

.pl-row.pl-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Линия теперь тень, и снимается она тоже тенью. */
.pl-row:last-child {
    box-shadow: none;
}

.pl-row:not(.pl-row-header):hover {
    background: var(--alpha-lime-06);
}

.pl-row-header {
    background: var(--bg-elevated);
    font-size: var(--fs-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    opacity: 1;
    transform: none;
}

/* Columns */
.pl-col-rank {
    font-weight: 700;
    color: var(--text-secondary);
    text-align: center;
    font-size: var(--fs-base);
}

.pl-rank-top {
    color: var(--accent);
    font-size: var(--fs-md);
}

.pl-col-player {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.pl-player-photo {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.pl-player-info {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-width: 0;
}

.pl-player-name-row {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.pl-player-name {
    position: relative;
    display: inline-block;
    padding-block: 10px;
    margin-block: -10px;
    font-weight: 600;
    color: var(--text-primary);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.2s;
}

/* ЦЕЛЬ НАЖАТИЯ У ИМЕНИ ИГРОКА. Замер 06.10 на пяти видах: ссылка имени —
   24 высотой, на телефоне 21, при норме 44. Это САМОЕ НАЖИМАЕМОЕ на
   странице: десять таких на обзорной, двенадцать на разряде, и ни у одной
   слоя не было. Коробку не трогаем — она держит ряд 53 и лесенку текста;
   КНОПКА 36 ЗАКОННА, ЕСЛИ У НЕЁ ЕСТЬ ПРОЗРАЧНЫЙ СЛОЙ ЦЕЛИ 44 (принято
   Костей 04.10), и ссылка живёт по тому же правилу. Слой 44 помещается в
   ряд 53 и в карточку телефона 46.
   СЛОЙ ЗДЕСЬ НЕ ГОДИТСЯ, И ЭТО ПОМЕРЕНО, А НЕ УГАДАНО. Первый заход
   поставил прозрачный `::after` высотой 44 — и он НЕ РАБОТАЛ: у ссылки
   стоит `overflow: hidden` ради многоточия в длинном имени, и она срезает
   собственный псевдоэлемент. `elementFromPoint` в восьми пикселях над
   ссылкой возвращал ячейку, а не ссылку. ЭЛЕМЕНТ, ВИСЯЩИЙ СНАРУЖИ СВОЕЙ
   КОРОБКИ, БУДЕТ СРЕЗАН — в том числе собственной коробкой.
   Поэтому высоту даёт САМА ссылка: поле сверху и снизу по 10 растит
   попадание до 44, отрицательное внешнее поле на столько же возвращает
   раскладку на место. Ряд, лесенка текста и многоточие не трогаются. */
.pl-player-name:hover {
    color: var(--accent);
}

.pl-player-category {
    display: inline-block;
    font-size: var(--fs-2xs);
    color: var(--accent);
    font-weight: 600;
    background: var(--alpha-lime-06);
    padding: 2px 8px;
    border-radius: var(--radius-full);
    width: fit-content;
    line-height: 1.3;
}

.pl-player-badges {
    display: flex;
    gap: 3px;
    flex-shrink: 0;
}

.pl-col-country {
    text-align: center;
}

.pl-row:not(.pl-row-header) .pl-col-country {
    font-size: var(--fs-md);
}

/* ЗНАЧОК NTRP ПЕРЕНОСИЛСЯ, И ОТ ЭТОГО РЯД СТАНОВИЛСЯ ВЫШЕ. Померено 13.10 на
   768 и 844: у парного значения «4.5 / 4.0» ячейка выходила 48 вместо 24, и
   ряд — 68 при 56 у соседей. Правило не новое: `Badge 27:53` говорит высоту
   24 и ОДНУ строку, и ровно эту беду ловили в админке 08.10 («каждая
   четвёртая строка была 56»). Сюда оно не доехало. */
.pl-col-ntrp {
    text-align: center;
    white-space: nowrap;
}

.pl-ntrp-value {
    color: #00BFFF;
    font-weight: 700;
    font-size: var(--fs-sm);
}

.pl-ntrp-na {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

/* ОЧКИ НЕ РАСТУТ ОТ ТОГО, ЧТО ЭКРАН УЖЕ. Замер 06.10: на широких видах
   колонка очков шла 12, на телефоне — 14, то есть на маленьком экране
   главное число было КРУПНЕЕ, чем на большом. Оба числа со шкалы, но
   порядок перевёрнут. Кегль объявлен один раз здесь: 14 на всех видах —
   мельче имени (16) и не мельче прочих колонок. */
.pl-col-points {
    font-size: var(--fs-sm);
    font-weight: var(--fw-extrabold);
    color: var(--accent);
    text-align: center;
}

.pl-col-record {
    text-align: center;
    color: var(--text-secondary);
    font-size: var(--fs-sm);
}

.pl-col-form {
    display: flex;
    gap: 4px;
    justify-content: center;
}

.pl-col-change {
    text-align: center;
}

.pl-col-actions {
    display: flex;
    gap: 6px;
    justify-content: center;
}

/* Online dot */
/* `.pl-online-dot` и `.pl-online-pulse` СНЯТЫ 29.10: точку рисовало
   условие `p.online`, а это поле всегда было `false` — онлайн с рейтинга
   убран твоим словом 06.10. Понятие живо и считается одним правилом
   `KSLT_LICO.вСети(last_seen)`; вернёшь онлайн — вид завести заново. */

/* Badge */
.pl-badge {
    font-size: var(--fs-sm);
    cursor: help;
    line-height: 1;
}

/* Form dots */
.pl-form-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

.pl-form-win {
    background: var(--success);
}

.pl-form-loss {
    background: var(--danger);
}

/* Change */
.pl-change-up {
    color: var(--success);
    font-weight: 600;
    font-size: var(--fs-sm);
}

.pl-change-down {
    color: var(--danger);
    font-weight: 600;
    font-size: var(--fs-sm);
}

.pl-change-neutral {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

/* Action buttons.
   `.pl-btn-message` СНЯТА 29.10: кнопку письма рисовало условие
   `p.online`, а поле всегда было `false`. Кнопка вызова осталась. */
.pl-btn-challenge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    text-decoration: none;
    font-size: var(--fs-sm);
    transition: all 0.2s;
}

.pl-btn-challenge {
    background: var(--alpha-lime-12);
    border: var(--bw-hair) solid var(--alpha-lime-20);
}

.pl-btn-challenge:hover {
    background: var(--accent);
    border-color: var(--accent);
}

/* No results */
.pl-no-results {
    padding: var(--space-xl);
    text-align: center;
    color: var(--text-muted);
    font-size: var(--fs-md);
}

/* === GUEST RESTRICTION — Progressive Blur + CTA === */

/* Blurred rows — progressive blur */
.pl-row-blur {
    pointer-events: none;
    user-select: none;
}
.pl-row-blur-1 { filter: blur(2px); opacity: 0.7; }
.pl-row-blur-2 { filter: blur(4px); opacity: 0.5; }
.pl-row-blur-3 { filter: blur(6px); opacity: 0.35; }
.pl-row-blur-4 { filter: blur(8px); opacity: 0.2; }

/* CTA overlay — floats over blurred rows */
.pl-guest-overlay {
    position: relative;
    margin-top: -200px;
    padding-top: 40px;
    padding-bottom: 8px;
    background: linear-gradient(to bottom,
        transparent 0%,
        rgba(10, 10, 10, 0.6) 25%,
        rgba(10, 10, 10, 0.92) 50%,
        var(--bg-dark) 70%
    );
    z-index: 2;
}

/* Animated gradient border card */
/* ПОДКЛЮЧЕНА К ЭТАЛОНУ 24.09 — вторая из трёх копий коробки-гейта.
   Эталон .badges-cta-box в css/style.css, сторож tools/check-korobka.js.
   От эталона копия вправе отличаться только полями и шириной — и поля
   теперь тоже его: было 44 / 40 / 40, ни одно не ступень шкалы
   8 · 12 · 16 · 24 · 32 · 40. Ширина 460 остаётся своей: это накладка
   поверх таблицы рейтинга, а не коробка под перебивкой. */
.pl-guest-cta {
    position: relative;
    text-align: center;
    padding: var(--space-6) var(--space-8);   /* 24 / 32 — как у эталона */
    margin: 0 auto;
    max-width: 460px;
    background: rgba(18, 18, 18, 0.85);
    border-radius: 24px;
    overflow: hidden;
    isolation: isolate;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
}

/* Rotating gradient border */
.pl-guest-cta::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 24px;
    padding: 1px;
    background: conic-gradient(
        from var(--guest-angle, 0deg),
        transparent 0%,
        var(--accent) 10%,
        transparent 20%,
        transparent 50%,
        var(--accent-glow) 60%,
        transparent 70%
    );
    -webkit-mask: linear-gradient(var(--neutral-white) 0 0) content-box, linear-gradient(var(--neutral-white) 0 0);
    mask: linear-gradient(var(--neutral-white) 0 0) content-box, linear-gradient(var(--neutral-white) 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    animation: pl-border-spin 4s linear infinite;
    z-index: -1;
}

@property --guest-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

@keyframes pl-border-spin {
    to { --guest-angle: 360deg; }
}

/* Ambient glow behind card */
.pl-guest-cta::after {
    content: '';
    position: absolute;
    top: -40%;
    left: 50%;
    transform: translateX(-50%);
    width: 200px;
    height: 200px;
    background: radial-gradient(circle, var(--alpha-lime-12) 0%, transparent 70%);
    border-radius: 50%;
    z-index: -1;
    animation: pl-glow-pulse 3s ease-in-out infinite;
}

@keyframes pl-glow-pulse {
    0%, 100% { opacity: 0.5; transform: translateX(-50%) scale(1); }
    50% { opacity: 1; transform: translateX(-50%) scale(1.2); }
}

.pl-guest-icon {
    width: 52px;
    height: 52px;
    margin: 0 auto 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--alpha-lime-06);
    border: var(--bw-hair) solid var(--alpha-lime-12);
    color: var(--accent);
}

.pl-guest-title {
    font-size: var(--fs-lg);
    font-weight: 800;
    color: var(--neutral-white);
    margin-bottom: var(--space-2);       /* 8; было 10 — не ступень */
    letter-spacing: -0.02em;
}

.pl-guest-text {
    font-size: var(--fs-sm);
    color: var(--alpha-white-50);
    max-width: 340px;
    margin: 0 auto var(--space-6);       /* 24; было 28 — не ступень */
    line-height: var(--lh-normal);       /* 1.5; было 1.6 и 1.3 на телефоне */
}

/* КНОПКА ЭТАЛОНА. Было: высота полями 14 / 40, кегль 16, радиус 14, и
   ещё две переопределяющие ступени ниже по файлу — 13/20 на 1024 и 10/16
   на 768. Три высоты на пяти видах, ни одна не ступень Button 17:82
   (28 · 36 · 44 · 52), радиус 14 не ступень (8 · 12 · 16 · 24).
   Теперь запись .badges-cta-btn: высота свойством, ступень md 44. */
.pl-guest-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);                 /* 8 */
    height: var(--btn-h-md);             /* 44 */
    padding: 0 var(--space-8);           /* 32 */
    background: var(--accent);
    color: var(--neutral-black);
    font-weight: 800;
    font-size: var(--fs-sm);             /* 14; было 16 */
    border-radius: 12px;
    text-decoration: none;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 0 24px var(--alpha-lime-20), 0 0 60px var(--alpha-lime-06);
    overflow: hidden;
}

.pl-guest-btn::after {
    content: '';
    position: absolute;
    top: -50%;
    left: -60%;
    width: 40%;
    height: 200%;
    background: linear-gradient(90deg, transparent, var(--alpha-white-12), transparent);
    transform: skewX(-20deg);
    animation: pl-shimmer 3s ease-in-out infinite;
}

@keyframes pl-shimmer {
    0%, 100% { left: -60%; }
    50% { left: 120%; }
}

.pl-guest-btn:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 0 32px var(--alpha-lime-30), 0 8px 40px var(--alpha-lime-12);
}

/* ЧЕРТЫ МЕЖДУ СЕКЦИЯМИ РЕЙТИНГА СНЯТЫ.
   Слово Кости 06.10: «убери полосу эту сверху», «эти полосы разделения не в
   теме». Замер на 1280 показал их четыре подряд в одной ладони: черта под
   подиумом (снята в podium.css), верхняя и нижняя границы липкой полосы и
   верхняя граница таблицы — причём две последние стояли на одной координате.

   ИСТОЧНИК — ОБЩЕЕ ПРАВИЛО, А НЕ СЕКЦИЯ: `section:not(.hero)` в style.css
   вешает границу на КАЖДУЮ секцию сайта, и вес у него (0,1,1) — выше, чем у
   простого класса. Адресую секции рейтинга их собственными номерами на
   странице: вес (1,0,0), спорить не с чем, и правило не притворяется стилем
   пьедестала — пьедестал целиком живёт в podium.css.
   Остальные секции сайта свои черты сохраняют. */
#playersPodium,
#playersFilters,
#playersTable,
#playersPagination {
    border-top: 0;
}

/* === ПОЛОСА СТРАНИЦ ===
   КОМПОНЕНТ ОБЩИЙ, И ЖИВЁТ ОН В style.css. Переехал 07.10, когда полосу
   страниц попросили корты: с 06.10 определение было одно, но лежало в
   файле одного раздела, и второй раздел не мог его взять, не подключив
   чужой лист целиком. Там же, в style.css, живут и другие общие части
   полосы фильтров — `trn-back`, `trn-search-wrap`, `trn-chips`.
   Имена классов оставлены прежними: по ним стоят правила заморозки и
   проба, а префикс — это имя компонента, а не его прописка. */

/* === SPONSORS === */

/* === SCROLL ANIMATIONS === */
.pl-animate {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.5s ease, transform 0.5s ease;
}

/* ДВИЖЕНИЕ СПРАШИВАЕТ РАЗРЕШЕНИЯ. У страницы рейтинга своё движение:
   въезд рядов таблицы с задержкой до 300 мс, пульс онлайна, вращение рамки
   и мерцание заглушки. Ни одно из них не спрашивало. Гасим ДВИЖЕНИЕ, а не
   элемент: ряд остаётся на месте и видимым, кольца и заглушка — тоже. */
@media (prefers-reduced-motion: reduce) {

    .pl-animate {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .pl-guest-cta::before{
        animation: none;
    }

    .pl-row,
    .pl-page-btn,
    .pl-category-pill,
    .pl-gender-tab,
    .pl-player-name,
    .pl-view-all {
        transition: none;
    }
}

.pl-animate.pl-visible {
    opacity: 1;
    transform: translateY(0);
}

/* === CATEGORY PAGE === */

/* Hero content — left-aligned back link */
.pl-cat-hero-content {
    position: relative;
    z-index: 2;
    max-width: 700px;
    margin: 0 auto;
    text-align: center;
}

/* ПЛАШЕК С ЧИСЛАМИ НА ОБЛОЖКЕ КАТЕГОРИИ БОЛЬШЕ НЕТ — те же три, что были
   на обзорной: игроки, турниры и онлайн. Сняты 06.10 по уже принятому
   решению Кости, вместе с запросом к базе, который считал турниры только
   ради одной из них. Оформление снято здесь, разметка — в
   `js/players.js:renderCatHero`: КОД, КОТОРОМУ НЕЧЕГО ОФОРМЛЯТЬ, НЕ
   ОСТАЁТСЯ ЖДАТЬ. */

/* ПОЛОСА РАЗРЯДА — ТОТ ЖЕ КОМПОНЕНТ, ЧТО СТРОКА ФИЛЬТРОВ НА ОБЗОРНОЙ.
   Слово Кости 06.10: «они должны быть одинаковыми по ширине и содержанию —
   приведи как с обзорной стр рейтинга», «обзорная уже есть на всех видах,
   не придумывай — отталкивайся от неё».
   Было два компонента на одно понятие: здесь `.trn-filters` в один ряд с
   собственной сеткой, своим шагом 24 и своими переносами на узких видах, а
   на обзорной — `.pl-gender-tabs` + `.pl-category-row`. Отсюда и расхождение
   по ширине, и разный состав ряда, и разные переносы.
   Своих правил раскладки у полосы разряда больше НЕТ: разметка носит те же
   классы, и сетку, шаг, центровку и поведение на 992 и 640 держит один
   набор правил выше. Здесь остаётся только то, чего на обзорной нет
   физически: место трёх элементов в ряду и черта при прокрутке. */

/* Места в ряду названы явно — тем же способом, что на обзорной: состав
   строки может меняться, а место каждого элемента — нет.
   Слева «назад» — как на всех восьми полосах сайта; по центру поиск, ровно
   под вершиной пьедестала, ширина 320 — та же мерка, что в `.pl-category-row
   .trn-search-wrap`; справа название разряда — колонка, в которой на
   обзорной стоит «Показать всех». */
.pl-cat-back {
    grid-column: 1;
    justify-self: start;
}

.pl-cat-mode .pl-category-row .trn-search-wrap {
    grid-column: 2;
    justify-self: center;
    /* ШИРИНА ПОИСКА — 320, И ЭТО НЕ МОЁ ЧИСЛО. Я поставил сюда 480 и был
       поправлен: «полоса поиска у нас есть стандарт в фигме — почему ты
       придумываешь что-то новое». Прочитан компонент `Search field 50:67`:
       все три состояния 320 × 44, радиус 8, поля 0 · 16, кегль 16. Средняя
       колонка `auto` отдавала полю 234 — вот это и было мимо; 320 ставится
       явно, потому что `width: 100%` в колонке `auto` считает себя от
       содержимого. */
    width: 320px;
    max-width: 100%;
}

.trn-cat-name {
    grid-column: 3;
    justify-self: end;
    /* Выравнивание — свойство РАСКЛАДКИ, а не межстрочного. Здесь стоял
       line-height 44, подогнанный под высоту чипа, и выбивал уровень с
       лестницы: прибор намерил 2.75 при ступенях 1 · 1.1 · 1.3 · 1.5 · 1.65.
       Высоту даёт сама строка.
       ЦЕЛИ НАЖАТИЯ У НАЗВАНИЯ НЕТ — ОНО НЕ НАЖИМАЕТСЯ. Здесь стояло
       min-height 44, чтобы встать по высоте чипа, когда чип был в том же
       ряду. Чипы уехали в свой ряд, а 44 осталось и тянуло ряд: на узких
       видах полоса считала 44 там, где у строки 21. Померено: 204 → 181 на
       телефоне, 205 → 182 на телефоне боком. На широких высоту ряда задаёт
       поиск (44), и снятие ничего не меняет. */
    display: inline-flex;
    align-items: center;
    line-height: var(--lh-none);
}

/* НА УЗКИХ ВИДАХ «НАЗАД» И НАЗВАНИЕ ЕДУТ ОДНИМ РЯДОМ — ЭТО ПОСЧИТАНО, А НЕ
   ПРИДУМАНО, И ЭТО ЕДИНСТВЕННОЕ, ЧЕМ ПОЛОСА РАЗРЯДА ОТЛИЧАЕТСЯ ОТ ОБЗОРНОЙ.
   Обзорная на узком складывается в одну колонку: пилюли, затем «Показать
   всех» — два уровня. У разряда их три: «назад» 21, поиск 38, название 44.
   Замер 06.10 ровно по обзорной раскладке дал полосу 231 на телефоне 375 и
   232 на телефоне боком 844×390 — пятьдесят девять процентов высоты экрана
   под фильтром. Отвергнутая утром раскладка стоила 209; эта стоила бы
   больше неё.
   «Назад» 21 и название 44 — два коротких уровня, они умещаются рядом на
   любом из узких видов, и один ряд уходит: 231 → 198 (ПОСЧИТАНО, померено
   ниже). Поиск берёт ряд целиком — на узком он главный способ найти игрока.
   Ширина ряда, отбивки, шаг, чипы и ступени остаются ровно теми же, что на
   обзорной: расходится только порядок трёх уровней внутри ряда. */
@media (max-width: 992px) {

    .pl-cat-mode .pl-category-row {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
    }

    .pl-cat-back {
        grid-column: 1;
        grid-row: 1;
        justify-self: start;
    }

    .trn-cat-name {
        grid-column: 2;
        grid-row: 1;
        justify-self: end;
    }

    /* Поиск во всю ширину ряда — как пилюли на обзорной, где
       `justify-items: start` и ряд отдаёт им всю колонку */
    .pl-cat-mode .pl-category-row .trn-search-wrap {
        grid-column: 1 / -1;
        grid-row: 2;
        justify-self: stretch;
        /* Ширину задаёт ряд, а не число: 480 с широкого вида здесь снимается */
        width: auto;
        max-width: none;
    }
}

/* Черта появляется только когда полоса прилипла: до этого под ней стоит
   своё содержимое, и делить нечего */
.pl-filters-section.pl-cat-mode.stuck {
    border-bottom: var(--bw-hair) solid var(--border-subtle);
}

/* МЁРТВОЕ СНЯТО: ЛИПКАЯ ПОЛОСА ВТОРОЙ КОНСТРУКЦИИ.
   Здесь жили `.pl-cat-sticky-bar`, `.pl-cat-sticky-name`,
   `.pl-cat-sticky-search` и `.pl-cat-back-link` — 115 строк на полосу,
   которая всплывала при прокрутке. Проверено, а не на вид: ни одного из
   четырёх имён нет ни в js/, ни в pages/, ни в index.html (grep 06.10).
   Полосу разряда рисует renderCategoryPage теми же классами, что обзорную.
   Правило «назад не лаймовый» (109:370) не теряется: оно живёт на
   `.trn-back` в общем листе, где стоят все восемь «назад» сайта. */

/* ШИРИНУ ДЕРЖИТ САМА ТАБЛИЦА — 1100, как у ATP, WTA и ITF. Здесь стояло
   860: вторая ширина на то же понятие. */
.pl-cat-table-wrap {
    margin: 0 auto;
}

/* Category table body (header row inside same container) */
.pl-cat-table-body {
    border-radius: var(--radius-lg);
}

/* Guest profile link in category table */
.pl-cat-row .pl-player-name[data-guest-profile] {
    cursor: pointer;
}

/* === RESPONSIVE === */

/* Tablet */
/* На узком экране строка раскладывается сверху вниз: поиск, категории,
   ссылка. Абсолютные края тут наложились бы друг на друга */
@media (max-width: 992px) {

    .pl-category-row {
        grid-template-columns: 1fr;
        justify-items: center;
        gap: 12px;
    }

    .pl-category-row .trn-search-wrap {
        justify-self: center;
        width: 100%;
        max-width: 320px;
    }
}

/* Телефон: содержимое строки категорий — влево, как везде на сайте */
@media (max-width: 992px) {

    .pl-category-row {
        justify-items: start;
    }

    /* КОЛОНКА НАЗНАЧАЕТСЯ ТАМ, ГДЕ КОЛОНОК ТРИ. Здесь строка в одну
       колонку, и номера 2 и 3 из базового правила заводили пустые
       колонки справа: пилюли уезжали от центра на 59 пикселей. */
    .pl-category-pills,
    .pl-view-all {
        grid-column: auto;
    }

    /* Ссылка стояла у правого края, оторванная от кнопок категорий */
    .pl-view-all {
        justify-self: start;
    }

    /* Поиск был 320 по центру, а кнопки — во всю ширину от левого края:
       левые края не совпадали */
    .pl-category-row .trn-search-wrap {
        justify-self: stretch;
        width: 100%;
        max-width: 480px;
    }
}

@media (max-width: 992px) {

    /* ИМЯ ИГРОКА — ГЛАВНАЯ КОЛОНКА, А ПОЛУЧАЛО 89 ИЗ 734: остальные держали
       свою десктопную ширину, и воздух собирался в середине. Ужаты до
       содержимого — «Стр.» флаг, «Δ» прочерк, им хватает 40. */
    .pl-table {
        --колонки-рейтинга: 40px 1fr 40px 64px 64px 48px 72px 40px;
    }

    .pl-row {
        padding: 10px 12px;
        gap: 6px;
    }

    .pl-player-photo {
        width: 36px;
        height: 36px;
    }
}

/* Mobile landscape */
    /* Раскладка телефона: ряд становится карточкой. Граница 640, а не 768 —
       на планшете 768 и на телефоне боком 844 место под настоящую таблицу
       есть, и карточки там его тратят зря. */
@media (max-width: 640px) {


    /* ОДНО ОПРЕДЕЛЕНИЕ НА ОДНО ПОНЯТИЕ. Эти три секции получают боковой
       отступ `var(--pad-x)` в своих базовых правилах (`:265`, `:413`,
       `:894`) — тем же самым значением. Повтор здесь ничего не менял и
       заводил ВТОРОЕ определение отступа у раздела пагинации: беда
       родилась бы ровно на шве, как только одно из двух мест поправят.
       Снято 06.10 после замера: отступы на 768 те же, что были. */

    

    

    

    
    

    
    

    
    
    

    
    
    

    
    

    .pl-gender-tab {
        /* Высоту держит min-height у самого чипа — одно место на все виды */
        padding: 8px 20px;
    }

    .pl-category-pill {
        padding: 0 14px;
        font-size: var(--fs-xs);
    }

    /* Table → cards on mobile */
    .pl-table {
        border: none;
        background: transparent;
    }

    .pl-row-header {
        display: none;
    }

    /* Строка занимала 66 пикселей плюс 16 отбивки — на экран влезало пять
       игроков, хотя данных в строке всего четыре: номер, имя, очки, стрелка */
    .pl-row {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        padding: 10px 14px;
        margin-bottom: 8px;
        border: var(--bw-hair) solid var(--border-subtle);
        border-radius: var(--radius-lg);
        background: var(--bg-card);
        gap: 8px;
    }

    .pl-row:last-child {
        box-shadow: inset 0 -1px 0 var(--border-subtle);
    }

    .pl-col-rank {
        font-size: var(--fs-base);
        width: 26px;
    }

    .pl-col-player {
        flex: 1;
        min-width: 0;
    }

    .pl-col-country {
        font-size: var(--fs-base);
    }

    .pl-col-ntrp {
        font-size: var(--fs-xs);
    }

    .pl-col-points {
        /* кегль держит базовое правило — одно место на все виды */
        margin-left: auto;
    }

    /* Имя шло 16-м кеглем и обрезалось на «Атхам И…» */
    .pl-player-name-row {
        font-size: var(--fs-sm);
    }

    .pl-player-photo {
        width: 28px;
        height: 28px;
    }

    .pl-col-record,
    .pl-col-form,
    .pl-col-change {
        font-size: var(--fs-xs);
    }

    .pl-col-actions {
        width: 100%;
        justify-content: flex-end;
        padding-top: 8px;
        border-top: var(--bw-hair) solid var(--border-subtle);
        margin-top: 4px;
    }

    .pl-btn-challenge {
        width: auto;
        padding: 6px 16px;
        font-size: var(--fs-xs);
    }

    /* Второе определение кнопки страницы снято: 36 по ширине 480 — и не
       ступень цели нажатия, и запрещённая граница. Число одно на все виды. */

    /* Category page mobile: cards inherit flex layout */
    .pl-cat-row {
        display: flex;
    }

    .pl-cat-table-body .pl-row-header {
        display: none;
    }
}

/* Phone */
    /* Мелкие кегли и скрытая шапка таблицы — только телефон. */
@media (max-width: 640px) {

    /* Плашек обложки категории больше нет, и своего кегля у её заголовка
       тоже: он стоит на той же крутилке `--fs-hero`, что обзорная.
       ОДНА ВЕЛИЧИНА — ОДИН ВЛАДЕЛЕЦ. */

    

    /* Кегли обложки держит крутилка в tokens.css — здесь своих чисел нет:
       ОДНА ВЕЛИЧИНА — ОДИН ВЛАДЕЛЕЦ. */

    /* On phone: keep pedestal layout but smaller */
    

    

    

    
    
    

    
    
    

    
    

    
    

    
    

    

    .pl-col-form {
        display: none;
    }

    .pl-col-record {
        display: none;
    }

    .pl-col-country {
        display: none;
    }

    .pl-col-ntrp {
        display: none;
    }

    .pl-gender-tab {
        padding: 8px 20px;
        font-size: var(--fs-sm);
    }

    .pl-category-pill {
        padding: 0 12px;
        font-size: var(--fs-xs);
    }

    /* Здесь было 16 по вертикали и 24 по бокам — эти числа и держали
       строку в 66 пикселей, перебивая правило для телефона выше */
    .pl-row {
        padding: 10px 14px;
    }

    .pl-player-photo {
        width: 28px;
        height: 28px;
    }

    .pl-player-name {
        font-size: var(--fs-sm);
    }
}

    /* Было 375: ширины в медиа только 640 и 992, остальное делится высотой
       и поворотом. */
@media (max-width: 640px) {

    
    .pl-hero-title {
        font-size: var(--fs-xl);
    }
    .pl-gender-tab {
        padding: 7px 16px;
        font-size: var(--fs-xs);
    }
    .pl-category-pill {
        padding: 0 10px;
        font-size: var(--fs-2xs);
    }
    .pl-row {
        padding: var(--space-xs) var(--space-sm);
    }
    .pl-player-photo {
        width: 28px;
        height: 28px;
    }
    .pl-player-name {
        font-size: var(--fs-sm);
    }
    .pl-col-rank {
        font-size: var(--fs-sm);
        min-width: 24px;
    }
}

/* Кнопка в гостевой плашке: на телефоне «Войти / Регистрация» не влезало
   в отведённые 240 пикселей — боковые отступы съедали половину */
/* «Войти / Регистрация» не влезало в плашку: боковые отступы по 40 съедали
   половину ширины. Текст в одну строку, отступы поменьше */
.pl-guest-btn {
    max-width: 100%;
    justify-content: center;
    text-align: center;
    white-space: nowrap;
}

/* СТУПЕНЬ НА 1024 УБРАНА 24.09: граница мимо лестницы (640 и 992), и
   задавала она высоту полями, которую теперь держит свойство. */

/* Приглашение гостю на телефоне: плашка занимала 377 пикселей — почти
   пол-экрана, и стояла отдельным этажом под таблицей. Уменьшаем и
   сильнее накладываем на последние строки рейтинга: список уходит в
   туман, а поверх него лежит короткое предложение */
/* ТЕЛЕФОН. Граница переехала с 768 на 640 — лестница разрешает 640 и 992.
   Числа поля и кнопки взяты у эталона. Радиус отсюда убран: 16 расходился
   с общей формой всех четырёх копий, которая говорит 24 на всех видах, —
   и это единственное, что сторож не дал бы разойтись, окажись оно в
   базовом правиле. Кегль заголовка был clamp(1.15rem, 5vw, 1.32rem) —
   18.4…21.1, то есть мимо шкалы и мимо сторожа кеглей, который ищет сырое
   число сразу за font-size, а не внутри clamp. Теперь ступень 18: ровно
   на одну ниже широкой. */
@media (max-width: 640px) {

    /* Накладка садится на последние строки. Сильнее поднимать нельзя:
       строки стали ниже, и под туманом скрывался бы весь список — сверху
       оставалась бы пустая полоса */
    .pl-guest-overlay {
        margin-top: -210px;
        padding-top: var(--space-6);     /* 24 */
    }

    .pl-guest-cta {
        padding: var(--space-4) var(--space-6);   /* 16 / 24 — как у эталона */
    }

    .pl-guest-icon {
        width: 32px;
        height: 32px;
        margin-bottom: var(--space-2);   /* 8; было 34 и 10 */
    }

    .pl-guest-title {
        font-size: var(--fs-md);         /* 18; было clamp 18.4…21.1 */
        margin-bottom: var(--space-2);   /* 8 */
    }

    .pl-guest-text {
        font-size: var(--fs-xs);
        margin-bottom: var(--space-3);   /* 12; было 14 */
    }

    .pl-guest-btn {
        padding: 0 var(--space-6);       /* 24; высота та же, 44 */
    }
}

/* ============================================
   Фоновая карточка в рейтинге
   ============================================
   Человек есть в списках клуба — мы перенесли базу NTRP, — но членство
   не оплачено. Строку показываем, чтобы рейтинг отражал настоящую силу
   игроков, но видно, что в клубе он не состоит: приглушаем и убираем
   кнопку вызова. Место в рейтинге такие не занимают. */

.pl-row-guest {
    opacity: 0.45;
}

.pl-row-guest:hover {
    opacity: 0.7;
}

.pl-row-guest .pl-col-rank {
    color: var(--text-dim);
}

/* Подпись рядом с именем — коротко, чтобы не спорить с самим именем */
.pl-guest-mark {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 7px;
    border: var(--bw-hair) solid var(--border-light);
    border-radius: var(--radius-full);
    font-size: var(--fs-2xs);
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--text-dim);
    white-space: nowrap;
    vertical-align: middle;
}

@media (max-width: 640px) {

    .pl-guest-mark { display: none; }
}

/* ============================================
   ЧИПЫ КАТЕГОРИЙ НА ТЕЛЕФОНЕ
   ============================================ */

/* Masters, Tour, Futures прижимались к левому краю: у блока с чипами
   ширина по содержимому — 210 пикселей, — и собственное
   justify-content: center внутри него ничего не менял.

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

@media (max-width: 992px) {

    .pl-category-pills {
        width: 100%;
        justify-content: center;
    }
}

/* ============================================
   КНОПКА ВЫЗОВА В СТРОКЕ РЕЙТИНГА
   ============================================ */

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

   Ставим в ту же строку справа: на телефоне видимых колонок мало —
   место, очки и изменение, — место остаётся. */

@media (max-width: 992px) {

    .pl-col-actions {
        width: auto;
        margin: 0 0 0 6px;
        padding-top: 0;
        border-top: none;
        gap: 4px;
    }

    .pl-btn-challenge {
        width: 28px;
        height: 28px;
        padding: 0;
        flex: 0 0 28px;
    }
}

/* ============================================
   ИМЯ НА ПЬЕДЕСТАЛЕ
   ============================================ */

/* Длинная фамилия рвалась посередине слова — «Трофимушк / ина». Виноват
   overflow-wrap: break-word: он разрешает разрыв в любом месте, когда
   слово не помещается в колонку шириной 110 пикселей.

   Разрешаем перенос только между словами, а само слово ужимаем кеглем:
   «Трофимушкина» помещается в строку при 0.72rem. Если не поместится
   и так — обрежется многоточием, а не разорвётся. */

@media (max-width: 992px) {

    

    /* Один кегль на всех трёх: у первого места карточка шире всего на
       двадцать пикселей, а «Трофимушкина» при 0.8rem в неё не влезала и
       обрезалась на «Трофимушки» */
    

    /* Очки с пьедестала убраны: под ним сразу идёт таблица, где те же
       три игрока стоят первыми строками — с очками и местом. Место в
       карточке освободилось под имя, и оно помещается целиком */
}


/* ЗАГОЛОВОК ДЛЯ ДИКТОРА, НЕ ДЛЯ ГЛАЗА. Замер 06.10: иерархия страницы шла
   H1 → H3, второго уровня не было вовсе, и у таблицы — главного на
   странице — не было заголовка ни одного уровня. Глазами он не нужен:
   над таблицей стоит обложка с названием раздела. Диктору нужен.
   Приём стандартный: элемент остаётся в потоке и доступен дереву
   доступности, но не занимает места и не рисуется. `clip-path` вместо
   старого `clip`: тот устарел и в части браузеров съедает фокус. */
.pl-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}


/* ─────────────────────────────────────────────────────────────────────
   ТЕЛЕФОН ЛЁЖА: ПОЛОСА ФИЛЬТРОВ — ПОЛОСА, А НЕ ЭКРАН.
   Слово Кости 07.10: «кнопки фильтров слишком много места забирают, в
   вертикальном отлично смотрится».
   Замер 07.10: полоса 173 из 375 — 46% экрана на обзорной и 181 из 375
   (48%) на странице разряда, причём полоса `sticky` и держит эту долю всё
   время прокрутки. На 375 в высоту она занимает 33% и 27% — там Костя ею
   доволен. Разницу делает не поворот, а ШИРИНА: на 375 работает ступень
   ≤640 (чип 12 · поля 7/16, пилюля 11 · поля 0/10), а на 667 она
   отключается и возвращаются базовые 14 и поля 24/20.
   Здесь вид делится высотой и поворотом — ширины в медиа только 640 и 992.
   Берётся ТА ЖЕ ступень, что на узком телефоне, плюс воздух со шкалы:
   поля полосы 12/24 → 8/8, отбивка под полами 24 → 8, зазор ряда 12 → 8.
   Пилюли и «Показать всех» встают в одну строку: на 635 они занимают 546.
   Посчитано: 8 + 36 + 8 + 36 + 8 = 96 вместо 173.
   Блок стоит В КОНЦЕ ФАЙЛА НАРОЧНО: вес у него такой же, как у правил
   ≤640, и решает порядок.
   ───────────────────────────────────────────────────────────────────── */
@media (max-height: 500px) and (orientation: landscape) {

    .pl-filters-section {
        padding-block: var(--space-xs) var(--space-xs);
    }

    .pl-gender-tabs {
        margin-bottom: var(--space-xs);
    }

    /* КНОПКА 36 ЗАКОННА, ЕСЛИ У НЕЁ ЕСТЬ СЛОЙ ЦЕЛИ 44 — правило выведено
       на пилюле разряда (css/players.css, `.pl-category-pill::after`) и
       применяется сюда без нового разбора. Высота видимой кнопки падает
       со ступени 44 на ступень 36, а попадать в неё по-прежнему можно
       как в 44. */
    .pl-gender-tab {
        position: relative;
        min-height: var(--btn-h-sm);
        padding: 7px 16px;
        font-size: var(--fs-xs);
    }

    .pl-gender-tab::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: 50%;
        transform: translateY(-50%);
        height: var(--btn-h-md);
    }

    .pl-category-pill {
        padding: 0 10px;
        font-size: var(--fs-2xs);
    }

    /* Пилюли слева, «Показать всех» справа — одной строкой. Колонки
       названы явно, как в базовом правиле: состав строки может меняться,
       место каждого элемента — нет. Режим поиска сюда не попадает: у него
       свой селектор весом выше (`.pl-filters-searching .pl-category-row`). */
    .pl-category-row {
        grid-template-columns: minmax(0, auto) auto;
        align-items: center;
        gap: var(--space-xs);
    }

    .pl-category-pills {
        grid-column: 1;
        justify-content: start;
    }

    .pl-view-all {
        grid-column: 2;
        grid-row: 1;
        justify-self: end;
    }

    /* Страница разряда: «назад», поиск и название разряда — одной строкой.
       Поиск стоит 320 по центру, как на широком виде: на 635 все трое
       занимают 139 + 320 + 70 и ещё остаётся место. */
    .pl-cat-mode .pl-category-row {
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    }

    .pl-cat-mode .pl-category-row .trn-search-wrap {
        grid-column: 2;
        grid-row: 1;
        justify-self: center;
        width: 320px;
        max-width: 100%;
    }

    .pl-cat-mode .trn-cat-name {
        grid-column: 3;
        grid-row: 1;
        justify-self: end;
    }
}

/* ── МЕТКА «ЗАКРЫТ» В СПИСКЕ ИГРОКОВ (04.11) ──────────────────────────
   Здесь стоял инлайн-стиль в двух местах `js/players.js`, и числа в нём
   шли мимо шкалы: 1px 6px, 3px, 0.65rem. Метка показывает ОБА вида бана
   разом — признак `zakryt` считает база
   (`sql/доступ/players-public-zakryt-04nov.sql`).
   СЛОВО КОСТИ 04.11: никого не прячем, показываем статус.
   Кегль 11 — нижняя ступень шкалы; отступ 8 — её же; радиус и краски из
   общих значений, своих чисел нет. */
.pl-zakryt {
    display: inline-block;
    margin-left: var(--space-2);
    padding: var(--space-05) var(--space-2);
    border-radius: var(--radius-xs);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    line-height: 1;
    background: var(--danger-subtle);
    color: var(--danger);
}
