/* Портал статистики клубов — единственный CSS-файл проекта.
 *
 * Слой токенов скопирован из артбордов Claude Design дословно: имена те же,
 * поэтому разметка артборда переезжает в Jinja как есть. Тёмная палитра —
 * из инлайнового <style> артбордов, светлая — из оверрайдов на контейнерах
 * в «Портал PUDRA.dc.html». Артборды лежат в design/v1/.
 *
 * Цвет объявляется здесь и нигде больше. В разметке — только var().
 */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');

/* ── Тёмная тема — дефолт, в ней нарисованы все артборды ──────────────── */
:root {
  --color-bg: #161826;
  --color-surface: #232532;
  --color-text: #e9e9ed;
  --color-accent: #9184d9;
  --color-divider: rgba(233, 233, 237, 0.16);

  --muted: #9397ab;
  --faint: #75798c;
  --line: rgba(233, 233, 237, 0.13);
  --line-strong: rgba(233, 233, 237, 0.26);
  --grid: rgba(233, 233, 237, 0.07);
  --mid: #75798c;
  --mark: #b2b6ca;
  --chip: #3f424d;
  --track: rgba(233, 233, 237, 0.07);
  --bar: #595d6c;
  --bar-strong: #75798c;
  --tooltip: #2b2d3b;

  /* Расходящаяся шкала win-rate с серединой в 50% (§9). Не «чем больше, тем
     зеленее» и не красно-чёрная: канонические цвета команд в интерфейсе не
     используются вообще, иначе они сталкиваются с исходом. Различима при
     дейтеранопии и протанопии. */
  --hi: oklch(0.74 0.13 289);
  --hi-dim: oklch(0.74 0.13 289 / 0.2);
  --lo: oklch(0.74 0.12 62);
  --lo-dim: oklch(0.74 0.12 62 / 0.2);

  --shadow-sm: 0 0 0 1px #3f424d;
  --shadow-md: 0 0 0 1px #595d6c, 0 6px 18px rgba(0, 0, 0, 0.55);
  --shadow-lg: 0 0 0 1px #9397ab, 0 16px 40px rgba(0, 0, 0, 0.65);

  --font-body: 'Inter', system-ui, sans-serif;
  --font-heading: 'Inter', system-ui, sans-serif;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;
}

/* Светлая палитра объявлена дважды: под системную настройку и под явный
   выбор. Шага сборки нет, вынести общий блок нечем — расхождение ловит
   tests/test_design/test_tokens.py. Правя одну копию, правь обе. */

/* ── Светлая тема по системной настройке ─────────────────────────────── */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --color-bg: #eceef7;
    --color-surface: #f9fafd;
    --color-text: #252735;
    --color-accent: #6a5eb8;
    --color-divider: rgba(37, 39, 53, 0.13);

    --muted: #5f6377;
    --faint: #6f7385;
    --line: rgba(37, 39, 53, 0.13);
    --line-strong: rgba(37, 39, 53, 0.24);
    --grid: rgba(37, 39, 53, 0.09);
    --mid: #6f7385;
    --mark: #5f6377;
    --chip: #e0e3ef;
    --track: rgba(37, 39, 53, 0.07);
    --bar: #b2b6ca;
    --bar-strong: #9397ab;
    --tooltip: #ffffff;

    --hi: oklch(0.5 0.14 289);
    --hi-dim: oklch(0.5 0.14 289 / 0.13);
    --lo: oklch(0.52 0.13 62);
    --lo-dim: oklch(0.52 0.13 62 / 0.13);

    --shadow-sm: 0 0 0 1px rgba(37, 39, 53, 0.08);
    --shadow-md: 0 0 0 1px rgba(37, 39, 53, 0.08), 0 6px 18px rgba(37, 39, 53, 0.1);
    /* В канве не переопределён — портальные страницы им не пользуются.
       Выведен по образцу двух предыдущих. */
    --shadow-lg: 0 0 0 1px rgba(37, 39, 53, 0.14), 0 16px 40px rgba(37, 39, 53, 0.16);

    --font-body: 'Inter', system-ui, sans-serif;
    --font-heading: 'Inter', system-ui, sans-serif;

    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 14px;
  }
}

/* ── Светлая тема по явному выбору ───────────────────────────────────── */
:root[data-theme="light"] {
  --color-bg: #eceef7;
  --color-surface: #f9fafd;
  --color-text: #252735;
  --color-accent: #6a5eb8;
  --color-divider: rgba(37, 39, 53, 0.13);

  --muted: #5f6377;
  --faint: #6f7385;
  --line: rgba(37, 39, 53, 0.13);
  --line-strong: rgba(37, 39, 53, 0.24);
  --grid: rgba(37, 39, 53, 0.09);
  --mid: #6f7385;
  --mark: #5f6377;
  --chip: #e0e3ef;
  --track: rgba(37, 39, 53, 0.07);
  --bar: #b2b6ca;
  --bar-strong: #9397ab;
  --tooltip: #ffffff;

  --hi: oklch(0.5 0.14 289);
  --hi-dim: oklch(0.5 0.14 289 / 0.13);
  --lo: oklch(0.52 0.13 62);
  --lo-dim: oklch(0.52 0.13 62 / 0.13);

  --shadow-sm: 0 0 0 1px rgba(37, 39, 53, 0.08);
  --shadow-md: 0 0 0 1px rgba(37, 39, 53, 0.08), 0 6px 18px rgba(37, 39, 53, 0.1);
  --shadow-lg: 0 0 0 1px rgba(37, 39, 53, 0.14), 0 16px 40px rgba(37, 39, 53, 0.16);

  --font-body: 'Inter', system-ui, sans-serif;
  --font-heading: 'Inter', system-ui, sans-serif;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;
}

/* ── База ─────────────────────────────────────────────────────────────── */

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--color-accent);
  text-decoration: none;
}

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

h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  margin: 0;
}

h1 {
  font-size: 38px;
  letter-spacing: -0.025em;
}

img {
  max-width: 100%;
}

/* ── Каркас страницы ──────────────────────────────────────────────────── */

.site-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 32px;
  height: 56px;
  border-bottom: 1px solid var(--line);
}

/* Логотип — две строки: имя портала и то, чем он занимается. Высота шапки
   не меняется: 15 + 11 пикселей с плотным лидингом умещаются в 56. */
.site-header__brand {
  display: flex;
  flex-direction: column;
  gap: 1px;
  color: inherit;
  text-decoration: none;
  line-height: 1.15;
}
.site-header__title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.site-header__tagline { font-size: 11px; color: var(--faint); }
.site-header__brand:hover .site-header__title { color: var(--color-accent); }

/* Навигация по разделам. Тем же приёмом, что вкладки клуба, только тоньше:
   шапка низкая, и подчёркивание в ней читалось бы как вторая линия рамки. */
.site-nav { display: flex; align-items: center; gap: 18px; margin-left: 12px; }
.site-nav__item { font-size: 13px; color: var(--muted); text-decoration: none; }
.site-nav__item:hover { color: var(--color-text); }
.site-nav__item--on { color: var(--color-text); font-weight: 500; }

.site-header__meta {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 12px;
  color: var(--faint);
}

.site-main {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 36px 32px 64px;
}

.site-footer {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 24px 32px 40px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--faint);
}
.site-footer__line { flex: 1; min-width: 260px; }
/* Кнопка донат-сервиса — его же картинка, поэтому своей рамки у неё нет. */
.donate { display: inline-flex; line-height: 0; }
.donate__logo { height: 34px; width: auto; border-radius: 6px; }

.page-lede {
  font-size: 14px;
  color: var(--muted);
}

.empty-state {
  padding: 48px 24px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  text-align: center;
  color: var(--muted);
}

/* ── Переключатель темы ───────────────────────────────────────────────── */

.theme-switch {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: 12px;
}

.theme-switch__option {
  padding: 5px 10px;
  background: none;
  border: 0;
  border-left: 1px solid var(--line);
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}

.theme-switch__option:first-child {
  border-left: 0;
}

.theme-switch__option[aria-pressed="true"] {
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

/* Без cookie обе кнопки честно приходят с aria-pressed="false" — выбора и
   правда не было, это не баг доступности. Но какая тема действует, видеть
   всё равно надо, а решает это prefers-color-scheme, а не aria-pressed:
   светлая тема применяется через :root:not([data-theme]) внутри медиазапроса
   (см. блок выше), тёмная — тот же селектор без него, дефолт. Подсвечиваем
   по тому же принципу, без JS. */
:root:not([data-theme]) .theme-switch__option:nth-child(2) {
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .theme-switch__option:first-child {
    color: var(--color-accent);
    box-shadow: inset 0 0 0 1px var(--color-accent);
  }

  :root:not([data-theme]) .theme-switch__option:nth-child(2) {
    color: var(--muted);
    box-shadow: none;
  }
}

/* Переключатель языка — та же форма-без-JS и та же геометрия, что у темы:
   две кнопки в одной рамке. Отдельные классы, а не .theme-switch на двоих:
   выбранный язык подсвечивается только по aria-pressed, потому что выбор
   тут всегда сделан — кука либо есть, либо действует русский дефолт, и
   ветки «решает браузер», ради которой у темы живёт медиазапрос, здесь нет. */
.lang-switch {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: 12px;
}

.lang-switch__option {
  padding: 5px 10px;
  background: none;
  border: 0;
  border-left: 1px solid var(--line);
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}

.lang-switch__option:first-child {
  border-left: 0;
}

.lang-switch__option[aria-pressed="true"] {
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

@media (max-width: 640px) {
  /* Три пункта навигации в 56 пикселей высоты рядом с логотипом и двумя
     переключателями не помещаются — на телефоне они уезжают своей строкой
     под шапку. */
  .site-header {
    height: auto;
    padding: 10px 16px;
    flex-wrap: wrap;
  }

  .site-nav {
    order: 3;
    width: 100%;
    margin-left: 0;
    gap: 16px;
  }

  .site-main {
    padding: 24px 16px 48px;
  }

  .site-footer {
    padding: 20px 16px 32px;
  }

  h1 {
    font-size: 28px;
  }
}

/* ── каркас ─────────────────────────────────────────────────────────── */
body {
  color: var(--color-text);
  font-family: Inter, system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

.site-main { padding: 0 32px 44px; }
.card { background: var(--color-surface); border-radius: 8px; }

/* ── метки ролей: форма, а не цвет (§9) ─────────────────────────────── */
.role-mark {
  width: 11px;
  height: 11px;
  flex: none;
  box-sizing: border-box;
  display: inline-grid;
  place-items: center;
}
.role-mark--red,
.role-mark--sheriff { border-radius: 50%; border: 1.5px solid var(--mark); }
.role-mark--black,
.role-mark--don { border-radius: 3px; background: var(--mark); }
.role-mark--sheriff::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--mark);
}
.role-mark--don::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 1px;
  background: var(--color-surface);
}

/* ── игрок ──────────────────────────────────────────────────────────── */
.player { display: flex; align-items: center; gap: 10px; min-width: 0; }
.player__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.player__name { color: inherit; text-decoration: none; }
a.player__name:hover { color: var(--color-accent); }

/* Метка домашнего клуба — только на федеральных таблицах, где клубов на
   экране много. Отдельной строкой под ником: .player — флекс-контейнер, и в
   узкой колонке метка сбоку съела бы сам ник. */
.player__club {
  display: block;
  margin-top: 1px;
  font-size: 11px;
  color: var(--faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.avatar { flex: none; border-radius: 50%; object-fit: cover; }
.avatar--md { width: 28px; height: 28px; }
.avatar--sm { width: 24px; height: 24px; }
.avatar--empty {
  background:
    repeating-linear-gradient(135deg, var(--track) 0 4px, transparent 4px 8px),
    var(--color-bg);
}

.guest-mark {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--faint);
  color: var(--faint);
  font-size: 9px;
  line-height: 1;
  cursor: help;
}
/* Своя подсказка, а не title: нативная всплывает через секунду, на телефоне
   не всплывает вовсе, а знак «?» без объяснения — ровно та загадка, ради
   которой он и поставлен. */
.guest-mark__tip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  width: max-content;
  max-width: 240px;
  padding: 8px 10px;
  background: var(--tooltip);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  color: var(--color-text);
  font-size: 12px;
  line-height: 1.35;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 120ms ease;
}
.guest-mark:hover .guest-mark__tip,
.guest-mark:focus-visible .guest-mark__tip,
.guest-mark--open .guest-mark__tip { opacity: 1; visibility: visible; }
/* Ник и сноска — одной строкой. Знак ставится в колоночных флексах и в
   ячейках гридов, где голым соседом он уезжал бы под ник отдельным рядом;
   обрезки на обёртке нет — она срезала бы подсказку. Многоточие остаётся
   на самом нике, поэтому длинный ник жмётся, а знак стоит на месте. */
.name-line { display: flex; align-items: center; gap: 6px; min-width: 0; }

/* ── расходящаяся шкала win-rate (§9) ───────────────────────────────── */
.winrate { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.winrate__track {
  position: relative;
  width: 70px;
  height: 8px;
  border-radius: 2px;
  background: var(--track);
}
.winrate__mid {
  position: absolute;
  left: 50%;
  top: -3px;
  bottom: -3px;
  width: 1px;
  background: var(--mid);
}
.winrate__fill { position: absolute; top: 0; bottom: 0; }
.winrate__fill--low { right: 50%; background: var(--lo); border-radius: 2px 0 0 2px; }
.winrate__fill--high { left: 50%; background: var(--hi); border-radius: 0 2px 2px 0; }
.winrate__value { min-width: 30px; text-align: right; color: var(--muted); }
.winrate__value--low { color: var(--lo); }
.winrate__value--high { color: var(--hi); }

/* ── доля с выборкой: процент никогда не стоит один (§6) ────────────── */
.rate { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.rate__value--low { color: var(--lo); }
.rate__value--high { color: var(--hi); }
.rate__value--empty { color: var(--faint); }
.rate__sample { font-size: 11px; color: var(--faint); }

/* ── таблицы ────────────────────────────────────────────────────────── */
/* Скруглённые углы держатся на самих крайних строках, а не на overflow у
   таблицы: обрезка резала бы подсказку «?» на первой и последней строке. */
.table__head { border-radius: var(--radius-md) var(--radius-md) 0 0; }
.table__row:last-child { border-radius: 0 0 var(--radius-md) var(--radius-md); }
.table__head,
.table__row { display: grid; gap: 12px; align-items: center; padding: 11px 20px; }
.table__head {
  padding: 10px 20px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  border-bottom: 1px solid var(--line);
}
.table__row { border-bottom: 1px solid var(--line); color: inherit; text-decoration: none; }
.table__row:last-child { border-bottom: 0; }
.table__row:hover { background: var(--track); }
.table__num { text-align: right; font-variant-numeric: tabular-nums; }
.table__muted { color: var(--muted); }

/* ── чипы фильтров ──────────────────────────────────────────────────── */
.chips {
  display: inline-flex;
  /* Города в списке фильтра не помещаются в одну строку почти нигде —
     без переноса хвост списка просто обрезался бы за краем экрана. */
  flex-wrap: wrap;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  font-size: 13px;
}
.chips__item {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  color: var(--muted);
  text-decoration: none;
  border-left: 1px solid var(--line);
}
.chips__item:first-child { border-left: 0; }
.chips__item:hover { color: var(--color-text); }
.chips__item--on { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }

/* ── пагинация ──────────────────────────────────────────────────────── */
.pager { display: flex; align-items: center; gap: 14px; font-size: 13px; }
.pager__list { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.pager__item {
  display: inline-grid;
  place-items: center;
  min-width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--line);
  color: var(--color-text);
  text-decoration: none;
}
.pager__item--on {
  border-color: transparent;
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}
.pager__item--off { color: var(--faint); }
.pager__gap { padding: 0 4px; color: var(--faint); }

/* ── пустые состояния ───────────────────────────────────────────────── */
.empty-state {
  padding: 36px 20px;
  text-align: center;
  color: var(--muted);
}
.empty-state__title { color: var(--color-text); font-size: 16px; margin-bottom: 6px; }
/* Код ошибки крупно и приглушённо: он для того, кто пришёл разбираться, а не
   для того, кто просто промахнулся ссылкой. */
.empty-state__code {
  font-size: 44px;
  line-height: 1;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}
.empty-state__actions { margin-top: 16px; }

@media (max-width: 760px) {
  .site-main { padding: 0 16px 32px; }
}

/* ── главная ────────────────────────────────────────────────────────── */
.index { display: flex; flex-direction: column; gap: 10px; padding-top: 28px; }
.index__title { margin: 0; font-size: 28px; letter-spacing: -0.02em; }
.index__lead { margin: 0; color: var(--muted); }
.index__totals { margin: 0 0 10px; font-size: 13px; color: var(--faint); }
.index__grid { display: grid; gap: 12px; }

.club-card {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 18px;
  align-items: center;
  padding: 18px 22px;
  color: inherit;
  text-decoration: none;
  border: 1px solid transparent;
}
.club-card:hover { border-color: var(--line-strong); }
.club-card__logo { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; }
.club-card__logo--empty {
  background:
    repeating-linear-gradient(135deg, var(--track) 0 4px, transparent 4px 8px),
    var(--color-bg);
}
.club-card__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.club-card__name { font-size: 19px; }
.club-card__where { font-size: 13px; color: var(--muted); }
.club-card__stats { display: flex; gap: 28px; }

.stat { display: flex; flex-direction: column; gap: 2px; }
.stat__label {
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}
.stat__value { font-size: 24px; font-weight: 500; letter-spacing: -0.02em; }
.stat__value--small { font-size: 14px; font-weight: 400; }
.stat__value--muted { color: var(--muted); }
.dot { color: var(--faint); }

@media (max-width: 760px) {
  .club-card { grid-template-columns: 44px 1fr; }
  .club-card__logo { width: 44px; height: 44px; }
  .club-card__stats { grid-column: 1 / -1; gap: 20px; }
  .stat__value { font-size: 19px; }
}

/* ── шапка клуба ────────────────────────────────────────────────────── */
.sync-stamp { font-size: 12px; color: var(--faint); }
/* Последняя строка контента, встык к футеру: та же кегль и тот же цвет, что
   у него, поэтому выравнивание тоже по левому краю — иначе она читалась бы
   отдельным элементом, а не концовкой страницы. */
.club__sync { margin-top: -8px; }

.club { display: flex; flex-direction: column; gap: 22px; padding-top: 28px; }
/* Федеральные страницы (/rating, /players) — та же форма «шапка + блоки
   секций», что у клубной, только без шапки клуба. */
.federation { display: flex; flex-direction: column; gap: 22px; padding-top: 28px; }
.club__head { display: flex; align-items: flex-start; gap: 20px; }
.club__logo { width: 72px; height: 72px; border-radius: 8px; object-fit: cover; flex: none; }
.club__logo--empty {
  background:
    repeating-linear-gradient(135deg, var(--track) 0 4px, transparent 4px 8px),
    var(--color-bg);
}
.club__ident { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.club__name { margin: 0; font-size: 32px; letter-spacing: -0.02em; }
.club__where { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--muted); }
/* flex-wrap: с четвёртой ссылкой (mafgame.org, она есть всегда) пилюли на
   узком экране перестают помещаться в одну строку — без переноса хвост
   обрезался бы точно так же, как раньше обрезались чипы городов. */
.club__socials { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 2px; }

.pill {
  font-size: 12px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--color-text);
  text-decoration: none;
}
.pill:hover { border-color: var(--line-strong); }

.club__summary { margin-left: auto; display: flex; align-items: stretch; gap: 28px; }
.stat--wide { width: 250px; gap: 5px; }
.stat__note { font-size: 12px; color: var(--muted); }

.balance { display: flex; height: 10px; border-radius: 3px; overflow: hidden; gap: 2px; }
.balance__red { background: var(--bar); }
.balance__black { background: var(--bar-strong); }
.balance__legend {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--muted);
}
.balance__legend span { display: inline-flex; align-items: center; gap: 6px; }

.tabs { display: flex; align-items: center; gap: 28px; border-bottom: 1px solid var(--line); }
.tabs__item { padding: 10px 0; font-size: 15px; color: var(--muted); text-decoration: none; }
.tabs__item:hover { color: var(--color-text); }
.tabs__item--on { color: var(--color-text); box-shadow: inset 0 -2px 0 var(--color-accent); }

.club__tab { display: flex; flex-direction: column; gap: 20px; }

.filters { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.filters__label { font-size: 12px; color: var(--faint); }

.months { position: relative; font-size: 13px; }
.months__summary { cursor: pointer; color: var(--muted); list-style: none; }
.months__list {
  position: absolute;
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-width: 160px;
  padding: 6px;
  background: var(--tooltip);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
}
.months__item { padding: 6px 10px; border-radius: 6px; color: var(--muted); text-decoration: none; }
.months__item:hover { background: var(--track); color: var(--color-text); }
.months__item--on { color: var(--color-accent); }

/* Рейтинг за один игровой вечер: календарь месяца в попапе рядом с «Месяц». */
.calendar { position: relative; font-size: 13px; }
.calendar__summary { cursor: pointer; color: var(--muted); list-style: none; }
.calendar__grid {
  position: absolute;
  right: 0;
  z-index: 2;
  width: 224px;
  padding: 10px;
  background: var(--tooltip);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
}
.calendar__nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.calendar__month {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text);
  text-align: center;
  text-transform: capitalize;
}
.calendar__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  color: var(--muted);
  text-decoration: none;
}
.calendar__arrow:hover { background: var(--track); color: var(--color-text); }
.calendar__arrow--off { color: var(--faint); visibility: hidden; }
.calendar__weekdays, .calendar__week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.calendar__weekdays { margin-bottom: 4px; font-size: 11px; color: var(--faint); text-align: center; }
.calendar__day {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--muted);
}
.calendar__day--off { color: var(--faint); }
.calendar__day--game { color: var(--color-text); }
.calendar__day--game:hover { background: var(--track); }
.calendar__day--on { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }

.section-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.section-head__title { margin: 0; font-size: 19px; }
.section-head__note { font-size: 13px; color: var(--muted); }

@media (max-width: 760px) {
  .club__head { flex-wrap: wrap; gap: 14px; }
  .club__name { font-size: 24px; }
  .club__summary { margin-left: 0; width: 100%; flex-wrap: wrap; gap: 18px; }
  .stat--wide { width: 100%; }
  .tabs { gap: 18px; overflow-x: auto; }
  .filters { margin-left: 0; width: 100%; flex-wrap: wrap; }
  /* .months__list — right:0, рассчитано на десктоп, где «Месяц» стоит у
     правого края строки (.filters с margin-left:auto). На телефоне
     .filters переносится и «Месяц» уезжает к левому краю — попап от
     right:0 растёт влево и вылезает за экран, видны только хвосты подписей.
     Якорим от левого края вместо правого. */
  .months__list { right: auto; left: 0; }
  .calendar__grid { right: auto; left: 0; }
}

/* ── вкладка «Игроки» ───────────────────────────────────────────────── */
.search {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 12px;
  width: 230px;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--faint);
}
.search__icon { flex: none; }
.search__input {
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: 13px;
  width: 100%;
}

.sorter { color: inherit; text-decoration: none; }
.sorter:hover { color: var(--color-text); }
.sorter--on { color: var(--color-accent); }

.players__row {
  grid-template-columns: 1fr 52px 118px 92px 92px 92px 92px 44px 78px 66px 100px;
}
/* Обёртки существуют ради телефона: на десктопе они растворяются и их ячейки
   встают прямо в сетку строки. */
.players__meta,
.players__roles { display: contents; }
.players__role-label,
.players__meta-label { display: none; }

/* Растворённые обёртки отдают ячейки в порядке DOM — а он группирует «Игр,
   ПУ, ЛХ» рядом ради мобильной раскладки. Порядок колонок с артборда
   (Игрок · Игр · Win-rate · роли · ПУ · ЛХ · Баллы · Последняя) поэтому
   задаётся явно: иначе шапка таблицы разъезжается с её телом. */
/* grid-row обязателен вместе с grid-column: автораскладка не умеет ходить
   назад, и ячейка с меньшим номером колонки уехала бы на вторую строку. */
.players__row > *,
.players__meta > *,
.players__roles > * { grid-row: 1; }
.players__who { grid-column: 1; }
.players__games { grid-column: 2; }
.players__wr { grid-column: 3; }
.players__role[data-role="red"] { grid-column: 4; }
.players__role[data-role="don"] { grid-column: 5; }
.players__role[data-role="sheriff"] { grid-column: 6; }
.players__role[data-role="black"] { grid-column: 7; }
.players__pu { grid-column: 8; }
.players__bm { grid-column: 9; }
.players__points { grid-column: 10; }
.players__last { grid-column: 11; }

.suggest { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.suggest__label { color: var(--faint); }
.suggest__item { color: var(--color-accent); text-decoration: none; }
.suggest__count { color: var(--faint); font-size: 12px; margin-left: 4px; }

@media (max-width: 760px) {
  .players__head { display: none; }
  .players__row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "who    points"
      "meta   last"
      "wr     wr"
      "roles  roles";
    row-gap: 8px;
    padding: 14px 16px;
  }
  .players__who { grid-area: who; }
  .players__points { grid-area: points; font-size: 16px; }
  .players__last { grid-area: last; }
  .players__wr { grid-area: wr; }
  /* Флекс-контейнер здесь .winrate, а не ячейка: на самой ячейке
     justify-content ничего не делает, и шкала осталась бы справа. */
  .players__wr .winrate { justify-content: flex-start; }
  /* .winrate__track — 70px фиксировано, под колонку в десктопной таблице.
     На телефоне у шкалы вся ширина строки (grid-area "wr wr" во всю карту,
     см. .players__row выше) — растягиваем, а не оставляем место пустым. */
  .players__wr .winrate__track { flex: 1; width: auto; }

  .players__meta {
    grid-area: meta;
    display: flex;
    gap: 10px;
    font-size: 12px;
    color: var(--muted);
  }
  .players__meta .rate { flex-direction: row; gap: 4px; align-items: baseline; }
  .players__meta-label {
    display: inline;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--faint);
    margin-right: 3px;
  }

  .players__roles {
    grid-area: roles;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
  }
  .players__role { display: flex; flex-direction: column; gap: 2px; }
  /* Селектор с атрибутом — чтобы перебить десктопные .players__role[data-role]:
     иначе роли остаются в колонках 4–7 и сетка расползается до семи. */
  .players__role[data-role] { grid-column: auto; }
  .players__role-label {
    display: block;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--faint);
  }
  .players__role .rate { align-items: flex-start; }
  .search { width: 100%; margin-left: 0; }
}

/* ── вкладка «Рейтинг» ──────────────────────────────────────────────── */
.rating__row {
  grid-template-columns: 60px 1fr 56px 66px 118px 74px 74px 82px 46px 82px 82px;
}
/* Мобильный дубль имени+аватарки и готовые текстовые строки (§ ниже) — на
   десктопе у тех же чисел уже есть отдельные колонки со своим заголовком, а
   аватарка — внутри .rating__who рядом с именем. */
.rating__identity, .rating__money { display: none; }
.rating__place { color: var(--muted); }
.note { margin: 0; font-size: 13px; color: var(--muted); max-width: 720px; }

.nominations, .leaders { display: flex; flex-direction: column; gap: 14px; padding-top: 8px; }
/* Номинаций пять — четыре ролевых плюс MVP; десяток по ролям по-прежнему
   четыре, и сетки разъезжаются. */
.nominations__grid, .leaders__grid { display: grid; gap: 12px; }
.nominations__grid { grid-template-columns: repeat(5, 1fr); }
.leaders__grid { grid-template-columns: repeat(4, 1fr); }

.nomination { display: flex; flex-direction: column; gap: 6px; padding: 16px 18px; }
.nomination__title { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.nomination__who { font-size: 19px; color: inherit; text-decoration: none; }
.nomination__who:hover { color: var(--color-accent); }
.nomination__rate { display: flex; align-items: baseline; gap: 8px; }
.nomination__percent { font-size: 22px; color: var(--hi); letter-spacing: -0.02em; }
.nomination__empty { color: var(--faint); }
/* Опущенный порог — оговорка к числу над ней, поэтому она тише числа, но
   всё же читается: без неё «100% (3/3)» выглядит как ошибка. */
.nomination__note { color: var(--faint); font-size: 12px; line-height: 1.35; }
/* MVP — клубная награда, а не пятая роль: отделяем её акцентной кромкой,
   чтобы не читалась как ещё одна строка того же списка. */
.nomination--mvp { box-shadow: inset 2px 0 0 var(--color-accent); }
.nomination--mvp .nomination__title { color: var(--color-accent); }

.leaders__column { display: flex; flex-direction: column; padding: 14px 16px; gap: 2px; }
.leaders__title { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.leaders__row {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 5px 0;
  color: inherit;
  text-decoration: none;
}
.leaders__row:hover { color: var(--color-accent); }
.leaders__place { color: var(--faint); font-size: 12px; }
.leaders__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leaders__empty { color: var(--faint); font-size: 13px; }
.leaders__threshold { margin-left: auto; color: var(--faint); font-size: 12px; }

@media (max-width: 760px) {
  /* Таблица на телефоне не таблица: общий заголовок колонок не совпадает
     шириной с самими колонками и только путает (§ багрепорт). Карточка
     профиля вместо строки таблицы: слева имя и «игр · побед» одной строкой
     под ним, справа баллы, допы/штраф и win-rate — три строки одна под
     другой. .rating__meta и .rating__money — готовый текст на замену
     колонкам-числам (см. разметку), а не их визуальное перекладывание. */
  .table__head.rating__row { display: none; }
  .rating__row {
    grid-template-columns: 22px 1fr auto;
    grid-template-areas:
      "place identity points"
      "place identity money"
      "place identity wr";
    row-gap: 3px;
    column-gap: 10px;
    padding: 12px;
  }
  .rating__place { grid-area: place; font-size: 15px; }
  /* .rating__who (десктопная колонка с именем и аватаркой рядом в одну
     строку) на телефоне не нужна — идентичность игрока рисует identity
     ниже, с другой раскладкой (аватарка + две строки текста). */
  .rating__who { display: none; }
  /* identity растянута на все три строки карточки (area повторён трижды) и
     центруется как единый блок — как «место» слева и «баллы/win-rate»
     справа. Раньше аватарка+имя+«N игр · N побед» занимали только свои две
     строки и потому сидели вровень с верхом карточки, а не по её середине. */
  .rating__identity {
    display: flex;
    grid-area: identity;
    align-items: center;
    gap: 10px;
    min-width: 0;
  }
  .rating__identity__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .rating__meta { font-size: 12px; color: var(--muted); }
  .rating__points { grid-area: points; font-size: 17px; }
  .rating__money {
    display: block;
    grid-area: money;
    text-align: right;
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
  }
  .rating__wr { grid-area: wr; justify-self: end; }
  /* Серая шкала на 220px строк выглядит частоколом одинаковых чёрточек —
     число яснее её на этой ширине. Сама шкала остаётся на десктопе и в
     карточке роли игрока, там ширины хватает, чтобы её отклонение от
     середины что-то говорило. */
  .rating__wr .winrate__track { display: none; }
  .rating__wr .winrate__value { font-size: 13px; }
  /* Десктопные колонки-числа под общим заголовком на телефоне не нужны —
     их текстовые дубли выше (.rating__meta, .rating__money) уже сказали то
     же самое человеку, а не таблице. ПУ и средний ЛХ живут на карточке
     игрока — там же для них есть место без ужатия в одну строку. */
  .rating__games, .rating__wins, .rating__bonus, .rating__penalty,
  .rating__pu, .rating__bm, .rating__avg_bonus { display: none; }
  .nominations__grid { grid-template-columns: 1fr 1fr; }
  /* Четыре десятки по ролям в две колонки на 390px — это восемь узких
     карточек, где ник обрезается («new_kate...»). В одну колонку каждая
     десятка получает всю ширину экрана. */
  .leaders__grid { grid-template-columns: 1fr; }
  /* На телефоне пятая карточка осталась бы сиротой в половину ряда. */
  .nomination--mvp { grid-column: 1 / -1; }
}

/* ── вкладка «Игры» ─────────────────────────────────────────────────── */
.games__row { grid-template-columns: 96px 150px 190px 170px 1fr 34px; gap: 16px; padding: 14px 20px; }
.games__row--on { background: var(--track); }
.games__number { font-size: 15px; }
.games__outcome { display: inline-flex; align-items: center; gap: 9px; }
.games__faces { display: flex; align-items: center; }
.games__faces .avatar { box-shadow: 0 0 0 2px var(--color-surface); }
.games__faces .avatar + .avatar { margin-left: -9px; }
.games__more { margin-left: 10px; font-size: 13px; color: var(--muted); }
.games__chevron { color: var(--faint); text-align: right; }
.games__broadcast { margin-left: 6px; color: var(--muted); font-size: 11px; }

.game-card {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 28px;
  padding: 20px;
  background: var(--color-bg);
  border-bottom: 1px solid var(--line);
}
.game-card__row {
  display: grid;
  grid-template-columns: 44px 1fr 132px 56px 62px 66px 72px 66px;
  gap: 12px;
  align-items: center;
  padding: 9px 14px;
}
.game-card__head {
  padding: 0 14px 8px;
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}
.game-card__seat { background: var(--color-surface); border-top: 1px solid var(--color-bg); }
.game-card__seat:first-of-type { border-top: 0; border-radius: 6px 6px 0 0; }
.game-card__seat:last-of-type { border-radius: 0 0 6px 6px; }
.game-card__role { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.game-card__center { justify-self: center; }
.game-card__faded { color: var(--faint); }
.game-card__side { display: flex; flex-direction: column; gap: 14px; }
.game-card__fact { display: flex; flex-direction: column; gap: 3px; }

.badge {
  display: inline-flex;
  padding: 1px 8px;
  border-radius: 5px;
  border: 1px solid var(--line-strong);
  font-size: 11px;
  letter-spacing: 0.04em;
}

/* ── вкладка «Трансляции» ──────────────────────────────────────────── */
.broadcasts { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.broadcast-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
}
.broadcast-card:hover { border-color: var(--line-strong); }
.broadcast-card__thumb { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--track); }
.broadcast-card__body { display: flex; flex-direction: column; gap: 4px; padding: 10px 14px; }
.broadcast-card__date { font-size: 12px; color: var(--muted); }
.broadcast-card__title { font-size: 14px; }

@media (max-width: 760px) {
  .games__row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "num date" "outcome chevron" "referee referee" "faces faces";
    row-gap: 6px;
  }
  .games__row > :nth-child(1) { grid-area: num; }
  .games__row > :nth-child(2) { grid-area: date; text-align: right; }
  .games__row > :nth-child(3) { grid-area: outcome; }
  .games__row > :nth-child(4) { grid-area: referee; }
  .games__row > :nth-child(5) { grid-area: faces; }
  .games__row > :nth-child(6) { grid-area: chevron; }

  .game-card { grid-template-columns: 1fr; gap: 16px; padding: 14px; }
  /* На телефоне остаются место, игрок, ПУ, ЛХ и баллы: роль читается меткой
     у имени, а доп со штрафом появляются, только если судья их выставил —
     на артборде так же. Колонок ровно столько, сколько видимых ячеек:
     шестая колонка на четырёх ячейках переносила бы баллы на вторую строку. */
  .game-card__row { grid-template-columns: 40px 1fr auto auto 56px; gap: 8px; }
  .game-card__row > :nth-child(3),
  .game-card__row > :nth-child(6),
  .game-card__row > :nth-child(8) { display: none; }
}

/* ── вкладка «Судьи» ────────────────────────────────────────────────── */
.referees__row { grid-template-columns: 1fr 180px 70px 130px 140px 100px; }
/* Настоящее имя стоит справа от ника, а не под ним: .player — флексбокс и
   занимает всю строку ячейки, поэтому соседний span без этой обёртки
   переносился бы вниз и читался как отдельный судья. */
.referees__who { display: flex; align-items: center; gap: 6px; min-width: 0; }
.referees__real {
  color: var(--faint);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Суффикс к числу — только для мобильной карточки, где заголовка колонки
   нет (см. мобильный блок). На десктопе то же число под заголовком уже
   понятно и без слова. */
.referees__unit { display: none; }

@media (max-width: 760px) {
  /* Общий заголовок колонок на телефоне не совпадает шириной с самими
     колонками (см. багрепорт по рейтингу) — прячем его целиком, а не
     подгоняем. Раскладка на классах, а не на :nth-child: с ним появление
     колонки в таблице молча перекладывает телефон. */
  .table__head.referees__row { display: none; }
  .referees__row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "who games" "level share" "bonus bonus";
    row-gap: 4px;
  }
  .referees__who { grid-area: who; }
  .referees__level { grid-area: level; }
  .referees__games { grid-area: games; }
  .referees__share { grid-area: share; }
  .referees__last { display: none; }
  .referees__unit { display: inline; font-size: 11px; color: var(--faint); }
  /* Средний доп на телефоне ложится строкой и читается слева направо, а не
     столбиком в правом краю. */
  .referees__bonus { grid-area: bonus; text-align: left; }
  .referees__bonus .rate { flex-direction: row; gap: 6px; align-items: baseline; }
}

/* ── индикатор загрузки и сетевая ошибка ────────────────────────────── */
.progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 10;
  opacity: 0;
  transition: opacity 120ms ease;
  pointer-events: none;
}
.progress span {
  display: block;
  height: 100%;
  width: 40%;
  background: var(--color-accent);
  animation: progress-slide 900ms linear infinite;
}
/* .htmx-indicator включается самим HTMX на время запроса. */
.htmx-indicator.htmx-request { opacity: 1; }

@keyframes progress-slide {
  from { transform: translateX(-100%); }
  to { transform: translateX(250%); }
}

@media (prefers-reduced-motion: reduce) {
  .progress span { animation: none; width: 100%; }
}

.net-error {
  margin: 12px 32px 0;
  padding: 12px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 13px;
}

/* HTMX помечает уходящий блок — притушим его, чтобы подмена не мигала. */
.htmx-swapping { opacity: 0.6; transition: opacity 90ms ease; }

/* ── карточка игрока ────────────────────────────────────────────────── */
.player-page { display: flex; flex-direction: column; gap: 18px; padding-top: 22px; }

/* Отступ снизу не нужен: и .club, и .player-page — колонки с gap. */
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--color-text); }

.player-head { display: flex; align-items: flex-start; gap: 20px; }
.avatar--lg { width: 72px; height: 72px; border-radius: 50%; }
.player-head__ident { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.player-head__name {
  margin: 0;
  font-size: 32px;
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  gap: 10px;
}
.player-head__real { color: var(--muted); font-size: 14px; }
.player-head__place { color: var(--color-accent); font-size: 13px; }
.player-head__facts {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--muted);
}
.player-head__facts a { color: var(--muted); }
/* Вторая строка фактов — то, что игрок написал о себе сам, а не то, что мы
   посчитали. Тише первой ровно поэтому. */
.player-head__profile { color: var(--faint); }
.player-head__profile a { color: var(--color-accent); }
.player-head__back { font-size: 13px; margin-top: 4px; }
/* Уход наружу — это ссылка, а не строка фактов: её кликают, а не читают,
   поэтому цвет тот же, что у «Все игроки клуба», а не приглушённый. */
.player-head__source a { color: var(--color-accent); }

.player-page__filters { display: flex; }
.player-page__filters .filters { margin-left: 0; }
.player-page__tab { display: flex; flex-direction: column; gap: 18px; }

@media (max-width: 760px) {
  .player-head { gap: 14px; }
  .avatar--lg { width: 56px; height: 56px; }
  .player-head__name { font-size: 24px; }
  .tabs { gap: 18px; }
}

/* ── плитки обзора ──────────────────────────────────────────────────── */
.tiles { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
.tile { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px; }
.tile__value { font-size: 28px; font-weight: 500; letter-spacing: -0.02em; }
.tile__value--high { color: var(--hi); }
.tile__value--low { color: var(--lo); }
.tile__note { font-size: 12px; color: var(--faint); }

.recent { display: flex; flex-direction: column; gap: 12px; }
.recent__row {
  grid-template-columns: 72px 104px 112px 106px 116px 68px 68px 68px 1fr;
}
/* На глобальной карточке в первой колонке стоит ещё и название клуба: без
   него строки из разных клубов сливаются в один список. */
.recent__table--global .recent__row {
  grid-template-columns: 210px 104px 108px 100px 112px 64px 64px 66px 1fr;
}
/* Обёртка «ПУ · допы · штраф» существует ради телефона: на десктопе она
   растворяется и отдаёт три ячейки прямо в сетку строки. */
.recent__meta { display: contents; }
.recent__role { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.recent__outcome--win { color: var(--hi); }
.recent__outcome--loss { color: var(--lo); }
.recent__pu { display: inline-flex; align-items: baseline; gap: 6px; }

@media (max-width: 760px) {
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .tile__value { font-size: 22px; }
  /* Раскладка привязана к классам ячеек, а не к их номерам: с nth-child
     добавление колонки в таблицу молча перекладывает телефон. */
  .recent__row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "num date" "role outcome" "meta points";
    row-gap: 4px;
  }
  .recent__num { grid-area: num; }
  .recent__date { grid-area: date; text-align: right; }
  .recent__role { grid-area: role; }
  .recent__outcome { grid-area: outcome; text-align: right; }
  .recent__points { grid-area: points; }
  /* Обёртка снова становится обёрткой: ПУ, допы и штраф выстраиваются в
     строку под ролью, а не занимают три колонки на узком экране. */
  .recent__meta {
    grid-area: meta;
    display: flex;
    align-items: baseline;
    gap: 10px;
    text-align: left;
  }
  .recent__bonus, .recent__penalty { text-align: left; }
  /* Судью на телефоне режем: это единственная колонка, ради которой не
     открывают карточку игрока. */
  .recent__referee { display: none; }
}

/* ── графики ────────────────────────────────────────────────────────── */
.chart { display: flex; flex-direction: column; gap: 10px; padding: 18px 22px 14px; }
.chart__head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.chart__legend {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 11px;
  color: var(--muted);
}
.chart__legend span { display: inline-flex; align-items: center; gap: 6px; }
.chart__legend i { width: 9px; height: 9px; border-radius: 50%; }
.dot-hi { background: var(--hi); }
.dot-lo { background: var(--lo); }
.dot-small { border: 1.5px solid var(--lo); box-sizing: border-box; }

.chart__roles { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chart__roles-label {
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}
.chip {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.chip:hover { color: var(--color-text); }
.chip--on { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }

.chart__canvas { position: relative; height: 232px; }
.chart__canvas--short { height: 56px; }
.chart__label {
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.chart-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.bars { display: flex; flex-direction: column; gap: 10px; }
.bars__row { display: grid; grid-template-columns: 120px 1fr 84px; gap: 14px; align-items: center; }
.bars__name { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; }
.bars__track { position: relative; height: 10px; border-radius: 3px; background: var(--track); }
.bars__mid { position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px; background: var(--mid); }
.bars__fill { position: absolute; top: 0; bottom: 0; }
.bars__fill--low { right: 50%; background: var(--lo); border-radius: 3px 0 0 3px; }
.bars__fill--high { left: 50%; background: var(--hi); border-radius: 0 3px 3px 0; }
.bars__fill--flat { left: 0; background: var(--bar-strong); border-radius: 3px; }
.bars__expected { position: absolute; top: -3px; bottom: -3px; width: 0; border-left: 1px dashed var(--mark); }
.bars__count { text-align: right; font-variant-numeric: tabular-nums; }
.bars__count .rate__sample { margin-left: 6px; }

/* Слоты: та же полоска, что у «Сколько игр в каждой роли», но колонок
   четыре — номер слота, шкала, счётчик и win-rate. */
.slots__series { display: flex; flex-direction: column; gap: 10px; }
.slots__row { grid-template-columns: 32px 1fr 84px 76px; }
.slots__place {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.slots__note { color: var(--faint); font-size: 12px; }
/* §8: малая выборка помечается и на полоске, а не только цифрой рядом.
   Прозрачность, а не свой токен: цвет остаётся тем же в обеих темах, а
   заводить --bar-weak ради одного правила незачем. */
.bars__fill--small { opacity: 0.5; }
/* Свотч легенды — та же полоска, что в строке, а не кружок: круглым
   правилом .chart__legend i метит точки графика по месяцам. */
.chart__legend .bar-small {
  width: 18px;
  height: 6px;
  border-radius: 3px;
  background: var(--bar-strong);
  opacity: 0.5;
}

@media (max-width: 760px) {
  .chart-pair { grid-template-columns: 1fr; }
  .chart__canvas { height: 190px; }
  .bars__row { grid-template-columns: 92px 1fr 72px; gap: 10px; }
  .slots__row { grid-template-columns: 24px 1fr 64px 64px; gap: 10px; }
  .chart__legend { margin-left: 0; width: 100%; }
}

/* ── по-ролевые блоки ───────────────────────────────────────────────── */
.role-mark--all {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  border: 1.5px dashed var(--mark);
  margin-top: 2px;
}

.role-block { padding: 20px 24px 22px; display: flex; flex-direction: column; gap: 18px; }
.role-block__head { display: flex; align-items: flex-start; gap: 14px; }
.role-block__score { margin-left: auto; display: flex; align-items: center; gap: 20px; }
.role-block__percent {
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.02em;
  text-align: right;
}
.winrate__track--wide { width: 220px; height: 10px; border-radius: 3px; }

.role-groups { display: grid; grid-template-columns: 1fr 1fr; gap: 0 32px; }
.metric-group { display: flex; flex-direction: column; }
.metric-group__title,
.role-card__title {
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  padding-bottom: 7px;
}
.role-card__title {
  font-size: 12px;
  letter-spacing: 0.11em;
  color: var(--color-text);
  padding-bottom: 0;
}

.metric {
  display: grid;
  grid-template-columns: 1fr 68px 68px;
  align-items: baseline;
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid var(--line);
}
.metric__label { font-size: 13px; color: var(--muted); }
.metric__hint { color: var(--faint); }
.metric__value { text-align: right; font-variant-numeric: tabular-nums; }
.metric__sample {
  text-align: right;
  font-size: 12px;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.metric__none { color: var(--faint); }
/* §8: малая выборка — рамкой, а не словами. */
.metric__box {
  display: inline-block;
  padding: 0 5px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  font-size: 11px;
  color: var(--muted);
  cursor: help;
}
.metric--sub { border-top: 0; padding: 2px 0 5px; }
.metric--sub .metric__label { font-size: 12px; color: var(--faint); padding-left: 12px; }
.metric--sub .metric__value { font-size: 12px; color: var(--muted); }

/* Сноска на карточке игрока мельче и тише клубной: их тут по три на экран,
   и общий `.note` из плана 4 не переопределяется — вкладки клуба своим
   размером довольны. */
.player-page .note { margin: 12px 0 0; font-size: 12px; color: var(--faint); text-wrap: pretty; }

.group-head { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.group-head__title { margin: 0; font-size: 17px; }
.group-head__note { font-size: 13px; color: var(--muted); }
.group-head__line {
  flex: 1;
  height: 1px;
  background: linear-gradient(to right, var(--line), transparent 90%);
}

.role-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.role-card { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 14px; }
.role-card__head { display: flex; align-items: flex-start; gap: 12px; }
.role-card__ident { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.role-card__sub { font-size: 13px; color: var(--muted); }
.role-card__score { margin-left: auto; text-align: right; }
.role-card__percent { font-size: 26px; font-weight: 500; letter-spacing: -0.02em; }
.role-card__wl { font-size: 12px; color: var(--muted); }
.role-card__none { font-size: 13px; color: var(--faint); padding: 6px 0 2px; }
.metrics { display: flex; flex-direction: column; }

@media (max-width: 760px) {
  /* Три колонки знаменателей на телефоне становятся одним списком: ширины
     на три нет, а порядок метрик и подписи-знаменатели сохраняются. */
  .role-groups { grid-template-columns: 1fr; gap: 18px 0; }
  .role-cards { grid-template-columns: 1fr; gap: 14px; }
  .role-block__head { flex-wrap: wrap; }
  .role-block__score { width: 100%; margin-left: 0; }
  /* .role-block__score — строчный флекс: flex:1 растягивает ширину.
     .role-card — колоночный (§ выше); тот же flex:1 растянул бы высоту и
     схлопнул полоску в 0 — там достаточно снять фиксированную ширину,
     дальше её растягивает дефолтный align-items: stretch колонки. */
  .role-block__score .winrate__track--wide { flex: 1; width: auto; }
  .role-card .winrate__track--wide { width: auto; }
  .role-block__percent { font-size: 26px; }
  .group-head { flex-wrap: wrap; gap: 8px; }
  .group-head__line { display: none; }
  .metric { grid-template-columns: 1fr 62px 62px; gap: 8px; }
}

/* ── форма обратной связи ───────────────────────────────────────────── */
.feedback { display: flex; flex-direction: column; gap: 14px; max-width: 640px; padding-top: 28px; }
.feedback__back { font-size: 13px; }

.form { display: flex; flex-direction: column; gap: 18px; padding: 20px; }
.form__row { display: flex; flex-direction: column; gap: 8px; }
.form__pair { display: flex; flex-direction: column; gap: 5px; }
.form__label {
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}
.form__sub, .form__hint { font-size: 12px; color: var(--muted); }
.form__hint { margin: 0; }

.form__input {
  width: 100%;
  padding: 9px 11px;
  font: inherit;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.form__input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -1px; }
.form__input--area { resize: vertical; min-height: 120px; line-height: 1.5; }

/* Тип заявки — те же чипы, что и у фильтров, но радиокнопками: без JS
   переключаться нечем, а :has даёт подсветку выбранного без него. Класса
   --on здесь нет намеренно: он приезжает с сервера и остался бы висеть на
   исходном варианте после переключения — два выбранных чипа сразу. */
.form .chips {
  /* Колонка .form__row растянула бы inline-flex на всю ширину карточки, и
     справа от чипов осталась бы пустая рамка. */
  align-self: flex-start;
}
.form .chips__item { cursor: pointer; }
.form .chips__item input { position: absolute; opacity: 0; pointer-events: none; }
.form .chips__item:has(input:checked) {
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}
.form .chips__item:has(input:focus-visible) { outline: 2px solid var(--color-accent); }

.form__submit {
  align-self: flex-start;
  padding: 9px 18px;
  font: inherit;
  font-size: 14px;
  color: var(--color-bg);
  background: var(--color-text);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}
.form__submit:hover { background: var(--color-accent); }

/* Цвет из палитры, а не свой красный: --lo — это «хуже, чем ожидалось» в
   обеих темах, и другого негативного токена у портала нет. */
.form__error { font-size: 12px; color: var(--lo); }
.form__error--top {
  padding: 12px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--color-surface);
  font-size: 13px;
}

/* Ловушка для ботов: из вёрстки убрана целиком, а не спрятана прозрачностью
   — иначе поле осталось бы кликабельным и попадало бы в автозаполнение. */
.form__trap { display: none; }

/* ── пары ───────────────────────────────────────────────────────────── */
.mates-summary { display: flex; align-items: flex-start; gap: 20px; padding: 14px 18px; }
.mates-summary__cell { display: flex; flex-direction: column; gap: 2px; max-width: 420px; }
.mates-summary__sep { width: 1px; align-self: stretch; background: var(--line); }
.mates-summary__big { font-size: 20px; font-weight: 500; letter-spacing: -0.02em; }
.mates-summary__text { font-size: 13px; color: var(--muted); text-wrap: pretty; }
.mates-summary__strong { color: var(--color-text); }
.mates-top { display: flex; flex-direction: column; gap: 12px; }
.mates-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

.mate { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.mate__head { display: flex; align-items: center; gap: 12px; }
.mate__ident { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.mate__name {
  font-size: 16px;
  color: var(--color-text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mate__name:hover { color: var(--color-accent); }
.mate__score { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Победы и поражения — та же пара --hi/--lo, что у колонки «Исход» в списке
   игр: другого языка для «сложилось / не сложилось» у портала нет, а свои
   зелёный с красным спорили бы с ней на соседних вкладках. */
.mate__won { color: var(--hi); }
.mate__lost { color: var(--lo); }
.mate__percent {
  margin-left: auto;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.mate__percent--high { color: var(--hi); }
.mate__percent--low { color: var(--lo); }
.mate__scale { display: flex; flex-direction: column; gap: 5px; }
/* Полоска — баланс исходов, а не объём выборки: дорожка целиком жёлтая
   (поражения), синяя заливка съедает её слева ровно на win rate. Второго
   тега под жёлтое не нужно — доли в сумме дают сто процентов, и одной
   ширины хватает, чтобы задать обе. */
.mate__track {
  position: relative;
  display: block;
  height: 8px;
  border-radius: 2px;
  background: var(--lo);
}
.mate__fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 2px 0 0 2px;
  background: var(--hi);
}
/* Крайние случаи: у 100% и 0% скруглён весь прямоугольник, иначе полоска без
   второго цвета выглядит подрезанной с одного бока. */
.mate__fill[style*="width:100.0%"] { border-radius: 2px; }
.mate__count { display: flex; align-items: baseline; gap: 7px; font-size: 12px; color: var(--muted); }
.mate__games { font-size: 14px; color: var(--color-text); font-variant-numeric: tabular-nums; }
.avatar--lg-sm { width: 40px; height: 40px; }

.link-button {
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-accent);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.link-button:hover { color: var(--color-text); }

/* Alpine ставит x-show после первой отрисовки: без x-cloak семь скрытых
   карточек успевают мигнуть. */
[x-cloak] { display: none !important; }

@media (max-width: 760px) {
  .mates-summary { flex-direction: column; gap: 12px; }
  .mates-summary__sep { display: none; }
  .mates-grid { grid-template-columns: 1fr; gap: 12px; }
}

/* ── Заглушки «скоро» (§3, §14) ───────────────────────────────────────────
   Пунктирная рамка, приглушённый текст — раздела ещё нет, и карточка обязана
   читаться как зарезервированное место, а не как пустой блок с данными.
   Разметка снята с артборда PlayerPage; инлайновые стили превращены в классы. */
.soon {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 24px;
}
.soon__card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 20px 22px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
}
.soon__head { display: flex; align-items: center; gap: 10px; }
.soon__title { margin: 0; font-size: 16px; color: var(--muted); }
.soon__badge {
  padding: 2px 9px;
  border-radius: 5px;
  background: var(--chip);
  color: var(--muted);
  font-size: 11px;
}
.soon__text { font-size: 13px; color: var(--faint); text-wrap: pretty; }

@media (max-width: 760px) {
  .soon { grid-template-columns: 1fr; gap: 12px; margin-top: 16px; }
  .soon__card { padding: 14px; }
  .soon__title { font-size: 14px; }
  .soon__badge { padding: 2px 8px; font-size: 10px; }
  .soon__text { font-size: 12px; }
}
