/* ==========================================================================
   Статистика L4D2 — PlayBCM
   Токены и приёмы вёрстки повторяют основной сайт playbcm.net, чтобы раздел
   не выглядел чужим: те же цвета, те же карточки, тот же сайдбар.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Токены
   -------------------------------------------------------------------------- */

:root {
    --content-width: 1040px;
    --sidebar-width: 200px;
    --layout-gap: 40px;

    --font-family: Inter, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --font-size-logo: 2em;
    --font-size-huge: 1.3em;
    --font-size-large: 1.15em;
    --font-size-default: 14px;
    --font-size-small: 0.9em;
    --font-size-smaller: 0.8em;
    --font-size-tiny: 0.7em;
    /* Подсказки — в пикселях, а не в em. Они всплывают внутри самых мелких
       подписей (шкала графика набрана 0.7em), и относительный размер там
       складывался сам с собой: текст подсказки доходил до восьми пикселей. */
    --font-size-tip: 13px;

    --font-weight-regular: 400;
    --font-weight-medium: 500;
    --font-weight-bold: 600;

    --line-height-default: 1.4em;

    --radius-card: 8px;
    --radius-control: 6px;

    --badge-background-red: #b3261e;

    --mobile-display-flex: none;
}

/* Палитра одна — тёмная, переключателя тем нет. */
:root {
    --background-body: rgb(18, 18, 18);
    --background-card: rgb(28, 28, 30);
    --border-card: rgb(36, 36, 38);
    --color-brand: hsl(0, 0%, 90%);

    --background-nav-hover: rgb(255 255 255 / 5%);
    --background-nav-active: rgb(255 255 255 / 8%);
    --background-nav-mobile: #1c1c1e;

    --color-text-important: hsl(209, 5%, 95%);
    --color-text-default: hsl(209, 5%, 85%);
    --color-text-secondary: hsl(209, 5%, 65%);
    --color-text-sidebar: hsl(209, 5%, 80%);

    --color-icon-default: hsl(0, 0%, 80%);
    --color-icon-secondary: hsl(0, 0%, 60%);
    --color-icon-tertiary: hsl(0, 0%, 40%);
    --color-icon-nav: hsl(0, 0%, 60%);

    --color-blue: #71aaeb;
    --color-green: #78b757;
    --color-orange: #e7893a;
    --color-red: #ec5e5d;
    --color-violet: #9a54a3;

    --background-default: rgb(255 255 255 / 5%);
    --background-blue: rgb(109 165 243 / 12%);
    --border-blue: rgb(109 165 243 / 30%);

    --input-background: rgb(36, 36, 38);
    --input-background-focus: rgb(44, 44, 46);
    --input-border: rgb(44, 44, 46);
    --input-border-focus: rgb(72, 72, 74);

    --table-border: hsl(0, 0%, 20%);
    --table-hover: hsl(0, 0%, 13%);
    --table-inner: hsl(240, 2%, 13%);

    --bar-fill: rgb(109 165 243 / 14%);
    --chart-bar: #71aaeb;


    --skeleton-shadow: none;
}

/* --------------------------------------------------------------------------
   2. База
   -------------------------------------------------------------------------- */

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

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

body {
    margin: 0;
    background-color: var(--background-body);
    color: var(--color-text-default);
    font-family: var(--font-family);
    font-size: var(--font-size-default);
    font-weight: var(--font-weight-regular);
    line-height: var(--line-height-default);
    overflow-x: hidden;
    -webkit-tap-highlight-color: transparent;
    word-break: break-word;
}

input,
select,
button {
    font-family: inherit;
    font-size: inherit;
}

a {
    color: inherit;
    text-decoration: none;
}

a.link {
    color: var(--color-blue);
}

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

h1,
h2,
h3 {
    color: var(--color-text-important);
    font-weight: var(--font-weight-bold);
    margin: 0;
}

h1 {
    font-size: var(--font-size-huge);
}

img {
    max-width: 100%;
}

/* Базовый размер контурных иконок. SVG задан только viewBox, поэтому без
   явных размеров он растягивается на всю ширину родителя. */
.icon {
    height: 1.15em;
    width: 1.15em;
    flex: none;
    vertical-align: -0.18em;
}

.muted {
    color: var(--color-text-secondary);
}

.nowrap {
    white-space: nowrap;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* Цифры в таблицах должны стоять в колонку одинаковой ширины. */
.tabular {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

/* --------------------------------------------------------------------------
   3. Каркас страницы
   -------------------------------------------------------------------------- */

.layout {
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: var(--layout-gap);
    padding: 0 20px;
}

.sidebar {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    width: var(--sidebar-width);
    flex: 0 0 var(--sidebar-width);
    user-select: none;
}

.sidebar .brand {
    display: flex;
    align-items: center;
    min-height: 100px;
    padding-left: 20px;
    font-size: var(--font-size-logo);
    font-weight: var(--font-weight-bold);
    color: var(--color-brand);
}

.sidebar .nav {
    display: flex;
    flex-direction: column;
}

/* Геометрия пункта повторяет playbcm.net до пикселя: высота 41 px, шаг 45 px,
   иконка на 20 px от края, подпись на 50 px.

   Высоту задаёт только строка текста. На основном сайте line-height нигде не
   переопределён и равен normal — это 17 px при Inter 14 px, плюс отступы 12+12
   даёт 41. У нас же line-height: 1.4em висит на body, то есть 19.6 px, и пункт
   вырастал до 43.6 px. Поэтому здесь возвращаем normal. */
.sidebar .nav a {
    display: flex;
    align-items: center;
    padding: 12px 20px;
    margin-bottom: 4px;
    border-radius: var(--radius-card);
    color: var(--color-text-sidebar);
    line-height: normal;
    transition: background-color 150ms;
    cursor: pointer;
}

/* Подпись отодвигается фиксированным отступом, а не gap: иконка выведена из
   потока (см. ниже), и раздвигать flex-ом уже нечего. 20 px отступа плюс 30 —
   ровно те же 50 px от края пункта, что и на основном сайте. */
.sidebar .nav a span {
    margin-left: 30px;
}

.sidebar .nav a:hover,
.sidebar .nav a:focus-visible {
    background-color: var(--background-nav-hover);
    outline: none;
}

.sidebar .nav a.active {
    background-color: var(--background-nav-active);
    color: var(--color-text-important);
}

/* Иконка вынута из потока — так же, как на основном сайте. Она выше строки
   текста (19.6 против 17 px), и оставаясь flex-элементом растягивала бы пункт
   по себе. Координаты не заданы: абсолютный элемент без top/left встаёт на своё
   же место в потоке, а во flex-контейнере это место считается по align-items,
   то есть иконка остаётся у левого края и по центру высоты. */
.sidebar .nav svg {
    position: absolute;
    height: 1.4em;
    width: 1.4em;
    color: var(--color-icon-nav);
}

.sidebar .nav a.active svg {
    color: var(--color-icon-default);
}

.content {
    width: 100%;
    max-width: var(--content-width);
    min-width: 0;
    /* Ровно высота блока с логотипом в сайдбаре: содержимое любой страницы
       начинается на одной линии с первым пунктом меню. */
    padding-top: 100px;
    /* Снизу отступ даёт сама карточка (margin-bottom: 20px). Дополнительные
       40 px остались от строки «Загружено за …» и после её удаления читались
       как пустой хвост страницы. */
    padding-bottom: 0;
}

.page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding-bottom: 20px;
}

.page-head .subtitle {
    color: var(--color-text-secondary);
    font-size: var(--font-size-small);
    margin-top: 2px;
}

.page-foot {
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    text-align: center;
    padding: 8px 0 24px;
}

/* --------------------------------------------------------------------------
   4. Карточки
   -------------------------------------------------------------------------- */

.card {
    background-color: var(--background-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
    margin-bottom: 20px;
    box-shadow: var(--skeleton-shadow);
}

.card > .header {
    display: flex;
    align-items: center;
    gap: 10px;
    border-bottom: 1px solid var(--border-card);
    font-size: var(--font-size-large);
    font-weight: var(--font-weight-bold);
    color: var(--color-text-important);
    padding: 14px 20px;
}

.card > .header img {
    height: 20px;
    width: 20px;
    object-fit: contain;
}

/* Иконка раздела в шапке карточки рейтинга. */
.card > .header .board-icon {
    height: 18px;
    width: 18px;
    color: var(--color-icon-secondary);
    vertical-align: 0;
}

/* Заголовок карточки рейтинга ведёт на тот же рейтинг целиком. Стрелка
   приглушена, но видна всегда: только по наведению её не нашли бы с телефона,
   где наведения не бывает. */
.card > .header .board-title {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    transition: color 150ms;
}

.card > .header .board-title:hover {
    color: var(--color-blue);
}

.card > .header .board-more {
    height: 14px;
    width: 14px;
    opacity: 0.45;
    transition: opacity 150ms;
}

.card > .header .board-title:hover .board-more,
.card > .header .board-title:focus-visible .board-more {
    opacity: 1;
}

.card > .header .note {
    margin-left: auto;
    font-size: var(--font-size-smaller);
    font-weight: var(--font-weight-regular);
    color: var(--color-text-secondary);
}

/* Шапка графика с переключателем окна: на телефоне переключатель уходит на
   вторую строку, а не сминает заголовок. */
.card > .header.chart-header {
    flex-wrap: wrap;
    row-gap: 8px;
}

/* Карточка, окно которой подгружается: старый график остаётся на месте, чтобы
   страница не прыгала, но видно, что он уже не тот. */
.chart-card.loading > :not(.header) {
    opacity: 0.45;
    transition: opacity 150ms;
}

/* Размер — как у строки фильтров над страницей, чтобы список длины окна был
   точной копией списков «Всё время» и «Все сервера». Шапка карточки крупнее
   (--font-size-large), а размеры здесь в em, поэтому её увеличение снимается.
   Выделять в переключателе нечего: двойной клик по стрелке иначе подсвечивал
   бы и её, и подпись окна. */
.chart-range {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    font-size: calc(1em / 1.15 * 0.9);
    font-weight: var(--font-weight-regular);
    user-select: none;
    -webkit-user-select: none;
}

.chart-range-step {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

/* Стрелки — иконки, а не символы ‹ ›: у символа шрифта свои боковые отступы,
   и подпись окна между двумя такими стрелками стояла не по центру. */
.chart-range-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-control);
    color: var(--color-text-secondary);
}

.chart-range-arrow .icon {
    width: 16px;
    height: 16px;
    vertical-align: 0;
}

a.chart-range-arrow:hover {
    background-color: var(--background-nav-hover);
    color: var(--color-text-important);
}

.chart-range-arrow.disabled {
    opacity: 0.3;
    cursor: default;
}

/* Ширина подписи не прыгает при листании: цифры моноширинные. */
.chart-range-label {
    padding: 0 6px;
    cursor: default;
    font-size: var(--font-size-small);
    color: var(--color-text-default);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.card > .body {
    padding: 16px 20px;
}

.card > .body.flush {
    padding: 4px 0;
}

/* Колонки — обычный grid с готовой раскладкой из PHP. CSS-колонки (columns: 2)
   здесь не годятся: карточку выше колонки они разрывают, а break-inside: avoid
   в таком случае не спасает. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 20px;
    align-items: start;
}

.card-column {
    min-width: 0;
}

/* --------------------------------------------------------------------------
   5. Таблицы
   -------------------------------------------------------------------------- */

.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Полосу прокрутки прячем: она оказывается под таблицей, а у рекордов это
       полторы тысячи строк вниз. Тянуть можно за любое место (см. app.js). */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.table-scroll::-webkit-scrollbar {
    display: none;
}

/* Курсор-«рука» только когда таблица действительно шире экрана. */
.table-scroll.grabbing {
    cursor: grabbing;
    user-select: none;
}

table.data {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

table.data th,
table.data td {
    padding: 8px 20px;
    text-align: left;
    vertical-align: middle;
}

table.data thead th {
    color: var(--color-text-secondary);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-smaller);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
    border-bottom: 1px solid var(--table-border);
    padding-top: 10px;
    padding-bottom: 10px;
}

table.data thead th a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

table.data thead th a:hover {
    color: var(--color-text-important);
}

table.data thead th a.sorted {
    color: var(--color-blue);
}

table.data tbody tr {
    border-bottom: 1px solid var(--table-border);
}

table.data tbody tr:last-child {
    border-bottom: 0;
}

/* «Лучшие результаты» стоят в профиле среди карточек, где строки ничем не
   разделены (.facts и .breakdown линеек не рисуют), и единственная таблица с
   разлиновкой выбивалась из ряда. В списке игроков и рекордах линейки
   остаются: там строк сотни и глазу нужно за что-то держаться. */
table.data.seamless tbody tr {
    border-bottom: 0;
}

/* «Лучшие результаты»: название карты забирает остаток ширины и обрезается
   многоточием, а не растягивает таблицу. Иначе профиль на телефоне уезжал
   вбок — таблица оказывалась шире экрана. */
table.data.seamless td.map {
    max-width: 0;
}

table.data.seamless td.map .nowrap {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Таблицы аналитики колонок не теряют: там смотрят на цифры целиком, а узкий
   экран решается горизонтальной прокруткой (.table-scroll). */
table.data.full-columns {
    width: max-content;
    min-width: 100%;
}

table.data.full-columns .hide-md,
table.data.full-columns .hide-sm {
    display: table-cell;
}

table.data.full-columns .row-meta {
    display: none;
}

table.data tbody tr:hover {
    background-color: var(--table-hover);
}

/* Строка-ссылка: нажимается вся площадь, а не только ник.
   Выделение текста отключено, иначе клик по строке начинал бы его выделять. */
table.data tbody tr[data-href] {
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}

table.data tbody tr[data-href] a {
    cursor: pointer;
}

table.data td.numeric,
table.data th.numeric {
    text-align: right;
    white-space: nowrap;
}

/* Заголовок текстовой колонки выровнен так же, как ники под ним. */
table.data th.player-heading {
    text-align: left;
}

/* Колонка сжимается по содержимому: ширина 1% при table-layout: auto
   заставляет браузер отдать ей минимум, а остаток забирают соседние. */
table.data td.shrink,
table.data th.shrink {
    width: 1%;
    white-space: nowrap;
}

table.data td.position {
    color: var(--color-text-secondary);
    width: 1%;
    white-space: nowrap;
    padding-right: 0;
}

table.data td.position.top-1 { color: #e0b341; font-weight: var(--font-weight-bold); }
table.data td.position.top-2 { color: #b6bec8; font-weight: var(--font-weight-bold); }
table.data td.position.top-3 { color: #c8813f; font-weight: var(--font-weight-bold); }

/* Значения скрытых на телефоне колонок, показываемые под ником. */
.row-meta {
    display: none;
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    margin-top: 1px;
    /* Ограничение обязательно: иначе эта строка становится самым широким
       содержимым ячейки и растягивает всю колонку. */
    max-width: 26ch;
}

/* Таблицы внутри двухколоночной сетки живут в 500 px — им нужны более
   плотные отступы и более короткий предел для ников. */
.card-grid table.data th,
.card-grid table.data td {
    padding-left: 12px;
    padding-right: 12px;
}

.card-grid .player .name {
    max-width: 14ch;
}

table.data .empty {
    text-align: center;
    color: var(--color-text-secondary);
    padding: 28px 20px;
}

/* Пары «показатель — значение». */
.facts {
    width: 100%;
    border-collapse: collapse;
}

.facts th,
.facts td {
    padding: 7px 20px;
    vertical-align: baseline;
}

.facts th {
    text-align: left;
    font-weight: var(--font-weight-regular);
    color: var(--color-text-secondary);
    width: 55%;
}

.facts td {
    text-align: right;
    color: var(--color-text-important);
    font-variant-numeric: tabular-nums;
}

.facts tr:hover {
    background-color: var(--table-hover);
}

/* Знак вопроса рядом с подписью: пояснение, которое нужно один раз, не должно
   занимать место в таблице постоянно. */
.hint-mark {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 14px;
    width: 14px;
    margin-left: 6px;
    border-radius: 999px;
    background-color: var(--background-default);
    color: var(--color-text-secondary);
    line-height: 1;
    cursor: help;
    vertical-align: middle;
}

.hint-mark::before {
    content: "?";
    font-size: var(--font-size-tiny);
}

.hint-mark:hover,
.hint-mark:focus-visible {
    outline: none;
    color: var(--color-text-important);
}

/* Общий вид всплывающих подсказок: у знака вопроса, у ячейки тепловой карты,
   у точки «в игре» и у графика он один и тот же. */
.hint-tip,
.chart-tip,
.chart-area-tip,
.dot-tip {
    z-index: 5;
    /* Ограничение для подсказок с переносом; у однострочных снимается ниже —
       иначе текст не переносился бы, а вылезал за фон. */
    max-width: 260px;
    width: max-content;
    padding: 8px 10px;
    border: 1px solid var(--input-border-focus);
    border-radius: var(--radius-control);
    background-color: var(--input-background-focus);
    color: var(--color-text-important);
    box-shadow: 0 6px 20px rgb(0 0 0 / 45%);
    font-size: var(--font-size-tip);
    font-weight: var(--font-weight-regular);
    line-height: 1.45;
    text-align: left;
    white-space: normal;
    pointer-events: none;
}

/* Появляются по наведению. Позиционирование общее, отклонения — у каждой своё
   ниже: тепловая карта и точка живут в разных по высоте контейнерах. */
.hint-tip,
.chart-tip,
.dot-tip {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 6px);
    transform: translateX(-50%);
    opacity: 0;
    transition: opacity 120ms;
}

/* Подсказка на самом значении: уточнение к тому, что уже видно, поэтому
   ни знака вопроса, ни подчёркивания — только курсор. */
.hint-anchor {
    position: relative;
    cursor: help;
}

.hint-mark:hover .hint-tip,
.hint-mark:focus-visible .hint-tip,
.hint-anchor:hover .hint-tip,
.hint-anchor:focus-visible .hint-tip {
    opacity: 1;
}

.hint-anchor:focus-visible {
    outline: none;
}

/* Значения в таблице прижаты вправо, поэтому по центру подсказка вылезала бы
   за карточку — прижимаем её к тому же правому краю. */
.facts .hint-anchor .hint-tip {
    left: auto;
    right: 0;
    transform: none;
}

/* Пояснение справа от значения: «за 90 дней» и подобное. */
.facts .note {
    margin-left: 6px;
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
}

/* Примечание, которому рядом со значением не хватает места: своей строкой и
   без разрыва внутри — «20 ч. назад» не должно разваливаться на две. */
.facts .note.below {
    display: block;
    margin-left: 0;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   6. Игрок в строке таблицы
   -------------------------------------------------------------------------- */

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

.player .flag {
    height: 12px;
    width: 16px;
    flex: none;
    object-fit: cover;
    border-radius: 2px;
}

.player .name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--color-text-important);
    /* Без ограничения ширины колонка растягивается под самый длинный ник
       в выдаче, и многоточие никогда не срабатывает. Полное имя — в title. */
    max-width: 24ch;
}


.player .alias {
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dot-online {
    position: relative;
    height: 8px;
    width: 8px;
    flex: none;
    border-radius: 50%;
    background-color: var(--color-green);
    box-shadow: 0 0 0 3px var(--background-default);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-green) 20%, transparent);
}

/* Точка «в игре» подписывается своей подсказкой, а не системным title:
   тот появляется с задержкой в секунду, набран шрифтом системы и в тёмной
   теме выглядит белым прямоугольником посреди страницы. */
/* Подсказка встаёт сбоку, а не сверху. У .table-scroll задан overflow-x, из-за
   чего по вертикали он тоже обрезает содержимое, — и у первой строки списка
   подсказка над точкой оказывалась срезанной верхним краем таблицы. Сбоку она
   целиком помещается в высоту строки и не обрезается никогда. */
.dot-tip {
    bottom: auto;
    top: 50%;
    left: calc(100% + 8px);
    transform: translateY(-50%);
    max-width: none;
    white-space: nowrap;
}

.dot-online:hover .dot-tip {
    opacity: 1;
}

.badge-inactive {
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
    border: 1px solid var(--border-card);
    border-radius: 999px;
    padding: 0 6px;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   7. Шапка профиля
   -------------------------------------------------------------------------- */

.profile-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    align-items: start;
    gap: 20px;
}

.profile-identity {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 20px;
    border-bottom: 1px solid var(--border-card);
    margin-bottom: 6px;
}

.profile-identity .avatar {
    height: 84px;
    width: 84px;
    flex: none;
    border-radius: var(--radius-card);
    object-fit: cover;
    background-color: var(--background-default);
}

.profile-identity .meta {
    min-width: 0;
}

.profile-identity h1 {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--font-size-huge);
    overflow-wrap: anywhere;
}

.profile-identity .place {
    color: var(--color-text-secondary);
    margin-top: 2px;
}

.profile-identity .place b {
    color: var(--color-text-important);
}

/* Флаг в строке «Откуда». */
.facts .flag {
    height: 12px;
    width: 16px;
    object-fit: cover;
    border-radius: 2px;
    vertical-align: baseline;
}

/* Ссылка-действие в подвале карточки (например «Подарить VIP»). */
.card-action {
    display: flex;
    align-items: center;
    gap: 6px;
    border-top: 1px solid var(--border-card);
    margin-top: 6px;
    padding: 12px 20px;
    font-size: var(--font-size-small);
}

.status-online {
    color: var(--color-green);
}

.profile-rank {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 20px;
}

.profile-rank img {
    height: 132px;
    width: 132px;
    object-fit: contain;
}

.profile-rank .rank-name {
    color: var(--color-text-important);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-large);
    margin-top: 6px;
}

.profile-rank .rank-next {
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    margin-top: 2px;
}

.progress {
    width: 100%;
    height: 6px;
    margin-top: 12px;
    border-radius: 999px;
    background-color: var(--background-default);
    overflow: hidden;
}

.progress > span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background-color: var(--color-blue);
}

/* На максимальном звании подпись остаётся одна — «до повышения» больше нет,
   и space-between прижимал бы её к левому краю. */
.progress-legend.single {
    justify-content: center;
}

.progress-legend {
    display: flex;
    justify-content: space-between;
    width: 100%;
    margin-top: 6px;
    font-size: var(--font-size-smaller);
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   8. Плитки показателей
   -------------------------------------------------------------------------- */

.kpi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px;
    background-color: var(--border-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
    overflow: hidden;
    margin-bottom: 20px;
}

.kpi .tile {
    background-color: var(--background-card);
    padding: 14px 16px;
}

.kpi .tile .label {
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.kpi .tile .value {
    color: var(--color-text-important);
    font-size: var(--font-size-huge);
    font-weight: var(--font-weight-bold);
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}

/* Обзор аналитики: две короткие сводки вместо двух широких таблиц с
   техническими средними. На одной высоте сравниваются исходы и сложность. */
.analytics-overview-grid {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 20px;
    margin-bottom: 20px;
}

.analytics-overview-grid .card {
    min-width: 0;
    margin-bottom: 0;
}

.outcome-body {
    padding: 18px 20px 16px;
}

.outcome-primary {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 0 12px;
}

.outcome-primary strong {
    grid-row: 1 / 3;
    color: var(--color-text-important);
    font-size: 2.15em;
    line-height: 1em;
    font-variant-numeric: tabular-nums;
}

.outcome-primary span {
    color: var(--color-text-important);
    font-weight: var(--font-weight-medium);
}

.outcome-primary small {
    color: var(--color-text-secondary);
}

.outcome-bar {
    display: flex;
    height: 8px;
    overflow: hidden;
    margin: 18px 0 12px;
    border-radius: 999px;
    background-color: var(--background-default);
}

.outcome-bar span {
    width: var(--share);
    min-width: 0;
}

.outcome-win { background-color: var(--color-green); }
.outcome-loss { background-color: var(--color-red); }
.outcome-incomplete { background-color: var(--color-orange); }

.outcome-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.outcome-list > div {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto 3.6em;
    align-items: center;
    gap: 8px;
}

.outcome-list strong,
.outcome-list small {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.outcome-list small {
    color: var(--color-text-secondary);
}

.outcome-key {
    width: 9px;
    height: 9px;
    border-radius: 3px;
}

table.data.difficulty-summary th,
table.data.difficulty-summary td {
    padding-left: 12px;
    padding-right: 12px;
}

table.data.difficulty-summary th:first-child,
table.data.difficulty-summary td:first-child {
    padding-left: 20px;
}

table.data.difficulty-summary th:last-child,
table.data.difficulty-summary td:last-child {
    padding-right: 20px;
}


/* --------------------------------------------------------------------------
   9. Строки с долей
   -------------------------------------------------------------------------- */

.breakdown {
    display: flex;
    flex-direction: column;
}

/* Долю показывает фоновый градиент с резкой границей — раньше это был
   псевдоэлемент с position: absolute и z-index: -1 внутри своего контекста
   наложения. Градиент даёт ту же картинку, но не создаёт ни абсолютного
   позиционирования, ни контекста наложения. */
.breakdown-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 12px;
    padding: 7px 20px;
    background-image: linear-gradient(
        to right,
        var(--bar-fill) var(--fill, 0%),
        transparent var(--fill, 0%)
    );
}

.breakdown-row:hover {
    background-color: var(--table-hover);
}

.breakdown-row .title {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    color: var(--color-text-important);
}

.breakdown-row .title span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.breakdown-row .title img {
    height: 20px;
    width: 24px;
    flex: none;
    object-fit: contain;
}

/* Оружие заметно шире остальных игровых пиктограмм. Сохраняем исходные
   пропорции 11:3, чтобы силуэт не превращался в короткую узкую полоску. */
.breakdown-row.wide .title img {
    width: 74px;
}

.breakdown-row .value {
    color: var(--color-text-important);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.breakdown-row .percent {
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    min-width: 3.4em;
    text-align: right;
}

.breakdown-row.wide {
    grid-template-columns: minmax(0, 1fr) auto auto auto;
}

/* --------------------------------------------------------------------------
   10. Награды
   -------------------------------------------------------------------------- */

.awards {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 16px 20px;
}

.awards figure {
    margin: 0;
    width: 96px;
    text-align: center;
}

.awards img {
    width: 96px;
    height: 96px;
    object-fit: contain;
}

.awards figcaption {
    font-size: var(--font-size-smaller);
    color: var(--color-text-secondary);
    margin-top: 4px;
}

/* --------------------------------------------------------------------------
   11. Графики
   -------------------------------------------------------------------------- */

.chart-empty {
    color: var(--color-text-secondary);
    text-align: center;
    padding: 32px 0;
    margin: 0;
}

/* --- Тепловая шкала активности --------------------------------------- */

.activity {
    padding: 4px 20px 18px;
}

.activity-summary {
    margin: 0 0 16px;
    color: var(--color-text-important);
}

.activity-section + .activity-section {
    margin-top: 18px;
}

.activity-title {
    font-size: var(--font-size-smaller);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-secondary);
    margin-bottom: 8px;
}

.heat {
    display: grid;
    grid-template-columns: repeat(var(--cells), minmax(0, 1fr));
    gap: 3px;
}

.heat-cell {
    position: relative;
    min-width: 0;
    text-align: center;
}

/* В ячейке нет текста, поэтому насыщенность задаём прозрачностью:
   значение попадает в CSS одним числом и не требует расчёта цвета в PHP. */
.heat-box {
    display: block;
    height: 30px;
    border-radius: 4px;
    background-color: var(--chart-bar);
    opacity: calc(0.07 + 0.93 * var(--level));
    transition: transform 150ms;
}

.heat-hours .heat-box {
    height: 26px;
    border-radius: 3px;
}

.heat-cell:hover .heat-box {
    transform: scaleY(1.12);
}

/* Самая активная ячейка обведена — глазами её искать не нужно. */
.heat-cell.peak .heat-box {
    box-shadow: 0 0 0 2px var(--background-card), 0 0 0 3px var(--chart-bar);
}

.heat-label {
    display: block;
    margin-top: 6px;
    font-size: var(--font-size-smaller);
    color: var(--color-text-secondary);
    white-space: nowrap;
    overflow: hidden;
}

.heat-text {
    display: block;
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
    opacity: 0.75;
    white-space: nowrap;
    overflow: hidden;
}

/* Двадцать четыре подписи в ряд не читаются — оставляем каждую третью. */
.heat-hours .heat-cell:not(:nth-child(3n + 1)) .heat-label {
    visibility: hidden;
}

.chart-tip {
    /* Верх ячейки совпадает с верхом цветного квадрата, поэтому подсказка
       встаёт над ним и не перекрывает подписи снизу. */
    bottom: calc(100% + 6px);
    max-width: none;
    white-space: nowrap;
}

.heat-cell:hover .chart-tip {
    opacity: 1;
}

/* Подсказка шире ячейки, поэтому у краёв шкалы её прижимаем к краю —
   иначе она вылезала бы за карточку и расширяла страницу вбок.
   Ячеек в шкале часов двадцать четыре, так что «край» — это первые
   и последние пять. */
.heat-cell:nth-child(-n + 5) .chart-tip {
    left: 0;
    transform: none;
}

.heat-cell:nth-last-child(-n + 5) .chart-tip {
    left: auto;
    right: 0;
    transform: none;
}

.chart-area {
    position: relative;
    margin: 0;
    padding: 16px 20px 8px;
}

.chart-area-svg {
    display: block;
    width: 100%;
    height: 220px;
}

.chart-fill {
    stroke: none;
}

.chart-gradient-top {
    stop-color: var(--chart-bar);
    stop-opacity: 0.35;
}

.chart-gradient-bottom {
    stop-color: var(--chart-bar);
    stop-opacity: 0;
}

.chart-line {
    fill: none;
    stroke: var(--chart-bar);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.chart-zero {
    stroke: var(--table-border);
    stroke-width: 1;
    stroke-dasharray: 4 4;
}

.chart-cursor {
    stroke: var(--color-text-secondary);
    stroke-width: 1;
}

.chart-area-scale {
    position: absolute;
    top: 16px;
    bottom: 30px;
    right: 20px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: flex-end;
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

.chart-area-axis {
    display: flex;
    justify-content: space-between;
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.chart-area-tip {
    position: absolute;
    top: 16px;
    max-width: none;
    white-space: nowrap;
    pointer-events: none;
    transform: translateX(-50%);
}

/* --- График онлайна: линии по серверам ------------------------------- */

.chart-lines {
    position: relative;
    margin: 0;
    padding: 16px 20px 8px;
}

.chart-lines:focus-visible {
    outline: 1px solid var(--input-border-focus);
    outline-offset: -1px;
}

.chart-lines-svg {
    display: block;
    width: 100%;
    height: 260px;
}

/* Шкала общая с графиком профиля, но там она тянется до низа карточки —
   здесь ниже графика лежит ещё и легенда, и подписи уехали бы в неё вместе
   с нулём. Высота задаётся ровно по графику: числа обязаны стоять на своих
   высотах, иначе они хуже, чем никаких. */
.chart-lines .chart-area-scale {
    top: 16px;
    bottom: auto;
    height: 260px;
}

/* Общий онлайн — главная кривая: заливка под ней задаёт форму волны,
   которую видно раньше, чем разбираешь отдельные сервера. */
.chart-total-fill {
    stroke: none;
}

.chart-total-line {
    fill: none;
    stroke: var(--color-text-important);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.chart-serie {
    fill: none;
    stroke: var(--series);
    stroke-dasharray: var(--dash, none);
    stroke-width: 1.5;
    stroke-linejoin: round;
    stroke-linecap: round;
    opacity: 0.85;
    transition: opacity 120ms;
}

/* Горизонтальная сетка: без неё высота кривой читается только по краям
   шкалы, а «двадцать это много или мало» спрашивают к середине. */
.chart-grid {
    stroke: var(--table-border);
    stroke-width: 1;
    stroke-dasharray: 3 5;
    opacity: 0.5;
}

/* Наведение на строку легенды гасит остальные линии: полтора десятка кривых
   в одном поле — искать свой сервер по цвету точки отдельная работа. */
.chart-lines.highlight .chart-serie {
    opacity: 0.1;
}

.chart-lines.highlight .chart-total-line,
.chart-lines.highlight .chart-total-fill {
    opacity: 0.25;
}

.chart-lines.highlight .chart-serie.on {
    opacity: 1;
    stroke-width: 2.5;
}

.chart-legend {
    display: grid;
    /* 150, а не 160: на телефоне шириной 375 пикселей вторая колонка при
       ста шестидесяти не влезает ровно на ширину зазора, и легенда из всех
       серверов вытягивается в столбик на пол-экрана. */
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 2px 16px;
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    font-size: var(--font-size-smaller);
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 6px;
    border-radius: var(--radius-control);
    cursor: default;
    transition: background-color 120ms;
}

.legend-item:hover {
    background-color: var(--background-default);
}

.legend-item:focus-visible {
    outline: 1px solid var(--input-border-focus);
    background-color: var(--background-default);
}

.legend-dot {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background-color: var(--series);
}

.chart-legend .legend-dot {
    width: 16px;
    height: 4px;
    border-radius: 2px;
}

.chart-legend .legend-dot.dash-1 {
    background: repeating-linear-gradient(
        to right,
        var(--series) 0 7px,
        transparent 7px 11px
    );
}

.chart-legend .legend-dot.dash-2 {
    background: repeating-linear-gradient(
        to right,
        var(--series) 0 2px,
        transparent 2px 5px
    );
}

.legend-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Ось времени: подписи стоят каждая на своей доле ширины, а не разложены
   поровну. Проценты в transform считаются от ширины самой подписи, поэтому
   одна и та же переменная и сдвигает подпись вправо, и втягивает её обратно
   ровно настолько, чтобы крайние не вылезли за график. */
.chart-lines-axis {
    position: relative;
    display: block;
    height: 1.3em;
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
}

.chart-lines-axis span {
    position: absolute;
    left: var(--at);
    transform: translateX(calc(var(--at) * -1));
    white-space: nowrap;
}

/* Подсказка разбирает все линии под курсором, поэтому она выше однострочной
   подсказки линейного графика профиля. */
.chart-lines .chart-area-tip {
    max-width: none;
    min-width: 190px;
}

.tip-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.tip-row .legend-dot {
    width: 8px;
    height: 8px;
}

.tip-row span:last-child {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

/* Общий онлайн — первая строка и единственная выделенная: он отвечает на
   вопрос, ради которого на график и смотрят. */
.tip-total {
    font-weight: var(--font-weight-bold);
    color: var(--color-text-important);
    border-bottom: 1px solid var(--input-border);
    padding-bottom: 4px;
    margin-bottom: 4px;
}

.tip-when {
    color: var(--color-text-secondary);
    margin-bottom: 4px;
}

/* --------------------------------------------------------------------------
   12. Поиск, кнопки, фильтры
   -------------------------------------------------------------------------- */

.toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.field {
    position: relative;
    display: flex;
    align-items: center;
}

.field svg {
    position: absolute;
    left: 10px;
    height: 16px;
    width: 16px;
    color: var(--color-icon-secondary);
    pointer-events: none;
}

.field.wide {
    flex: 1;
    min-width: 220px;
}

.field.wide input {
    width: 100%;
}

.field input {
    width: 220px;
    max-width: 100%;
    padding: 8px 12px 8px 32px;
    color: var(--color-text-default);
    background-color: var(--input-background);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-control);
    transition: border-color 150ms, background-color 150ms;
}

.field input::placeholder {
    color: var(--color-text-secondary);
}

.field input:focus {
    outline: none;
    background-color: var(--input-background-focus);
    border-color: var(--input-border-focus);
}

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid var(--input-border);
    border-radius: var(--radius-control);
    background-color: var(--input-background);
    color: var(--color-text-important);
    cursor: pointer;
    transition: background-color 150ms, border-color 150ms;
}

.button:hover {
    background-color: var(--background-nav-hover);
}

.button.primary {
    background-color: rgb(52, 52, 54);
    border-color: rgb(52, 52, 54);
    color: hsl(0, 0%, 60%);
}

.button.primary:hover {
    filter: brightness(1.15);
}

.button svg {
    height: 16px;
    width: 16px;
}

.chips {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    border: 1px solid var(--border-card);
    color: var(--color-text-secondary);
    font-size: var(--font-size-small);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 150ms, color 150ms;
}

.chip:hover {
    background-color: var(--background-nav-hover);
    color: var(--color-text-important);
}

.chip.active {
    background-color: var(--background-blue);
    border-color: var(--border-blue);
    color: var(--color-blue);
}

.filter-note {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 20px;
    border-bottom: 1px solid var(--border-card);
    color: var(--color-text-secondary);
    font-size: var(--font-size-small);
}

/* --------------------------------------------------------------------------
   13. Пагинация
   -------------------------------------------------------------------------- */

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    flex-wrap: wrap;
    padding: 14px 20px;
    border-top: 1px solid var(--border-card);
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0 8px;
    border-radius: var(--radius-control);
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
}

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

.pagination .current {
    background-color: var(--background-blue);
    color: var(--color-blue);
    font-weight: var(--font-weight-bold);
}

.pagination .gap {
    min-width: 20px;
}

/* --------------------------------------------------------------------------
   14. Вкладки
   -------------------------------------------------------------------------- */

.tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border-card);
    padding: 0 12px;
    overflow-x: auto;
    /* Прокрутка нужна только на узком экране, а полоса под вкладками мешает
       всегда — прячем её, жест и колесо продолжают работать. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.tabs::-webkit-scrollbar {
    display: none;
}

.tabs button {
    position: relative;
    padding: 12px 12px 11px;
    border: 0;
    background: none;
    color: var(--color-text-secondary);
    white-space: nowrap;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 150ms;
}

.tabs button:hover {
    color: var(--color-text-important);
}

.tabs button[aria-selected="true"] {
    color: var(--color-text-important);
    border-bottom-color: var(--color-blue);
    font-weight: var(--font-weight-medium);
}

/* --------------------------------------------------------------------------
   15. Мобильная навигация
   -------------------------------------------------------------------------- */

.nav-mobile {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 56px;
    display: var(--mobile-display-flex);
    justify-content: space-around;
    align-items: stretch;
    /* Первое объявление — запасное для браузеров без color-mix(). */
    background-color: var(--background-nav-mobile);
    background-color: color-mix(in srgb, var(--background-nav-mobile) 82%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-top: 1px solid var(--border-card);
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 10;
}

.nav-mobile a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    flex: 1;
    font-size: var(--font-size-tiny);
    color: var(--color-text-secondary);
}

.nav-mobile a.active {
    color: var(--color-blue);
}

.nav-mobile svg {
    height: 22px;
    width: 22px;
}

.topbar {
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 20px;
}

.topbar .brand {
    font-size: var(--font-size-huge);
    font-weight: var(--font-weight-bold);
    color: var(--color-brand);
}

/* --------------------------------------------------------------------------
   16. Аналитика
   -------------------------------------------------------------------------- */

/* Переключение между обзором, картами, выдачей и заходами. От .tabs отличается
   тем, что это настоящие ссылки: на срез удобно дать ссылку, да и держать в
   разметке сразу четыре страницы тяжёлых агрегатов незачем. */
.section-tabs {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding-bottom: 16px;
}

.section-tabs a {
    padding: 7px 14px;
    border-radius: var(--radius-control);
    color: var(--color-text-secondary);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    transition: background-color 150ms, color 150ms;
}

.section-tabs a:hover {
    background-color: var(--background-nav-hover);
    color: var(--color-text-important);
}

.section-tabs a.active {
    background-color: var(--background-nav-active);
    color: var(--color-text-important);
}

/* Карточка с фильтрами состоит из одних полос .filter-note, и последняя из них
   рисовала линию по нижнему краю самой карточки. */
.card.filters .filter-note:last-child {
    border-bottom: none;
}

/* Доля, окрашенная по значению. Цвет отвечает на вопрос «много это или мало»
   раньше, чем глаз дочитает цифру, и в отличие от прежней полоски под числом
   не растит строку вдвое. */
.percent-value {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
    white-space: nowrap;
}

.percent-value.tone-good {
    color: var(--color-green);
}

.percent-value.tone-warn {
    color: var(--color-orange);
}

.percent-value.tone-bad {
    color: var(--color-red);
}

.percent-value.tone-muted {
    color: var(--color-text-secondary);
}

.delta {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.delta.up {
    color: var(--color-green);
}

.delta.down {
    color: var(--color-red);
}

.badge-done {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background-color: var(--background-blue);
    color: var(--color-blue);
    font-size: var(--font-size-smaller);
    white-space: nowrap;
}

/* Заголовок-сортировка. Значка рядом с названием нет: нажимаемость видно по
   курсору, а текущий столбец — по подсветке его заголовка. */
table.data thead th[data-sort] {
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}

table.data thead th[data-sort]:hover,
table.data thead th[data-sort].sorted {
    color: var(--color-text-important);
}

/* Поиск в строке фильтров прижимается вправо: он ищет по уже отобранным
   строкам, а не отбирает их, и в один ряд с выпадающими списками не встаёт. */
.filter-note .field {
    margin-left: auto;
}

/* Поле, которое само отбирает строки запросом к серверу — карта в списке
   раундов, — стоит в ряду с выпадающими списками. */
.filter-note .field.inline {
    margin-left: 0;
}

/* У кнопки задан display, и он сильнее атрибута hidden — возвращаем атрибуту
   его смысл: кнопку «Показать» прячет скрипт, когда форма применяется сама. */
.button[hidden] {
    display: none;
}

/* Метка исхода. Цвет несёт тот же смысл, что и слово, и читается раньше него —
   в списке из пятидесяти раундов это решает. */
.outcome {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    background-color: var(--background-default);
    color: var(--color-text-secondary);
    font-size: var(--font-size-smaller);
    white-space: nowrap;
}

.outcome.win {
    background-color: rgb(120 183 87 / 14%);
    color: var(--color-green);
}

.outcome.loss {
    background-color: rgb(236 94 93 / 14%);
    color: var(--color-red);
}

.outcome.large {
    padding: 6px 16px;
    font-size: var(--font-size-default);
}

/* Шапка карточки раунда: название карты слева, исход справа. */
.round-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 18px 20px;
}

.round-head h2 {
    font-size: var(--font-size-large);
}

.round-head .subtitle {
    color: var(--color-text-secondary);
    font-size: var(--font-size-small);
    margin-top: 3px;
}

/* Выпадающие списки в строке фильтров списка раундов. Оформлены под .field,
   но без иконки: у select своя стрелка. */
.select select {
    appearance: none;
    -webkit-appearance: none;
    padding: 7px 30px 7px 12px;
    border-radius: var(--radius-control);
    border: 1px solid var(--input-border);
    background-color: var(--input-background);
    color: var(--color-text-default);
    font-size: var(--font-size-small);
    cursor: pointer;
    /* Стрелка нарисована фоном: системная у select не поддаётся перекраске и
       на тёмной подложке остаётся чёрной. Одной SVG-картинкой, а не двумя
       градиентными половинками: при дробной ширине списка половинки ложились
       на разные пиксели, и треугольник выглядел разрезанным. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'%3E%3Cpath fill='%23999' d='M0 0h10L5 5z'/%3E%3C/svg%3E");
    background-position: right 6px top calc(50% + 1px);
    background-size: 10px 5px;
    background-repeat: no-repeat;
}

.select select:focus {
    outline: none;
    border-color: var(--input-border-focus);
    background-color: var(--input-background-focus);
}

.select select option {
    background-color: var(--background-card);
    color: var(--color-text-default);
}

/* Срез без данных — штатное состояние, а не поломка: почти у каждого есть
   порог выборки, и на узком фильтре его никто не проходит. */
.analytics-empty {
    padding: 28px 20px 32px;
    text-align: center;
}

.analytics-empty p {
    margin: 0;
}

.analytics-empty p + p {
    margin-top: 6px;
    font-size: var(--font-size-small);
}

/* Пояснение под строкой фильтра переносится на свою строку: рядом с коротким
   «Самые трудные карты сверху» оно вытягивало полосу на всю ширину экрана. */
.filter-note .muted {
    flex-basis: 100%;
    font-size: var(--font-size-smaller);
    line-height: 1.5em;
}

/* --------------------------------------------------------------------------
   17. Адаптив
   -------------------------------------------------------------------------- */

@media (max-width: 1200px) {
    :root {
        --font-size-default: 16px;
        --mobile-display-flex: flex;
    }

    /* Семь дат в ряд на телефоне наезжают друг на друга — оставляем каждую
       вторую. Последняя остаётся всегда: правый край оси это «сейчас», и
       без него непонятно, чем график вообще заканчивается. */
    .chart-lines-axis span:nth-child(even):not(:last-child) {
        display: none;
    }

    .layout {
        padding: 0;
        gap: 0;
    }

    .sidebar {
        display: none;
    }

    .topbar {
        display: flex;
    }

    .content {
        max-width: 100%;
        padding: 0 16px 80px;
    }

    .page-head {
        padding: 4px 0 16px;
    }

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

    .card-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Широкие таблицы (рекорды) теряют часть колонок уже здесь: базовый шрифт
       вырос до 16 px, и семь колонок перестают помещаться. */
    .hide-md {
        display: none;
    }
}

/* Порог подобран по фактической ширине таблицы игроков при базовом шрифте
   16 px: ниже него шесть колонок уже не помещаются без прокрутки. */
@media (max-width: 900px) {
    .analytics-overview-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Второстепенные колонки уезжают, их значения показаны строкой под ником. */
    .hide-sm {
        display: none;
    }

    .row-meta {
        display: block;
    }

    table.data th,
    table.data td {
        padding-left: 12px;
        padding-right: 12px;
    }

    table.data td.position {
        padding-right: 0;
    }

    .player .name {
        max-width: 17ch;
    }

    table.data td.map .nowrap {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 17ch;
    }
}

@media (max-width: 640px) {
    .analytics-overview-grid {
        gap: 12px;
        margin-bottom: 12px;
    }

    .content {
        padding: 0 0 80px;
    }

    .page-head {
        padding: 4px 16px 12px;
    }

    .card {
        border-radius: 0;
        border-left: 0;
        border-right: 0;
        margin-bottom: 12px;
    }

    .kpi {
        border-radius: 0;
        border-left: 0;
        border-right: 0;
        grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
        margin-bottom: 12px;
    }

    .outcome-body {
        padding-left: 16px;
        padding-right: 16px;
    }

    table.data.difficulty-summary th,
    table.data.difficulty-summary td {
        padding-left: 7px;
        padding-right: 7px;
    }

    table.data.difficulty-summary th:first-child,
    table.data.difficulty-summary td:first-child {
        padding-left: 16px;
    }

    table.data.difficulty-summary th:last-child,
    table.data.difficulty-summary td:last-child {
        padding-right: 16px;
    }

    .card > .header,
    .card > .body,
    table.data th,
    table.data td,
    .facts th,
    .facts td,
    .breakdown-row,
    .filter-note,
    .pagination {
        padding-left: 16px;
        padding-right: 16px;
    }

    .profile-identity {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }

    .profile-identity .tags {
        justify-content: center;
    }

    .profile-identity h1 {
        justify-content: center;
    }

    .facts th {
        width: 50%;
    }

    /* На телефоне режем пределы ещё сильнее — полное значение остаётся в title. */
    .player .name {
        max-width: 13ch;
    }

    /* В рекордах в строке соседствуют две длинные текстовые колонки —
       название карты и ник, поэтому обеим нужен более жёсткий предел. */
    table[data-records] td.map .nowrap,
    table[data-records] .player .name {
        max-width: 10ch;
    }

    .activity {
        padding: 4px 16px 16px;
    }

    /* На узком экране остаются подписи каждого шестого часа. */
    .heat-hours .heat-cell:not(:nth-child(6n + 1)) .heat-label {
        visibility: hidden;
    }

    .heat-days .heat-text {
        display: none;
    }

    .awards {
        justify-content: center;
    }
}

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