/* =========================================================================
   DESIGN TOKENS — three-layer system (primitive → semantic → component)
   Фирменный стиль «Legend FM»: золото — primary/CTA/бренд, зелёное поле —
   отдельный success-токен (бейджи «одобрено»/VIP) и буквально цвет травы
   на тактическом поле, бирюзовое свечение прожекторов — атмосферный акцент
   на лендинге, красный — danger. Легаси-переменные (--bg, --surface, --text
   и т.п.) сохранены как алиасы — на них есть прямые ссылки из инлайн-стилей
   в HTML (admin.html, dashboard.html).
   ========================================================================= */
@font-face{font-family:'Oswald';font-weight:700;font-style:normal;font-display:swap;
  src:url(/fonts/Oswald_700_cyrillic.woff2) format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Oswald';font-weight:700;font-style:normal;font-display:swap;
  src:url(/fonts/Oswald_700_latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Rubik';font-weight:400;font-style:normal;font-display:swap;
  src:url(/fonts/Rubik_400_cyrillic.woff2) format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Rubik';font-weight:400;font-style:normal;font-display:swap;
  src:url(/fonts/Rubik_400_latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Rubik';font-weight:600;font-style:normal;font-display:swap;
  src:url(/fonts/Rubik_600_cyrillic.woff2) format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Rubik';font-weight:600;font-style:normal;font-display:swap;
  src:url(/fonts/Rubik_600_latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

:root{
  /* ---- Primitive: neutrals ---- */
  --gray-950:#050810; --gray-900:#0a0f1c; --gray-850:#0e1526; --gray-800:#121b2e;
  --gray-750:#161f35; --gray-700:#182140; --gray-650:#1c2748; --gray-600:#22304f;
  --gray-500:#34426b; --gray-400:#5c6683; --gray-300:#8b93a7; --gray-100:#edeff3;

  /* ---- Primitive: brand green (pitch) ---- */
  --green-800:#163a26; --green-700:#215e3d; --green-600:#2f8a4f; --green-500:#3ba55c;
  --green-400:#45bd68; --green-300:#6fd08c;

  /* ---- Primitive: gold (accent / admin) ---- */
  --gold-700:#a9812a; --gold-600:#c2952f; --gold-500:#d4a73c; --gold-400:#e0bc5f; --gold-300:#e9cf8c;

  /* ---- Primitive: red (danger) ---- */
  --red-600:#b53c3c; --red-500:#d64545; --red-400:#e26a6a; --red-300:#f08a8a;

  /* ---- Primitive: teal (прожекторы — атмосферный акцент лендинга) ---- */
  --teal-600:#0d9488; --teal-500:#14b8a6; --teal-300:#5eead4; --teal-100:#eafbf8;

  /* ---- Primitive: typography ---- */
  --font-display:'Oswald','Rubik',sans-serif;
  --font-body:'Rubik',system-ui,-apple-system,sans-serif;
  --text-2xs:.6875rem; --text-xs:.75rem; --text-sm:.8125rem; --text-base:.875rem;
  --text-md:.9375rem; --text-lg:1rem; --text-xl:1.0625rem; --text-2xl:1.375rem;
  --text-3xl:1.75rem; --text-5xl:3rem;
  --leading-tight:1.1; --leading-snug:1.4; --leading-normal:1.6;

  /* ---- Primitive: spacing (4px base) ---- */
  --space-0-5:2px; --space-1:4px; --space-1-5:6px; --space-2:8px; --space-2-5:10px;
  --space-3:12px; --space-3-5:14px; --space-4:16px; --space-4-5:18px; --space-5:20px;
  --space-6:24px; --space-7:28px; --space-8:32px; --space-10:40px; --space-12:48px; --space-14:56px;
  --space-16:64px; --space-20:80px;

  /* ---- Primitive: radius / shadow / motion ---- */
  --radius-xs:3px; --radius-sm:6px; --radius-md:8px; --radius-lg:12px; --radius-full:999px;
  --shadow-xs:0 1px 2px rgba(0,0,0,.28); --shadow-sm:0 2px 6px rgba(0,0,0,.28);
  --shadow-md:0 6px 16px rgba(0,0,0,.32); --shadow-lg:0 16px 40px rgba(0,0,0,.4);
  --duration-fast:.12s; --duration-base:.18s; --ease:cubic-bezier(.4,0,.2,1);

  /* ---- Semantic ---- */
  --color-bg:var(--gray-900); --color-bg-elevated:var(--gray-850);
  --color-surface:var(--gray-800); --color-surface-hover:var(--gray-750);
  --color-surface-2:var(--gray-700); --color-surface-2-hover:var(--gray-650);
  --color-border:var(--gray-600); --color-border-strong:var(--gray-500);
  --color-text:var(--gray-100); --color-text-muted:var(--gray-300); --color-text-dim:var(--gray-400);
  --color-text-inverse:#08150c;

  /* Primary/CTA/бренд — золото (см. решение по редизайну: логотип LEGEND FM,
     прожекторы). Зелёное поле — больше не primary, а отдельный success. */
  --color-primary:var(--gold-500); --color-primary-hover:var(--gold-400);
  --color-primary-active:var(--gold-600); --color-primary-subtle:rgba(212,167,60,.15);

  --color-accent:var(--gold-500); --color-accent-subtle:rgba(212,167,60,.15);

  --color-success:var(--green-500); --color-success-hover:var(--green-400);
  --color-success-subtle:rgba(59,165,92,.14);

  --color-danger:var(--red-500); --color-danger-hover:var(--red-400);
  --color-danger-subtle:rgba(214,69,69,.12);

  --color-focus-ring:0 0 0 3px rgba(212,167,60,.35);

  /* Прожекторы — атмосферное свечение фона на лендинге (морская волна) */
  --glow-1:rgba(20,184,166,.24); --glow-2:rgba(110,231,214,.16);

  --container-max:1250px; --container-narrow-max:440px;

  /* ---- Legacy aliases (backward-compat, referenced inline in HTML) ---- */
  --bg:var(--color-bg); --surface:var(--color-surface); --surface2:var(--color-surface-2);
  --pitch:var(--green-700); --pitch-light:var(--color-success); --gold:var(--color-accent);
  --text:var(--color-text); --text-muted:var(--color-text-muted); --text-dim:var(--color-text-dim);
  --red:var(--color-danger); --border:var(--color-border);

  /* ---- Component: button ---- */
  --button-radius:var(--radius-xs); --button-font-size:var(--text-base);
  --button-padding-y:var(--space-2-5); --button-padding-x:var(--space-4-5);
  --button-padding-y-sm:var(--space-1-5); --button-padding-x-sm:var(--space-3); --button-font-size-sm:var(--text-xs);
  --button-bg:var(--color-surface-2); --button-fg:var(--color-text); --button-border:var(--color-border);
  --button-hover-bg:var(--color-surface-2-hover); --button-hover-border:var(--color-primary);
  --button-primary-bg:var(--color-primary); --button-primary-fg:var(--color-text-inverse);
  --button-primary-hover-bg:var(--color-primary-hover);
  --button-danger-bg:var(--color-danger); --button-danger-fg:#fff; --button-danger-hover-bg:var(--color-danger-hover);

  /* ---- Component: input ---- */
  --input-bg:var(--color-surface-2); --input-fg:var(--color-text); --input-border:var(--color-border);
  --input-radius:var(--radius-md); --input-padding-y:var(--space-2-5); --input-padding-x:var(--space-3);
  --input-focus-border:var(--color-primary); --input-placeholder:var(--color-text-dim);

  /* ---- Component: card ---- */
  --card-bg:var(--color-surface); --card-border:var(--color-border);
  --card-radius:var(--radius-lg); --card-padding:var(--space-6); --card-shadow:var(--shadow-sm);

  /* ---- Component: badge ---- */
  --badge-radius:var(--radius-full); --badge-padding-y:var(--space-0-5); --badge-padding-x:var(--space-2-5);
  --badge-font-size:var(--text-2xs); --badge-font-weight:700;

  /* ---- Component: table ---- */
  --table-header-fg:var(--color-text-dim); --table-border:var(--color-border);
  --table-cell-padding-y:var(--space-2-5); --table-cell-padding-x:var(--space-2-5); --table-row-hover-bg:var(--color-surface-hover);

  /* ---- Component: admin sidebar ---- */
  --sidebar-width:220px; --sidebar-item-hover-bg:var(--color-surface-2);
  --sidebar-item-active-bg:var(--color-primary-subtle); --sidebar-item-active-fg:var(--color-primary);

  /* ---- Component: scrollbar ---- */
  --scrollbar-size:8px; --scrollbar-page-size:10px;
  --scrollbar-thumb:rgba(139,147,167,.32); --scrollbar-thumb-hover:rgba(139,147,167,.55);
  --scrollbar-thumb-active:var(--color-primary); --scrollbar-track:transparent;

  /* ---- Смысловые палитры (DESIGN.md §2.2) ---- */
  --pos-gk:#f59e0b; --pos-df:#3b82f6; --pos-mf:#22c55e; --pos-fw:#ef4444;
  --rating-elite:#e9c46a; --rating-great:#4ade80; --rating-good:#22c55e;
  --rating-mid:#a3e635; --rating-low:#f59e0b; --rating-poor:#8b93a7;
}

/* ---- Compact-режим (мобильный браузер + Android-приложение, mobile/) ----
   Вся плотность вёрстки на сайте УЖЕ выражена через примитивы --space-* и
   --text-* (см. :root выше) — карточки/кнопки/таблицы/отступы заголовков
   читают именно их (--card-padding:var(--space-6) и т.п.), а не хардкодят
   px. Поэтому переопределение примитивов ВНУТРИ media-блока даёт системную
   компактность сразу на всех игровых/клубных страницах разом, без правки
   каждого Vue-компонента — админку не трогаем (десктопный инструмент, вне
   этого брейкпоинта). 900px — тот же порог, что уже скрывает
   .nav-desktop-links (landscape-телефоны). Шкала отступов ужата к ~70-75%
   (крупные значения жмём сильнее — именно они съедают экран), самые
   мелкие (0-5/1) почти не трогаем — дальше уже нечитаемо/некликабельно.
   Шрифты — заметно только у крупных заголовков (hero h1, лого шапки) —
   именно они раньше требовали два «экрана» landscape-высоты ради одной
   строки текста; базовый текст (xs…base) не трогаем — это уже предел
   читаемости на телефоне. */
@media(max-width:900px){
  :root{
    --space-0-5:2px; --space-1:3px; --space-1-5:4px; --space-2:6px; --space-2-5:8px;
    --space-3:9px; --space-3-5:10px; --space-4:12px; --space-4-5:13px; --space-5:15px;
    --space-6:18px; --space-7:20px; --space-8:24px; --space-10:30px; --space-12:36px; --space-14:40px;
    --space-16:46px; --space-20:56px;

    --text-md:.875rem; --text-lg:.9375rem; --text-xl:1rem; --text-2xl:1.125rem;
    --text-3xl:1.375rem; --text-5xl:1.875rem;
  }
}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important;}
}

/* =========================================================================
   BASE
   ========================================================================= */
*{box-sizing:border-box;}
body{
  margin:0; background:var(--color-bg); color:var(--color-text);
  font-family:var(--font-body); font-size:var(--text-lg); line-height:var(--leading-normal);
  min-height:100vh; -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
h1,h2,h3{font-family:var(--font-display); letter-spacing:.5px; font-weight:400; line-height:var(--leading-tight); margin:0 0 var(--space-3);}
a{color:var(--color-primary); text-decoration:none;}
a:hover{text-decoration:underline;}
::selection{background:var(--color-primary); color:var(--color-text-inverse);}

/* Скроллбары: тонкий «плавающий» ползунок без дорожки — серый, при наведении
   светлее, при перетаскивании золотой. Chromium/Safari — через
   ::-webkit-scrollbar (там есть скругление и отступ от края), Firefox — через
   стандартные scrollbar-width/-color (Chromium 121+ при их наличии игнорирует
   ::-webkit-scrollbar, поэтому они только для браузеров без него). У страницы
   ползунок чуть шире, в попапах/модалках/списках — 8px. */
::-webkit-scrollbar{width:var(--scrollbar-size); height:var(--scrollbar-size);}
html::-webkit-scrollbar{width:var(--scrollbar-page-size); height:var(--scrollbar-page-size);}
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner{background:var(--scrollbar-track);}
::-webkit-scrollbar-track{margin:6px;}
html::-webkit-scrollbar-track{margin:0;}
::-webkit-scrollbar-thumb{
  background:var(--scrollbar-thumb); background-clip:padding-box;
  border:2px solid transparent; border-radius:var(--radius-full); min-height:32px;
}
::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover);}
::-webkit-scrollbar-thumb:active{background-color:var(--scrollbar-thumb-active);}
::-webkit-scrollbar-button{display:none; width:0; height:0;}
@supports not selector(::-webkit-scrollbar){
  *{scrollbar-width:thin; scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);}
  html{scrollbar-color:var(--scrollbar-thumb-hover) var(--color-bg);}
}
html{color-scheme:dark;}

:focus-visible{outline:none; box-shadow:var(--color-focus-ring); border-radius:var(--radius-sm);}

.nav{
  display:flex; align-items:center; justify-content:space-between;
  padding:var(--space-3-5) var(--space-6); border-bottom:1px solid var(--color-border); background:var(--color-bg-elevated);
  position:sticky; top:0; z-index:10;
  /* env(safe-area-inset-*) — 0px в обычном браузере (десктоп/мобильный
     Chrome), >0 только в Android-обёртке (mobile/, Capacitor) с
     edge-to-edge WebView — отступ под вырез/статус-бар не перекрывал
     шапку. top — для портретной ориентации (вырез сверху); left/right —
     для landscape (на повёрнутом телефоне вырез/скруглённые углы уезжают
     на боковую грань, не сверху). calc с env(...,0px) не ломается, если
     env() не поддерживается вообще (крайне старые браузеры). */
  padding-top:calc(var(--space-3-5) + env(safe-area-inset-top, 0px));
  padding-left:calc(var(--space-6) + env(safe-area-inset-left, 0px));
  padding-right:calc(var(--space-6) + env(safe-area-inset-right, 0px));
}
.nav-logo{
  font-family:var(--font-display); font-size:var(--text-2xl); letter-spacing:.03em; text-transform:uppercase;
  color:var(--color-text); text-decoration:none; display:inline-flex; align-items:center; gap:var(--space-2);
}
.nav-logo:hover{text-decoration:none;}
.nav-logo-icon{width:26px; height:26px; display:block;}
.fm-chip{
  display:inline-block; background:var(--color-primary); color:var(--color-text-inverse);
  padding:2px var(--space-2) 3px; font-size:.88em; clip-path:polygon(12% 0,100% 0,88% 100%,0 100%);
}
.nav-links{display:flex; gap:var(--space-2-5); align-items:center;}

/* Единое выпадающее меню шапки (AppHeader.vue) — разделы сайта + вход/
   регистрация или личный кабинет/админ-панель/выход, один и тот же
   компонент на всех страницах. Закрывается кликом снаружи (тот же
   принцип, что и .skill-tooltip — см. useSkillPopup.js), не по hover
   (нужно одинаково работать и на тач-устройствах). */
.nav-menu{position:relative;}
.nav-menu-trigger{
  display:inline-flex; align-items:center; gap:var(--space-2);
  padding:var(--button-padding-y) var(--button-padding-x); border-radius:var(--button-radius);
  border:1px solid var(--button-border); background:transparent; color:var(--color-text);
  font-size:var(--button-font-size); font-weight:700; cursor:pointer;
  transition:border-color var(--duration-base) var(--ease), background var(--duration-base) var(--ease);
}
.nav-menu-trigger:hover{border-color:var(--button-hover-border); background:var(--button-hover-bg);}
.nav-menu-icon{width:18px; height:18px; display:block; flex:none;}
.nav-menu-dropdown{
  position:absolute; top:calc(100% + var(--space-2)); right:0; min-width:200px; z-index:20;
  background:var(--color-bg-elevated); border:1px solid var(--color-border); border-radius:var(--radius-md);
  padding:var(--space-2); box-shadow:var(--shadow-lg);
  display:flex; flex-direction:column; gap:var(--space-2);
}
.nav-menu-dropdown a, .nav-menu-dropdown button{
  display:flex; align-items:center; width:100%; box-sizing:border-box;
  padding:var(--space-2) var(--space-2-5); border-radius:var(--radius-sm);
  color:var(--color-text); background:none; border:none; font-size:var(--text-sm); font-weight:600;
  text-align:left; cursor:pointer; text-decoration:none; white-space:nowrap;
}
.nav-menu-dropdown a:hover, .nav-menu-dropdown button:hover{background:var(--color-surface-2); text-decoration:none;}
.nav-menu-dropdown a.current{color:var(--gold-400);}
/* Все пункты сайта — в бургере (AppHeader.vue menuGroups): группы с
   заголовком; у залогиненного — колонками по 180px, не больше трёх в ряд
   (с клубом: Команда/Матчи и трансферы/Клуб, ниже Сайт/Администрирование/аккаунт). */
.nav-menu-dropdown-groups{display:flex; flex-direction:column; gap:2px; min-height:0;}
.nav-menu-group{display:flex; flex-direction:column; gap:2px; min-width:0;}
.nav-menu-group-title{
  display:flex; align-items:center; padding:var(--space-1) var(--space-2-5);
  font-size:var(--text-2xs); font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--color-text-dim);
}
/* "Выйти" — не в группе профиля, а отдельной строкой внизу бургера,
   прижатой к правому краю (по прямому запросу: раньше была последней
   кнопкой в группе профиля вперемешку с "Карьера"/"Достижения"). */
.nav-menu-dropdown-footer{display:flex; justify-content:flex-end; padding-top:var(--space-2); border-top:1px solid var(--color-border);}
.nav-menu-dropdown-footer button{width:auto;}
.nav-menu-dropdown--wide .nav-menu-dropdown-groups{
  flex-direction:row; flex-wrap:wrap; gap:var(--space-3) var(--space-2);
  width:max-content; max-width:calc(3 * 180px + 2 * var(--space-2) + 2 * var(--space-2) + 2px);
}
.nav-menu-dropdown--wide .nav-menu-dropdown-groups .nav-menu-group{width:180px;}
@media (max-width:640px){
  /* Телефон: на всю ширину экрана под шапкой, две колонки групп, своя
     прокрутка — только у групп, футер с "Выйти" остаётся закреплён снизу. */
  .nav-menu-dropdown--wide{
    position:fixed; top:auto; left:var(--space-2); right:var(--space-2);
    width:auto; max-width:none; max-height:calc(100dvh - 110px); margin-top:var(--space-2);
  }
  .nav-menu-dropdown--wide .nav-menu-dropdown-groups{width:100%; max-width:none; overflow-y:auto;}
  .nav-menu-dropdown--wide .nav-menu-dropdown-groups .nav-menu-group{width:calc(50% - var(--space-1));}
  .nav-menu-dropdown--wide a, .nav-menu-dropdown--wide button{white-space:normal; padding-top:var(--space-1-5); padding-bottom:var(--space-1-5);}
}
/* Переключатель режима игры (AppHeader.vue, migrations/064-065). */
/* Переключатель режима — в самой шапке (AppHeader.vue), пилюлей, как на
   главной (.mode-bar-switch), только компактнее. */
.header-mode-switch{display:inline-flex; flex:none; gap:2px; padding:2px; background:var(--color-surface-2); border:1px solid var(--color-border); border-radius:var(--radius-full);}
.header-mode-btn{
  padding:var(--space-1) var(--space-2-5); border:0; border-radius:var(--radius-full); background:none;
  font:inherit; font-size:var(--text-xs); font-weight:700; line-height:1.4; white-space:nowrap; cursor:pointer;
  color:var(--color-text-muted); transition:background var(--duration-base) var(--ease), color var(--duration-base) var(--ease);
}
.header-mode-btn:hover:not(.active){color:var(--color-text);}
.header-mode-btn.active{cursor:default; box-shadow:inset 0 0 0 1px currentColor;}
.header-mode-btn.mode-legends.active{color:var(--gold-400); background:rgba(212,167,60,.16);}
.header-mode-btn.mode-leagues.active{color:#6aa8ff; background:rgba(106,168,255,.16);}
/* Телефон: строка поиска и так тесная (на 320px поле сжималось до «Поис»),
   поэтому переключатель — в верхнюю строку, справа от логотипа (.nav —
   sticky, т.е. уже positioned-контейнер). */
@media (max-width:640px){
  .header-mode-switch{position:absolute; top:var(--space-3); right:var(--space-4);}
  .header-mode-btn{padding:var(--space-1) var(--space-2);}
}
/* Текущий режим — плашка на кнопке меню у любого залогиненного (и на
   телефоне — там имя скрыто, место есть). Цвет режима: «Легенды» —
   золото бренда, «Лиги» — синий. */
.nav-mode-chip{
  padding:1px 7px; border-radius:var(--radius-full); border:1px solid currentColor;
  font-size:var(--text-2xs); font-weight:700; line-height:1.5; letter-spacing:.02em; white-space:nowrap;
}
.nav-mode-chip.mode-legends, .mode-bar-btn.mode-legends{color:var(--gold-400);}
.nav-mode-chip.mode-leagues, .mode-bar-btn.mode-leagues{color:#6aa8ff;}
.nav-mode-chip.mode-legends{background:rgba(212,167,60,.14);}
.nav-mode-chip.mode-leagues{background:rgba(106,168,255,.14);}

/* Главная: режим игры в явном виде (ModeSwitchBar.vue в слоте героя). */
.mode-bar{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--space-2) var(--space-3);
  max-width:var(--container-max); margin:0 auto var(--space-4);
}
.mode-bar-label{font-size:var(--text-xs); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:.08em; font-weight:600;}
.mode-bar-switch{display:inline-flex; gap:2px; padding:3px; background:var(--color-surface-2); border:1px solid var(--color-border); border-radius:var(--radius-full);}
.mode-bar-btn{
  padding:var(--space-1-5) var(--space-4); border:0; border-radius:var(--radius-full); background:none;
  font:inherit; font-size:var(--text-sm); font-weight:700; cursor:pointer; opacity:.6;
  transition:background var(--duration-base) var(--ease), opacity var(--duration-base) var(--ease);
}
.mode-bar-btn:hover:not(:disabled){opacity:.9;}
.mode-bar-btn.active{opacity:1; cursor:default; box-shadow:inset 0 0 0 1px currentColor;}
.mode-bar-btn.mode-legends.active{background:rgba(212,167,60,.16);}
.mode-bar-btn.mode-leagues.active{background:rgba(106,168,255,.16);}
.mode-bar-btn:disabled{cursor:default;}
.mode-bar-hint{font-size:var(--text-xs); color:var(--color-text-dim);}
@media (max-width:640px){ .mode-bar-hint{flex-basis:100%; text-align:center;} }
/* «Лиги»: напоминание, что расстановку можно поменять до первого матча (App.vue). */
.leagues-setup-again{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-2) var(--space-3);}

/* Правый кластер шапки (AppHeader.vue) — поиск + уведомления + эмблема
   управляемого клуба + меню, единый flex-контейнер, чтобы
   justify-content:space-between не растягивало их поодиночке. */
.nav-right{display:flex; align-items:center; gap:var(--space-4);}
.header-club-link{display:flex; align-items:center; line-height:0; border-radius:50%; transition:opacity .15s;}
.header-club-link:hover{opacity:.8;}

/* Умный поиск по игрокам (AppHeader.vue) — по прямому запросу, выпадающий
   список подсказок ниже поля, тот же принцип клика-снаружи, что и
   .nav-menu-dropdown выше. */
.nav-search{position:relative; width:180px;}
.nav-search-input{
  width:100%; box-sizing:border-box; padding:var(--input-padding-y) var(--input-padding-x); border-radius:var(--input-radius);
  border:1px solid var(--input-border); background:var(--input-bg); color:var(--input-fg); font-size:var(--text-sm);
  transition:border-color var(--duration-base) var(--ease), box-shadow var(--duration-base) var(--ease), width var(--duration-base) var(--ease);
}
.nav-search-input::placeholder{color:var(--input-placeholder);}
.nav-search-input:focus{outline:none; border-color:var(--input-focus-border); box-shadow:var(--color-focus-ring); width:240px;}
/* Телефон (по прямому запросу — шапка вылезала за экран: поиск 120px +
   колокольчик + эмблема + флаг + кнопка меню с ником не помещались в
   ~343px). Правый кластер — вся вторая строка шапки, поиск забирает
   остаток ширины, у кнопки меню только иконка: ник виден в самом меню. */
@media(max-width:640px){
  .nav-right{gap:var(--space-2-5);}
  .nav-right:has(.nav-search){width:100%;} /* гость без поиска — меню остаётся рядом с лого */
  .nav-search{flex:1 1 auto; width:auto; min-width:0;}
  .nav-search-input:focus{width:100%;}
  .nav-menu-username{display:none;}
  .nav-menu-trigger{padding:var(--button-padding-y) var(--space-2-5);}
}
.nav-search-dropdown{
  position:absolute; top:calc(100% + var(--space-2)); left:0; width:280px; max-width:80vw; z-index:20;
  background:var(--color-bg-elevated); border:1px solid var(--color-border); border-radius:var(--radius-md);
  padding:var(--space-2); box-shadow:var(--shadow-lg);
  display:flex; flex-direction:column; gap:2px; max-height:60vh; overflow-y:auto;
}
.nav-search-item{
  display:flex; flex-direction:column; align-items:flex-start; gap:2px; width:100%; box-sizing:border-box;
  padding:var(--space-2) var(--space-2-5); border-radius:var(--radius-sm);
  color:var(--color-text); background:none; border:none; text-align:left; cursor:pointer;
}
.nav-search-item:hover, .nav-search-item.active{background:var(--color-surface-2);}
.nav-search-item-name{font-size:var(--text-sm); font-weight:700;}
.nav-search-item-meta{font-size:var(--text-xs); color:var(--color-text-muted);}
.nav-search-empty{padding:var(--space-2) var(--space-2-5); font-size:var(--text-sm); color:var(--color-text-muted);}

/* Колокольчик уведомлений (AppHeader.vue, migrations/061_notifications.sql)
   — тот же принцип дропдауна/клика-снаружи, что и .nav-search-dropdown/
   .nav-menu-dropdown выше. */
.notif-menu{position:relative;}
.notif-trigger{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; padding:0; border-radius:50%; border:1px solid transparent;
  background:transparent; color:var(--color-text-muted); cursor:pointer;
  transition:color var(--duration-base) var(--ease), background var(--duration-base) var(--ease);
}
.notif-trigger svg{width:20px; height:20px;}
.notif-trigger:hover{color:var(--color-text); background:var(--button-hover-bg);}
.notif-badge{
  position:absolute; top:-2px; right:-2px; min-width:16px; height:16px; padding:0 3px;
  display:flex; align-items:center; justify-content:center; border-radius:var(--radius-full);
  background:var(--color-danger); color:#fff; font-size:10px; font-weight:800; line-height:1;
}
.notif-dropdown{
  position:absolute; top:calc(100% + var(--space-2)); right:0; width:320px; max-width:85vw; z-index:20;
  background:var(--color-bg-elevated); border:1px solid var(--color-border); border-radius:var(--radius-md);
  box-shadow:var(--shadow-lg); max-height:70vh; overflow-y:auto;
}
.notif-dropdown-head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-2);
  padding:var(--space-2-5) var(--space-3); border-bottom:1px solid var(--color-border);
  font-size:var(--text-sm); font-weight:700; position:sticky; top:0; background:var(--color-bg-elevated);
}
.notif-mark-all{background:none; border:none; color:var(--color-primary); font-size:var(--text-xs); font-weight:600; cursor:pointer; padding:0;}
.notif-item{
  display:block; width:100%; box-sizing:border-box; text-align:left; background:none; border:none; cursor:pointer;
  padding:var(--space-2-5) var(--space-3); border-bottom:1px solid var(--color-border);
}
.notif-item:last-child{border-bottom:0;}
.notif-item:hover{background:var(--color-surface-2);}
.notif-item--unread{background:var(--color-accent-subtle);}
.notif-item-title{font-size:var(--text-sm); font-weight:700; color:var(--color-text);}
.notif-item-body{font-size:var(--text-xs); color:var(--color-text-muted); margin-top:2px;}
.notif-item-time{font-size:var(--text-2xs); color:var(--color-text-dim); margin-top:4px;}

.container{max-width:var(--container-max); margin:0 auto; padding:var(--space-8) var(--space-5);}
.container-narrow{max-width:var(--container-narrow-max); margin:0 auto; padding:var(--space-12) var(--space-5);}
/* Полноширинный вариант .container — по прямому запросу для страницы
   матча (MatchApp.vue): составам по бокам от поля тесно в обычном
   --container-max, а прижимать их к самым краям экрана без полей —
   уже другая крайность, поэтому боковой отступ (--space-5) остаётся,
   ограничение только по max-width снимается. */
.container-full{max-width:100%;}

/* Хлебные крошки (Breadcrumbs.vue) — первой строкой контейнера страницы.
   Длинные пункты обрезаются многоточием, на узком экране переносятся. */
.breadcrumbs{margin:calc(-1 * var(--space-4)) 0 var(--space-4); font-size:var(--text-xs); min-width:0;}
.breadcrumbs ol{display:flex; flex-wrap:wrap; align-items:center; gap:2px var(--space-1-5); margin:0; padding:0; list-style:none;}
.breadcrumbs li{display:inline-flex; align-items:center; gap:var(--space-1-5); min-width:0; max-width:100%;}
.breadcrumbs li + li::before{content:'›'; color:var(--color-text-dim);}
.breadcrumbs a, .breadcrumbs span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:min(320px, 70vw);}
.breadcrumbs a{color:var(--color-text-muted); text-decoration:none;}
.breadcrumbs a:hover{color:var(--color-text); text-decoration:underline;}
.breadcrumbs [aria-current]{color:var(--color-text);}

/* =========================================================================
   COMPONENTS
   ========================================================================= */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--space-1-5);
  padding:var(--button-padding-y) var(--button-padding-x); border-radius:var(--button-radius);
  border:1px solid var(--button-border); background:var(--button-bg); color:var(--button-fg);
  font-size:var(--button-font-size); font-weight:700; line-height:1;
  text-transform:uppercase; letter-spacing:.04em;
  cursor:pointer; text-decoration:none;
  transition:border-color var(--duration-base) var(--ease), background var(--duration-base) var(--ease), transform var(--duration-fast) var(--ease), box-shadow var(--duration-base) var(--ease);
}
.btn:hover{border-color:var(--button-hover-border); background:var(--button-hover-bg); text-decoration:none;}
.btn:active{transform:translateY(1px);}
.btn-primary{background:var(--button-primary-bg); border-color:var(--button-primary-bg); color:var(--button-primary-fg); font-weight:800;}
.btn-primary:hover{background:var(--button-primary-hover-bg); border-color:var(--button-primary-hover-bg); box-shadow:0 0 0 3px rgba(212,167,60,.28); transform:translateY(-1px);}
.btn-ghost{background:transparent;}
.btn-ghost:hover{background:var(--color-surface-2);}
.btn-danger{background:var(--button-danger-bg); border-color:var(--button-danger-bg); color:var(--button-danger-fg);}
.btn-danger:hover{background:var(--button-danger-hover-bg); border-color:var(--button-danger-hover-bg);}
.btn-sm{padding:var(--button-padding-y-sm) var(--button-padding-x-sm); font-size:var(--button-font-size-sm);}
.btn:disabled{opacity:.5; cursor:not-allowed; transform:none;}

.card{
  background:var(--card-bg); border:1px solid var(--card-border); border-radius:var(--card-radius);
  padding:var(--card-padding); box-shadow:var(--card-shadow);
}

/* Полноширинная секция-подложка (прожекторы/линии разметки тянутся во весь
   экран); .hero внутри — читаемая колонка по центру, без привязки к
   --container-max сайта. */
.hero-band{position:relative; width:100%; overflow:hidden; background:var(--color-bg);}
/* На десктопе лендинга растягиваем hero под тактическую доску — 3/4
   высоты экрана, контент центрируется по вертикали внутри. Не трогаем
   .hero-band-club (кабинет/страница клуба) — тот вариант короче по
   контенту и не должен раздуваться. */
body.page-landing .hero-band{display:flex; flex-direction:column; justify-content:center;}
@media(min-width:900px){ body.page-landing .hero-band{min-height:75vh;} }
.hero{position:relative; z-index:2; max-width:760px; margin:0 auto; text-align:center; padding:var(--space-16) var(--space-5) var(--space-10);}
.hero h1{font-size:var(--text-5xl); margin:0 0 var(--space-3); text-transform:uppercase;}
.hero p{color:var(--color-text-muted); font-size:var(--text-md); max-width:560px; margin:0 auto var(--space-7); line-height:var(--leading-normal);}
.hero-actions{display:flex; gap:var(--space-3); justify-content:center; flex-wrap:wrap;}
/* Слот кнопок/ближайших матчей (HeroActions.vue) — min-height держит место
   под кнопки, пока currentUser ещё не резолвился (устраняет скачок layout
   при появлении контента, см. useHeroActions.js). #heroActionsApp вынесен
   в index.html СНАРУЖИ .hero (по прямому запросу — карточка "ближайшие
   матчи" должна быть шириной с .container, а не зажата в узкие 760px
   .hero), поэтому здесь же держим горизонтальный gutter вместо .hero
   padding, который эта обёртка больше не наследует. Карточка "ближайшие
   матчи" — тот же .card, что и везде на сайте, но текст в ней должен идти
   слева (.hero центрирует по умолчанию), поэтому явно возвращаем left. */
.hero-actions-slot{min-height:52px; padding:0 var(--space-5);}
.hero-next-match{text-align:left; max-width:var(--container-max); margin:0 auto;}
/* Кнопка "Отправить состав" и ссылка "Карточка матча →" слишком плотно
   стояли рядом (--space-2-5=10px) — по прямому запросу разводим шире
   именно в этой карточке (не трогая общий .fixture-meta, который
   используется по всему сайту в более тесных местах вроде админки). */
.hero-next-match .fixture-meta{gap:var(--space-4);}
.hero-eyebrow{
  font-family:var(--font-display); font-size:var(--text-xs); letter-spacing:.22em; text-transform:uppercase;
  color:var(--teal-300); margin-bottom:var(--space-3);
}

/* ---- Прожекторы: атмосферное свечение фона (только hero лендинга) ---- */
.hero-beam{
  position:absolute; top:-40%; width:38%; height:150%; pointer-events:none; z-index:0;
  background:conic-gradient(from 180deg at 50% 0%, transparent, var(--club-glow-1, var(--glow-1)), transparent 60%);
  animation:heroBeamPulse 7s ease-in-out infinite;
}
.hero-beam.left{left:-4%; transform:rotate(18deg);}
.hero-beam.right{right:-4%; transform:rotate(-18deg); animation-delay:1.4s; background:conic-gradient(from 180deg at 50% 0%, transparent, var(--club-glow-2, var(--glow-2)), transparent 60%);}
@keyframes heroBeamPulse{0%,100%{opacity:.55;} 50%{opacity:1;}}
.hero-pitchlines{
  position:absolute; left:0; right:0; bottom:0; height:220px; pointer-events:none; z-index:0;
  background:repeating-linear-gradient(90deg, var(--color-border) 0 1px, transparent 1px 120px);
  mask-image:linear-gradient(0deg, black, transparent);
}

/* ---- Тактическая доска: анимированная разметка на canvas (только hero
   лендинга) — держим её тише прожекторов/пятен (z-index 1, между фоновыми
   слоями и текстом), чтобы не отвлекать от заголовка/CTA, как уже просил
   пользователь про декоративный фон раньше. */
.hero-tactics-board{position:absolute; inset:0; width:100%; height:100%; z-index:1; pointer-events:none; opacity:.32;}
@media(max-width:640px){ .hero-tactics-board{opacity:.20;} }

/* ---- Декоративная геометрия/тактика — фон лендинга на всю длину страницы ---- */
body.page-landing{
  background-image:url('/img/geo-pattern.svg');
  background-repeat:repeat; background-position:0 0; background-size:1300px 1500px;
}

/* Тот же декоративный фон — на страницах кабинета/клуба (dashboard.html,
   club.html), но перекрашенный под цвет текущего клуба вместо фиксированного
   золото+бирюза лендинга. Отдельный реальный элемент .page-cabinet-bg —
   первый потомок body, position:fixed;z-index:-1 (стандартный паттерн
   «слой фона позади контента», не псевдоэлемент — так надёжнее, не зависит
   от особенностей стекинг-контекста самого body). filter применяется
   ТОЛЬКО к этому слою, не ко всей странице. --club-hue-shift выставляется
   JS (applyClubPattern() в clubGlow.js) — 0deg по умолчанию, пока цвет
   клуба ещё не загружен (пользователь без клуба) — тогда просто исходные
   золото/бирюза, как на лендинге. */
.page-cabinet-bg{
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  background-image:url('/img/geo-pattern.svg');
  background-repeat:repeat; background-position:0 0; background-size:1300px 1500px;
  filter:hue-rotate(var(--club-hue-shift, 0deg));
}

.stat-strip{position:relative; z-index:2; display:flex; justify-content:center; flex-wrap:wrap; border-top:1px solid var(--color-border); border-bottom:1px solid var(--color-border); margin-bottom:var(--space-10);}
.stat{flex:1; min-width:110px; max-width:150px; text-align:center; padding:var(--space-4) var(--space-2); border-right:1px solid var(--color-border); font-variant-numeric:tabular-nums;}
.stat:last-child{border-right:none;}
.stat b{display:block; font-family:var(--font-display); font-size:var(--text-3xl); color:var(--teal-100);}
.stat span{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.06em;}

/* ---- Превью свободных команд/сборных на лендинге (FreeEntitiesPreview.vue) ----
   Выровнены горизонтально в 2 колонки (стек в 1 на узких экранах — тот же
   порог, что и у .features ниже). Список внутри карточки — компактные
   строки (эмблема/флаг + имя + иконка "возглавить"), не крупная плитка
   .club-tile (та рассчитана на десяток игроков сразу на весь экран, тут
   нужна плотная лента ровно на 10 записей). */
/* Лендинг: текст режима (index.html data-mode, index-main.js) — hidden
   должен побеждать display:flex/grid у .stat/.about-game-block и т.п. */
[data-mode][hidden]{display:none !important;}
.free-entities-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); gap:var(--space-4); margin-top:var(--space-8);}
@media(min-width:900px){ .free-entities-grid{margin-top:0;} }
.free-entity-list{display:flex; flex-direction:column; gap:var(--space-2-5);}
.free-entity-row{display:flex; align-items:center; gap:var(--space-2-5);}
.free-entity-name{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:var(--text-sm); font-weight:600;}
.free-entity-applied{flex-shrink:0; font-size:var(--text-xs);}
.free-entity-apply{
  flex-shrink:0; width:28px; height:28px; padding:0; display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--radius-full); border:1px solid var(--button-border); background:transparent; color:var(--color-accent);
  cursor:pointer; transition:background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.free-entity-apply:hover{background:var(--color-accent-subtle); border-color:var(--color-accent);}
.free-entity-apply:disabled{opacity:.5; cursor:default;}
.free-entity-apply svg{width:15px; height:15px;}

.features{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:var(--space-4); margin:var(--space-10) 0;}
.feature-card{
  background:var(--card-bg); border:1px solid var(--card-border); border-radius:var(--card-radius); padding:var(--space-5);
  transition:border-color var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.feature-card:hover{border-color:var(--teal-300); transform:translateY(-2px);}
.feature-card .icon{font-size:26px; margin-bottom:var(--space-2); line-height:0;}
.feature-card h3{margin:0 0 var(--space-1-5); font-size:var(--text-xl); color:var(--color-text);}
.feature-card p{margin:0; color:var(--color-text-muted); font-size:var(--text-sm); line-height:var(--leading-normal);}

.form-group{margin-bottom:var(--space-4);}
.form-group label{display:block; font-size:var(--text-sm); font-weight:600; color:var(--color-text-muted); margin-bottom:var(--space-1-5);}
.form-group input, .form-group select, .form-group textarea{
  width:100%; padding:var(--input-padding-y) var(--input-padding-x); border-radius:var(--input-radius);
  border:1px solid var(--input-border); background:var(--input-bg); color:var(--input-fg); font-size:var(--text-base);
  transition:border-color var(--duration-base) var(--ease), box-shadow var(--duration-base) var(--ease);
}
.form-group textarea{font-family:inherit; resize:vertical;}
.form-group input::placeholder, .form-group textarea::placeholder{color:var(--input-placeholder);}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus{outline:none; border-color:var(--input-focus-border); box-shadow:var(--color-focus-ring);}

.error-box{
  background:var(--color-danger-subtle); border:1px solid var(--color-danger); color:var(--red-300);
  padding:var(--space-2-5) var(--space-3-5); border-radius:var(--radius-md); font-size:var(--text-sm); margin-bottom:var(--space-4); display:none;
}
.error-box.visible{display:block;}
.success-box{
  background:var(--color-success-subtle); border:1px solid var(--color-success); color:var(--color-success);
  padding:var(--space-2-5) var(--space-3-5); border-radius:var(--radius-md); font-size:var(--text-sm); margin-bottom:var(--space-4); display:none;
}
.success-box.visible{display:block;}

.badge{display:inline-flex; align-items:center; gap:var(--space-1-5); padding:var(--badge-padding-y) var(--badge-padding-x); border-radius:var(--badge-radius); font-size:var(--badge-font-size); font-weight:var(--badge-font-weight);}
.badge-pending{background:var(--color-accent-subtle); color:var(--color-accent);}
.badge-approved{background:var(--color-success-subtle); color:var(--color-success);}
.badge-rejected{background:var(--color-danger-subtle); color:var(--red-300);}
.badge-admin{background:rgba(212,167,60,.2); color:var(--color-accent);}
.badge-player{background:rgba(139,147,167,.2); color:var(--color-text-muted);}
.badge-vip{background:var(--color-success-subtle); color:var(--color-success);}
.badge-claimed{background:rgba(92,102,131,.3); color:var(--color-text-dim);}
.badge-open{background:var(--color-success-subtle); color:var(--color-success);}

.club-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:var(--space-2-5); margin-top:var(--space-4);}
.club-tile{
  display:flex; align-items:center; gap:var(--space-2-5); padding:var(--space-3); border-radius:var(--radius-md);
  background:var(--color-surface-2); border:1px solid var(--color-border);
  transition:border-color var(--duration-base) var(--ease);
}
.club-tile-dot{width:var(--space-3); height:var(--space-3); border-radius:var(--radius-full); flex-shrink:0;}
.club-tile-name{flex:1; font-size:var(--text-sm); font-weight:600;}

/* Карточка сборной в "Свободные сборные" (dashboard.html) — своя, не
   .club-tile: там горизontal-ряд (крест+имя+кнопка) — с длинными
   названиями стран ("Босния и Герцеговина", "Республика Корея") и
   кнопкой "Подать заявку" в один ряд на узкой плитке (minmax(180px,1fr))
   текст/кнопка сжимались и переносились уродливо. Здесь — вертикально:
   флаг+имя сверху, кнопка на всю ширину снизу, по прямому запросу
   пользователя после того, как увидел горизонтальный вариант. */
.nation-tile{
  display:flex; flex-direction:column; gap:var(--space-2-5); padding:var(--space-3); border-radius:var(--radius-md);
  background:var(--color-surface-2); border:1px solid var(--color-border);
  transition:border-color var(--duration-base) var(--ease);
}
.nation-tile-head{display:flex; align-items:center; gap:var(--space-2-5); min-width:0;}
.nation-tile-head .club-tile-name{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nation-tile > .btn, .nation-tile > .badge{align-self:stretch; justify-content:center; text-align:center;}

/* Выбор свободного клуба (NoClubView.vue): лиги — отдельной колонкой
   слева (на ≤900px — пилюлями сверху), справа — клубы выбранной лиги
   строками: эмблема · название + состав/стадион · сила (.rating-badge) ·
   заявка. Свободные сверху, занятые — приглушённо ниже. */
.nc-layout{display:grid; grid-template-columns:minmax(200px,250px) 1fr; gap:var(--space-5); margin-top:var(--space-4); align-items:start;}
.nc-col-label{font-size:var(--text-2xs); font-weight:600; text-transform:uppercase; letter-spacing:.07em; color:var(--color-text-dim); padding:0 var(--space-1) var(--space-2);}
.nc-leagues{display:flex; flex-direction:column; gap:var(--space-1-5);}
.nc-league{display:flex; align-items:center; gap:var(--space-2); width:100%; text-align:left; border-radius:var(--radius-sm);}
.nc-league-name{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nc-league-count{font-variant-numeric:tabular-nums; color:var(--color-success); font-weight:700;}
.nc-league-count.none{color:var(--color-text-dim);}
.nc-league-count small{font-size:var(--text-2xs); color:var(--color-text-dim); font-weight:600;}
/* Строки — subgrid одной сетки: колонка кнопки по ширине самой кнопки,
   «занят» и «Подать заявку» одной ширины во всех строках. Крайние
   колонки — auto: паддинг строки-subgrid съедает фиксированную крайнюю
   колонку (28px → 16px под эмблему), к auto — прибавляется. */
.nc-clubs{display:grid; grid-template-columns:auto minmax(0,1fr) auto auto; column-gap:var(--space-3); row-gap:var(--space-1); min-width:0;}
.nc-clubs-head, .nc-club{grid-column:1 / -1; display:grid; grid-template-columns:subgrid; column-gap:var(--space-3); align-items:center; padding:var(--space-1-5) var(--space-3);}
.nc-club{border-radius:var(--radius-sm); background:var(--color-surface-2);}
.nc-clubs-head{padding-top:0; padding-bottom:var(--space-1);}
.nc-clubs-head > span:nth-child(3){text-align:center; cursor:help;}
.nc-club > :first-child{width:28px;}
.nc-club-main{min-width:0;}
.nc-club-name{display:block; font-size:var(--text-sm); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nc-club-meta{font-size:var(--text-xs); color:var(--color-text-dim); font-variant-numeric:tabular-nums; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nc-club-meta span + span::before{content:'·'; margin:0 var(--space-1-5);}
.nc-club-act.badge-claimed{color:var(--color-text-muted);}
.nc-club-str.rating-badge{min-width:38px; height:26px; font-size:1rem;}
.nc-club-act{justify-self:stretch; justify-content:center; text-align:center; white-space:nowrap;}
/* занятые — приглушённо (кроме бейджа «занят», он и так тусклый) */
.nc-club.claimed > :not(.nc-club-act){opacity:.5;}
.nc-club.claimed .nc-club-str.rating-badge{filter:grayscale(.7);}
@media(max-width:900px){
  .nc-layout{grid-template-columns:1fr; gap:var(--space-3);}
  /* лиг до 15 — одной строкой с прокруткой внутри (как .club-tabs), не стеной пилюль */
  .nc-leagues{flex-direction:row; overflow-x:auto; scrollbar-width:none; padding:var(--space-1) var(--space-1) var(--space-2); margin:0 calc(-1 * var(--space-1));}
  .nc-leagues::-webkit-scrollbar{display:none;}
  .nc-leagues .nc-col-label{display:none;}
  .nc-league{flex:none; width:auto; border-radius:999px;}
  .nc-league-name{overflow:visible;}
}

/* Фильтр лиг «Лиг» флагами (FreeClubsPicker.vue, по прямому запросу) —
   отдельно от колонки-нав «Легенд» выше: пилюли флаг+код страны+свободно,
   переносятся по строкам (15 лиг, не одна полоса со скроллом), клубы
   аккордеоном появляются под фильтром при клике по пилюле. */
.nc-flags{display:flex; flex-wrap:wrap; gap:var(--space-1-5); margin-top:var(--space-3);}
.nc-flag-pill{display:inline-flex; align-items:center; gap:var(--space-1-5);}
.nc-flag-pill-img{width:20px; height:14px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 1px var(--color-border); flex-shrink:0;}
.nc-flag-pill-abbr{letter-spacing:.03em;}
.nc-flag-pill-count{font-variant-numeric:tabular-nums; color:var(--color-success); font-weight:700; min-width:1.4em; text-align:center;}
.nc-flag-pill-count.none{color:var(--color-text-dim);}
.nc-flag-pill.active .nc-flag-pill-count{color:inherit;}
@media(max-width:560px){
  /* кнопка — второй строкой под названием, по своей ширине */
  .nc-clubs{grid-template-columns:auto minmax(0,1fr) auto;}
  .nc-club{row-gap:var(--space-1-5); padding:var(--space-2) var(--space-3);}
  .nc-club-act{grid-column:2 / -1; justify-self:start; min-width:9.5rem;}
  .nc-clubs-head > span:nth-child(4){display:none;}
}

table{width:100%; border-collapse:collapse; font-size:var(--text-sm);}
th{text-align:left; color:var(--table-header-fg); font-weight:600; font-size:var(--text-xs); text-transform:uppercase; letter-spacing:.4px; padding:var(--table-cell-padding-y) var(--table-cell-padding-x); border-bottom:1px solid var(--table-border);}
td{padding:var(--table-cell-padding-x); border-bottom:1px solid var(--table-border); vertical-align:middle;}

/* Обёртка для широких таблиц (состав/тренировки) — на узких экранах
   таблица шире контейнера прокручивается сама по себе (только по X),
   вместо горизонтального скролла всей страницы. */
.table-wrap{width:100%; overflow-x:auto;}

/* Турнирная таблица (StandingsTable.vue) на узких экранах — даже внутри
   .table-wrap 8 колонок (#/клуб/И/В/Н/П/Мячи/О) шире типичной карточки
   (~300px), из-за чего самые важные колонки (Мячи/О) оказывались видны
   только после ручного скролла. По прямому запросу — убираем И (играно:
   и так = В+Н+П, последняя по важности) и ограничиваем ширину имени
   клуба многоточием, чтобы остальные 7 колонок, включая Мячи/О, влезали
   без скролла у большинства названий. standings-col-played/
   standings-team-cell проставлены в самом StandingsTable.vue — общие
   для всех 5 мест её использования, правим один раз. */
@media(max-width:480px){
  .standings-col-played{display:none;}
  .standings-table-wrap td, .standings-table-wrap th{padding:var(--space-1-5) var(--space-1);}
  .standings-team-inner{gap:4px;}
  .standings-team-cell .club-link{max-width:72px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:inline-block; vertical-align:middle;}
  .standings-team-cell .manager-icon{display:none !important;}
}
tr:last-child td{border-bottom:none;}
tbody tr{transition:background var(--duration-fast) var(--ease);}
tbody tr:hover{background:var(--table-row-hover-bg);}

/* Зоны плей-офф в таблице (StandingsTable.vue showPlayoffZones) — по
   прямому запросу, регламент ЛЧ 2024/25, цвета следуют РЕАЛЬНЫМ
   последствиям (не симметрично между дивизионами — см. комментарий в
   StandingsTable.vue): зелёный/бирюзовый — прошёл в плей-офф напрямую/
   через стыки (оба дивизиона), красный — ТОЛЬКО настоящий вылет по
   лиговой таблице (только Д1, места 34-36). Места без класса (25-33 у
   Д1, 25-36 у Д2, когда явно НЕ standings-zone-relegated) — обычная
   строка без подсветки: ничего не происходит, красить нечего. box-shadow
   (не border-left) — надёжно рисует левую полосу на <tr> независимо от
   border-collapse, тот же приём, что border-left давал бы непредсказуемо
   на границах ячеек. */
.standings-zone-direct{box-shadow:inset 4px 0 0 var(--color-success); background:var(--color-success-subtle);}
.standings-zone-playin{box-shadow:inset 4px 0 0 var(--teal-500); background:rgba(20,184,166,.12);}
.standings-zone-relegated{box-shadow:inset 4px 0 0 var(--color-danger); background:var(--color-danger-subtle);}
/* Своя строка (DESIGN.md) — золотая заливка и рамка поверх зоны; место,
   очки — цифрами фирменного стиля. */
/* Иконка + текст в ячейке таблицы — flex во внутреннем span, не на <td>
   (на ячейке он ломает табличную раскладку и строки съезжают). */
.standings-team-inner, .cell-flex{display:flex; align-items:center; gap:8px; min-width:0;}
/* Своя строка — заливка и золотые линии тенью (inset), а не border:
   рамка добавляла пиксели и сдвигала строку относительно соседних. */
.standings-table-wrap tr.standings-me td{background:var(--color-primary-subtle); box-shadow:inset 0 1px 0 rgba(212,167,60,.5), inset 0 -1px 0 rgba(212,167,60,.5);}
.standings-table-wrap tr.standings-me td:first-child{box-shadow:inset 3px 0 0 var(--color-primary), inset 0 1px 0 rgba(212,167,60,.5), inset 0 -1px 0 rgba(212,167,60,.5);}
.standings-table-wrap tr.standings-me .club-link{color:var(--color-primary); font-weight:700;}
.standings-table-wrap .standings-pos{color:var(--color-text-dim); font-weight:700;}
.standings-table-wrap .standings-pts{font-family:var(--font-display); font-size:1.05rem; font-weight:700; color:var(--green-400);}
.standings-table-wrap td{font-variant-numeric:tabular-nums;}
.standings-zone-legend{display:flex; flex-wrap:wrap; gap:var(--space-4); margin-bottom:var(--space-3); font-size:var(--text-sm); color:var(--color-text-muted);}
.standings-zone-legend-item{display:flex; align-items:center; gap:var(--space-1-5);}
.standings-zone-dot{width:8px; height:8px; border-radius:1px; transform:rotate(45deg); display:inline-block; margin:0 2px;}
.standings-zone-dot.standings-zone-direct{background:var(--color-success); box-shadow:none;}
.standings-zone-dot.standings-zone-playin{background:var(--teal-500); box-shadow:none;}
.standings-zone-dot.standings-zone-relegated{background:var(--color-danger); box-shadow:none;}

/* flex-wrap — по прямому запросу (5 табов "Турниры" в личном кабинете, у
   двух длинные подписи — "Расписание и результаты"/"Лучшие игроки" — не
   помещаются в одну строку на узких экранах); существующие 3-табовые
   использования (MatchDetailCard.vue) уже помещаются в одну строку и
   визуально не меняются — wrap просто никогда не срабатывает там. */
.tabs{display:flex; flex-wrap:wrap; gap:var(--space-1-5); margin-bottom:var(--space-4-5); border-bottom:1px solid var(--color-border);}
.tab-btn{
  padding:var(--space-2-5) var(--space-4); background:none; border:none; color:var(--color-text-muted); font-size:var(--text-sm); font-weight:600;
  cursor:pointer; border-bottom:2px solid transparent; transition:color var(--duration-base) var(--ease), border-color var(--duration-base) var(--ease);
}
.tab-btn:hover{color:var(--color-text);}
.tab-btn.active{color:var(--color-text); border-bottom-color:var(--color-primary);}
.tab-btn-caret{margin-left:var(--space-1); font-size:10px; opacity:.6;}

/* ---- Подменю вкладок клуба (ClubTabs.vue) — второй ярус разделов
   "Команда"/"Матчи"/"Трансферы"/"Клуб", показывается, пока активен
   пункт раздела. По прямому запросу — пилюли (а не подчёркивание, как у
   основного ряда), чтобы ярус явно читался как уточнение выбора сверху. */
.tabs-sub{display:flex; flex-wrap:wrap; gap:var(--space-1-5); margin:calc(-1 * var(--space-2)) 0 var(--space-4);}
.tab-btn-sub{
  padding:var(--space-1-5) var(--space-3-5); background:var(--color-surface-2); border:1px solid var(--color-border); border-radius:999px;
  color:var(--color-text-muted); font-size:var(--text-sm); font-weight:600; cursor:pointer;
  transition:color var(--duration-base) var(--ease), background var(--duration-base) var(--ease), border-color var(--duration-base) var(--ease);
}
.tab-btn-sub:not(.active):not(:disabled):hover{color:var(--color-text); border-color:var(--color-text-dim);}
.tab-btn-sub.active{color:var(--color-primary); background:var(--color-primary-subtle); border-color:var(--color-primary); box-shadow:0 0 12px rgba(212,167,60,.28);}
.tab-btn-sub:disabled{cursor:default; opacity:.5;}
/* Тактика и стиль клуба на доске состава (TacticsBoard.vue) — по прямому
   запросу те же пилюли, что второй ярус меню клуба. */
.tactics-pills{display:flex; flex-wrap:wrap; gap:var(--space-1-5);}
/* «Автосостав» — главное действие доски: пилюля, всегда подсвеченная. */
.tab-btn-sub--accent{color:var(--color-primary); background:var(--color-primary-subtle); border-color:var(--color-primary);}
.tab-btn-sub.tab-btn-sub--accent:not(.active):not(:disabled):hover{color:var(--color-primary); border-color:var(--color-primary); filter:brightness(1.15);}
/* На телефоне пять разделов — в одну строку. */
@media(max-width:480px){
  .club-tabs{gap:0; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;}
  .club-tabs::-webkit-scrollbar{display:none;}
  .club-tabs .tab-btn{padding:var(--space-2-5) var(--space-2); flex:1 1 auto; white-space:nowrap;}
  .tab-btn-sub{padding:var(--space-1-5) var(--space-3);}
}
@media(max-width:360px){
  .club-tabs .tab-btn{padding:var(--space-2) 5px; font-size:var(--text-xs);}
}

/* ---- Админка: боковое меню ---- */
.admin-layout{display:flex; gap:var(--space-6); align-items:flex-start; margin-top:20px;}
/* Независимый скролл меню и контента (по прямому запросу): обе колонки —
   sticky-панели, прижатые к top:76px (как и раньше у сайдбара), но теперь
   ещё и ограничены по высоте видимой областью — у каждой своя внутренняя
   прокрутка, вместо вытягивания всей страницы в длину при длинной таблице
   справа или раскрытом дереве разделов слева. */
.admin-sidebar{
  flex:0 0 var(--sidebar-width); background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--card-radius);
  padding:var(--space-2-5); position:sticky; top:76px;
  max-height:calc(100dvh - 76px - var(--space-4)); overflow-y:auto;
}
.admin-content{
  flex:1; min-width:0; position:sticky; top:76px;
  max-height:calc(100dvh - 76px - var(--space-4)); overflow-y:auto;
}
.admin-nav-item{
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-2);
  padding:var(--space-2-5) var(--space-3); border-radius:var(--radius-md); cursor:pointer; font-size:var(--text-md); font-weight:600;
  color:var(--color-text-muted); margin-bottom:var(--space-0-5); user-select:none;
  transition:background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.admin-nav-item:hover{background:var(--sidebar-item-hover-bg); color:var(--color-text);}
.admin-nav-item.active{background:var(--sidebar-item-active-bg); color:var(--sidebar-item-active-fg);}
.admin-nav-caret{font-size:10px; transition:transform var(--duration-base) var(--ease); opacity:.6;}
.admin-nav-caret.open{transform:rotate(90deg);}
.admin-nav-children{margin-left:var(--space-2-5); padding-left:var(--space-2-5); border-left:1px solid var(--color-border); display:none;}
.admin-nav-children.open{display:block;}
.admin-nav-child{
  padding:var(--space-2) var(--space-3); border-radius:var(--radius-md); cursor:pointer; font-size:var(--text-sm); color:var(--color-text-muted); margin-top:var(--space-0-5);
  transition:background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.admin-nav-child:hover{background:var(--sidebar-item-hover-bg); color:var(--color-text);}
.admin-nav-child.active{background:var(--sidebar-item-active-bg); color:var(--sidebar-item-active-fg);}
.badge-wip{background:var(--color-accent-subtle); color:var(--color-accent); font-size:10px; padding:var(--space-0-5) 7px; border-radius:var(--badge-radius); font-weight:800; letter-spacing:.3px;}
.wip-panel{text-align:center; padding:var(--space-14) var(--space-5); color:var(--color-text-dim);}
.wip-panel .icon{font-size:34px; margin-bottom:var(--space-2-5);}

/* Плитки инфраструктуры клуба (club.html — стадион/академия/спонсоры/
   магазин/персонал) — компактнее wip-panel (тот рассчитан на целую
   вкладку), несколько штук в ряд внутри вкладки "Общие данные". */
.facility-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:var(--space-2-5);}
.facility-tile{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1-5); text-align:center;
  padding:var(--space-3-5) var(--space-2-5); border-radius:var(--radius-md);
  background:var(--color-surface-2); border:1px solid var(--color-border);
}
.facility-tile-icon{font-size:24px;}
.facility-tile-title{font-weight:700;}

/* ---- Сортируемые заголовки таблиц ---- */
th.sortable{cursor:pointer; user-select:none; transition:color var(--duration-fast) var(--ease);}
th.sortable:hover{color:var(--color-text);}
th.sortable .sort-arrow{margin-left:var(--space-1); opacity:.5; font-size:9px;}
th.sortable.sort-active .sort-arrow{opacity:1; color:var(--color-primary);}

@media(max-width:720px){
  .admin-layout{flex-direction:column;}
  /* в колонке с align-items:flex-start контент иначе растягивается по ширине широкой таблицы */
  /* Телефон/планшет — обратно обычная прокрутка всей страницы: отдельные
     скроллящиеся колонки неудобны на тач-устройстве и сайдбар тут и так
     схлопывается в горизонтальный ряд чипов (см. ниже), ему некуда расти в высоту. */
  .admin-content{width:100%; position:static; max-height:none; overflow-y:visible;}
  /* широкие таблицы (справка «Навыки и формулы» и др.) — прокрутка внутри карточки, не всей страницы */
  .admin-content .card > table, .admin-content .card .mt > table, .admin-content .card table.mt{display:block; max-width:100%; overflow-x:auto;}
  .admin-sidebar{flex:1 1 auto; width:100%; position:static; max-height:none; overflow-y:visible; display:flex; flex-wrap:wrap; gap:var(--space-1);}
  .admin-nav-children{margin-left:0; padding-left:0; border-left:none; display:flex; flex-wrap:wrap; gap:var(--space-1);}
}

@media(max-width:640px){
  .nav{padding:var(--space-3) var(--space-4); flex-wrap:wrap; row-gap:var(--space-2);}
  .nav-links{flex-wrap:wrap; gap:var(--space-2);}
  .nav-logo{font-size:var(--text-xl);}
  .hero{padding:var(--space-10) var(--space-4) var(--space-8);}
  .hero h1{font-size:clamp(26px, 8vw, 38px);}
  .hero-beam{width:80%;}
  .stat-strip{display:grid; grid-template-columns:repeat(2,1fr); gap:var(--space-2-5); border:none; padding:0 var(--space-4); margin-top:var(--space-6); margin-bottom:var(--space-8);}
  .stat{max-width:none; border-right:none; background:rgba(255,255,255,.03); border-radius:var(--radius-md); padding:var(--space-3);}
  .club-hero{flex-direction:column; text-align:center;}

  /* Таблицы с тяжёлыми ячейками (пикеры, select, текстовые прогнозы —
     см. TrainingsSection.vue) горизонтальным скроллом не спасти: колонок
     мало, но каждая сама по себе шире экрана. Вместо .table-wrap-скролла
     строка становится карточкой, ячейка — подписанным полем (подпись из
     заголовка колонки через data-label, см. th.sortable — тот же текст,
     что и в <thead>). Обычные компактные таблицы (состав/легенды) эту
     разметку не подключают — им обычный overflow-x горизонтальный скролл
     подходит лучше (сравнение построчно, не по одной карточке зараз). */
  .table-stack thead{display:none;}
  .table-stack, .table-stack tbody, .table-stack tr{display:block; width:100%;}
  .table-stack tr{
    border:1px solid var(--color-border); border-radius:var(--radius-md);
    padding:var(--space-3); margin-bottom:var(--space-2-5);
  }
  .table-stack tr:last-child{margin-bottom:0;}
  .table-stack td{
    display:block; width:auto; padding:var(--space-1-5) 0; border-bottom:1px dashed var(--color-border);
  }
  .table-stack td:last-child{border-bottom:none;}
  .table-stack td::before{
    content:attr(data-label); display:block; margin-bottom:3px;
    font-size:var(--text-2xs); font-weight:700; text-transform:uppercase; letter-spacing:.4px; color:var(--color-text-dim);
  }

  /* Сворачивание карточки по имени игрока (TrainingsSection.vue) — та же
     .collapse-chevron, что и "Свободные сборные" (NationCard.vue), но на
     уровне строки: .row-detail скрыты по умолчанию (row-collapsed),
     видна только ячейка "Игрок" (плюс "Поз"). Шеврон спрятан вне этого
     media query — на десктопной таблице сворачивания нет, значок не
     нужен. */
  .table-stack td.row-header-cell{cursor:pointer;}
  .table-stack .row-header-inner{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2);}
  .table-stack .row-header-name{flex:1; min-width:0;}
  .table-stack tr.row-collapsed td.row-detail{display:none;}
  .table-stack tr.row-collapsed td.row-header-cell{border-bottom:none;}
  .row-chevron{display:none;}
  .table-stack .row-chevron{display:inline-block; flex-shrink:0;}
}

/* ---- Личный кабинет: hero-блок клуба ----
   .hero-band-club — контейнерный (не на всю ширину экрана, как у лендинга)
   вариант .hero-band: те же анимированные прожекторы, но встроен в обычный
   поток .container, со скруглением и рамкой, как у карточек. Цвет
   прожекторов синхронизирован с фирменным цветом клуба через
   --club-glow-1/--club-glow-2 (проставляются инлайн в renderClubView(),
   dashboard.html) — без переопределения .hero-beam использует дефолтные
   --glow-1/--glow-2 (см. правило выше), поэтому на лендинге ничего не
   меняется. */
.hero-band-club{
  border:1px solid var(--card-border); border-radius:var(--card-radius); margin-bottom:var(--space-6);
}
.club-hero{
  position:relative; z-index:2;
  display:flex; align-items:center; gap:var(--space-5); padding:var(--space-6);
}
.club-hero-badge{position:relative; flex-shrink:0; display:flex; align-items:center; justify-content:center;}
.club-crest{display:block; flex-shrink:0; filter:drop-shadow(0 2px 4px rgba(0,0,0,.35));}
.club-hero-name{margin:0 0 var(--space-1); font-size:var(--text-3xl);}
.club-hero-meta{margin:0; color:var(--color-text-muted); font-size:var(--text-sm);}
/* Финансовая строка hero (по прямому запросу: вилка баланса + стоимость
   состава видны всем, точный баланс — только владельцу, ClubHero.vue) —
   несколько span рядом, не сплошной текст; на мобильном переносятся
   (flex-wrap), а не сжимаются до нечитаемого. */
.club-hero-finance{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-3); margin-top:var(--space-1);}
.club-hero-finance-exact{color:var(--gold); font-weight:600;}

/* ---- Кнопка-иконка редактирования поверх бейджа в hero (эмблема клуба /
   фото игрока) — без подписи, круглая, в углу картинки. ---- */
.hero-edit-btn{
  position:absolute; right:-4px; bottom:-4px; width:26px; height:26px; padding:0;
  display:flex; align-items:center; justify-content:center; border-radius:var(--radius-full);
  background:var(--color-surface-2); border:1px solid var(--color-border); color:var(--color-text);
  cursor:pointer; transition:background var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.hero-edit-btn:hover{background:var(--color-surface-2-hover); transform:scale(1.08);}
.hero-edit-btn svg{width:13px; height:13px; display:block;}

/* ---- Баннер hero-band-club (клуб/сборная, ClubHero.vue/NationHero.vue) ----
   Декоративная PNG-картинка справа от бейджа/имени в том же флекс-ряду
   .club-hero — margin-left:auto прижимает её (и слот-обёртку с кнопкой
   редактирования) к правому краю, max-width:40% — по прямому запросу
   (ограничение относительно ширины всего hero-band-club, не экрана).
   z-index:2 — тот же слой, что у .club-hero (см. выше), поверх прожекторов
   .hero-beam (z-index:0). */
/* .hero-band-banner — max-width:100% ВСЕГДА относительно своего прямого
   родителя: то .club-hero-slot (own, уже ограничен max-width:40% сам),
   то напрямую .club-hero (не-own — тогда ограничение 40% и прижатие
   вправо вешаются на сам img через дочерний селектор ниже, а не задаются
   тут дважды — иначе получилось бы 40% от 40%). */
.hero-band-banner{display:block; max-width:100%; max-height:180px; object-fit:contain; border-radius:var(--radius-md);}
.hero-banner-slot{position:relative; z-index:2; flex-shrink:0; max-width:40%; margin-left:auto;}
.club-hero > img.hero-band-banner{position:relative; z-index:2; flex-shrink:0; max-width:40%; margin-left:auto;}
.hero-banner-placeholder{
  width:160px; height:90px; border-radius:var(--radius-md); border:1px dashed var(--color-border);
  display:flex; align-items:center; justify-content:center; text-align:center; padding:var(--space-2);
  color:var(--color-text-dim); font-size:var(--text-xs); cursor:pointer; background:none;
  transition:border-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.hero-banner-placeholder:hover{border-color:var(--color-accent); color:var(--color-text-muted);}
.hero-edit-panel{margin:0 var(--space-6) var(--space-6); position:relative; z-index:2; background:var(--color-surface-2);}
@media(max-width:640px){
  .hero-banner-slot, .club-hero > img.hero-band-banner{margin-left:0; max-width:60%;}
  .hero-edit-panel{margin:0 var(--space-4) var(--space-4);}
}

/* ---- Карточка игрока (player.html) ---- */
.player-head{display:flex; align-items:center; gap:var(--space-5); flex-wrap:wrap;}
/* Фото — ромб с градиентной рамкой, как ромбы талантов (по прямому
   запросу): фиолетовая с переливом; у игрока из топ-15 лиги по средней
   оценке (player.leagueTopRank, seasonStats.js leagueTopRatedRank) —
   золотая. Рамка — фон ромба, видимый вокруг вложенного ромба с фото. */
/* Ромб — повёрнутый на 45° квадрат со скруглёнными углами (clip-path
   скругления не умеет); сторона = габарит / √2. Перелив — конический
   градиент, вращающийся по рамке (@property --photo-angle), и
   пульсирующее свечение. Фото внутри — обратно повёрнуто и растянуто на
   √2, чтобы заполнить ромб целиком. */
@property --photo-angle{syntax:'<angle>'; initial-value:0deg; inherits:false;}
.player-head-photo{
  --photo-size:174px; --photo-border:7px; --photo-radius:18px;
  --photo-from:#6d28d9; --photo-mid:#f0abfc; --photo-to:#c084fc; --photo-glow:rgba(168,85,247,.55);
  position:relative; flex-shrink:0; width:var(--photo-size); height:var(--photo-size);
  display:flex; align-items:center; justify-content:center;
  animation:photo-glow 3.2s ease-in-out infinite;
}
@media(max-width:640px){ .player-head-photo{--photo-size:160px; --photo-border:6px; --photo-radius:16px;} }
.player-head-photo--top{--photo-from:#a16207; --photo-mid:#fff3b0; --photo-to:#f5b82e; --photo-glow:rgba(245,184,46,.6);}
.player-head-photo-diamond{
  width:calc(var(--photo-size) / 1.4142); height:calc(var(--photo-size) / 1.4142);
  padding:var(--photo-border); box-sizing:border-box; border-radius:var(--photo-radius);
  transform:rotate(45deg);
  background:conic-gradient(from var(--photo-angle), var(--photo-from), var(--photo-to), var(--photo-mid), var(--photo-to), var(--photo-from), var(--photo-to), var(--photo-mid), var(--photo-to), var(--photo-from));
  animation:photo-spin 4s linear infinite;
}
@keyframes photo-spin{to{--photo-angle:360deg;}}
@keyframes photo-glow{
  0%,100%{filter:drop-shadow(0 0 6px var(--photo-glow));}
  50%{filter:drop-shadow(0 0 16px var(--photo-glow));}
}
@media (prefers-reduced-motion: reduce){ .player-head-photo, .player-head-photo-diamond{animation:none;} }
.player-head-photo-clip{
  position:relative; width:100%; height:100%; overflow:hidden;
  border-radius:calc(var(--photo-radius) - var(--photo-border) / 2); background:var(--color-surface-2);
}
.player-head-photo-clip > img, .player-head-photo-placeholder{
  position:absolute; left:-20.71%; top:-20.71%; width:141.42%; height:141.42%;
  transform:rotate(-45deg); object-fit:cover; display:block;
}
.player-head-photo-placeholder{display:flex; align-items:center; justify-content:center; color:var(--color-text-dim);}
.player-head-photo-placeholder svg{width:56px; height:56px;}
/* Кнопка загрузки — на нижней правой грани ромба, а не в пустом углу. */
.player-head-photo .hero-edit-btn{right:calc(var(--photo-size) / 4 - 13px); bottom:calc(var(--photo-size) / 4 - 13px);}
.player-head-photo-rank{
  position:absolute; left:50%; bottom:-6px; transform:translateX(-50%); white-space:nowrap;
  padding:0 6px; border-radius:var(--radius-sm); background:#f5b82e; color:#2a1d00;
  font-size:10px; font-weight:800; line-height:16px; box-shadow:0 1px 3px rgba(0,0,0,.4);
}
.player-head-crest{flex-shrink:0; display:flex; align-items:center; justify-content:center;}
.player-head-info{flex:1; min-width:200px;}
.player-head-name{margin:var(--space-1) 0 var(--space-2); font-size:var(--text-3xl);}
.player-head-tags{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;}
.player-head-flag, .player-flag-inline{width:20px; height:14px; object-fit:cover; border-radius:2px; vertical-align:middle;}
.player-ban{color:var(--color-danger); font-weight:600;}
/* Страница матча: рост талантов за матч (MatchDetailCard.vue, migrations/092) */
.md-talents{display:flex; flex-direction:column; gap:var(--space-1); margin-top:var(--space-2);}
.md-talent-row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; font-size:var(--text-sm); min-width:0;}
.md-talent-icon{width:1.4em; text-align:center;}
.md-talent-lvl{color:var(--gold); font-variant-numeric:tabular-nums;}
.md-talent-awake{color:#c084fc; font-weight:700; font-size:var(--text-2xs); text-transform:uppercase;}

/* Превью матча: пропускающие матч обеих сторон (UpcomingMatchCard.vue) */
.match-susp{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4);}
.match-susp-club{display:flex; align-items:center; gap:var(--space-2); font-weight:600; margin-bottom:var(--space-2); min-width:0;}
.match-susp-club span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.match-susp-row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; padding:2px 0;}
/* Составы свёрнуты по умолчанию — <details>, раскрываются по нажатию на клуб */
.match-squad{align-self:start;}
.match-squad summary{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2); flex-wrap:wrap; cursor:pointer; list-style:none; padding:var(--space-2) var(--space-3); border:1px solid var(--color-border); border-radius:var(--radius-md, 8px);}
.match-squad summary::-webkit-details-marker{display:none;}
.match-squad summary .match-susp-club{margin-bottom:0; flex:1 1 auto;}
.match-squad summary::after{content:'▾'; color:var(--text-muted, inherit); transition:transform .15s;}
.match-squad[open] summary{margin-bottom:var(--space-2);}
.match-squad[open] summary::after{transform:rotate(180deg);}
.match-squad-row{display:flex; align-items:center; gap:var(--space-2); padding:3px 0; border-bottom:1px solid var(--color-border); min-width:0;}
.match-squad-row.out{opacity:.5;}
.match-squad-name{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.match-squad-role{flex-shrink:0; font-size:var(--text-xs);}
.match-squad-ovr{flex-shrink:0; width:2.2em; text-align:right; font-weight:600; font-variant-numeric:tabular-nums;}
@media(max-width:560px){ .match-susp{grid-template-columns:1fr; gap:var(--space-3);} }
.player-head-ovr{
  flex-shrink:0; display:grid; grid-template-columns:auto auto; align-items:baseline; gap:0 var(--space-2);
  text-align:right; font-family:'JetBrains Mono',monospace;
}
.player-head-ovr-val{font-size:var(--text-3xl); font-weight:800; color:var(--pitch-light);}
.player-head-ovr-val.rating-badge{min-width:58px; height:46px; font-size:1.9rem; color:#0b1220; justify-self:end;}
.player-head-pot-val{font-size:var(--text-xl); font-weight:700; color:var(--gold);}
.player-head-ovr-label{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.6px; align-self:center;}
.fatigue-bar-card{height:6px;}
/* Карточка игрока: «Общие данные» слева, «Навыки» справа (PlayerApp.vue). */
/* У .card глобально height:100% (стекло до низа ячейки) — колонки равной
   высоты; отступ сверху — у сетки, а не у карточек, иначе margin-top + 100%
   вылезают на следующую карточку. */
.player-two-col{display:grid; grid-template-columns:minmax(0, 2fr) minmax(0, 3fr); gap:var(--space-5) var(--space-4); margin-top:var(--space-5);}
.player-two-col > .card{margin-top:0;}
@media(max-width:900px){ .player-two-col{grid-template-columns:minmax(0, 1fr);} }
/* Сыгранность / неудобные соперники (журнал п.252) — две равные колонки. */
.player-two-col.player-relations{grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);}
@media(max-width:900px){ .player-two-col.player-relations{grid-template-columns:minmax(0, 1fr);} }
.relations-list{display:flex; flex-direction:column;}
.relation-row{display:grid; grid-template-columns:minmax(0, 1fr) auto; gap:4px 12px; padding:10px 0; border-top:1px solid var(--color-border);}
.relation-row:first-child{border-top:0; padding-top:2px;}
.relation-main{display:flex; align-items:baseline; gap:6px; min-width:0; flex-wrap:wrap; font-weight:600;}
.relation-pos{font-size:11px; font-weight:700; color:var(--color-text-dim); min-width:28px;}
.relation-status{display:flex; flex-direction:column; align-items:flex-end; gap:2px; grid-row:1 / span 2; grid-column:2; justify-content:center;}
.relation-meter{display:flex; align-items:center; gap:8px; grid-column:1;}
.relation-meter-track{position:relative; flex:1; max-width:160px; height:6px; border-radius:3px; background:var(--color-surface-hover); overflow:hidden;}
.relation-meter-fill{position:absolute; inset:0 auto 0 0; background:linear-gradient(90deg, var(--green-500), var(--gold-500)); border-radius:3px;}
.relation-meter-tick{position:absolute; top:0; bottom:0; width:2px; margin-left:-1px; background:var(--color-bg); z-index:1;}
.relation-count, .relation-score{font-size:12px; color:var(--color-text-muted); white-space:nowrap; font-variant-numeric:tabular-nums;}
.relation-duel{display:flex; align-items:baseline; gap:8px; grid-column:1; min-width:0; flex-wrap:wrap;}
.relation-score{font-size:14px;}
.relation-score .neg{color:var(--color-danger);}
.relation-pill{display:inline-block; padding:3px 9px; border-radius:999px; font-size:12px; font-weight:600; white-space:nowrap; cursor:help;
  background:var(--color-surface-hover); color:var(--color-text-muted);}
.relation-pill--ok{background:var(--color-success-subtle); color:var(--color-success);}
.relation-pill--warn{background:var(--color-accent-subtle); color:var(--color-accent);}
.relation-pill--bad{background:var(--color-danger-subtle); color:var(--color-danger);}
@media(max-width:520px){
  .relation-row{grid-template-columns:minmax(0, 1fr);}
  .relation-status{grid-row:auto; grid-column:1; align-items:flex-start;}
  .relation-pill{white-space:normal;}
}
/* Усталость и мораль в шапке карточки игрока (PlayerHeadCard.vue). */
.player-head-meters{display:grid; gap:var(--space-1-5); margin-top:var(--space-2-5); max-width:340px;}
.player-head-meter{display:grid; grid-template-columns:72px 1fr 42px; align-items:center; gap:var(--space-2);}
.player-head-meter-label{font-size:var(--text-xs); color:var(--color-text-muted);}
.player-head-meter-val{font-size:var(--text-sm); text-align:right; font-variant-numeric:tabular-nums;}

/* ---- Карьера игрока: история клубов / прогрессия / сборная (player.html) ---- */
.career-club-row{display:flex; align-items:center; gap:var(--space-3); padding:var(--space-2-5) 0; border-bottom:1px solid var(--color-border);}
.career-club-row:last-child{border-bottom:none;}
.career-club-seasons{flex-shrink:0; width:110px; color:var(--color-text-dim); font-size:var(--text-xs);}
.career-club-info{flex:1; min-width:0;}
.career-club-fee{flex-shrink:0; font-weight:700; color:var(--gold); white-space:nowrap;}
.transfer-move{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;}
.transfer-arrow{color:var(--color-text-dim); flex-shrink:0;}
/* История трансферов клуба (TransfersSection.vue, DESIGN.md): плашка
   направления, тип сделки пилюлей. */
.tr-row{padding:var(--space-2) var(--space-2); border-radius:var(--radius-sm);}
.tr-dir{flex:none; width:64px; text-align:center; padding:2px 0; border-radius:var(--radius-full); font-size:var(--text-2xs); font-weight:700; text-transform:uppercase; letter-spacing:.04em;}
.tr-in .tr-dir{background:var(--color-success-subtle); color:var(--green-400);}
.tr-out .tr-dir{background:var(--color-danger-subtle); color:var(--red-300);}
.tr-type{font-size:var(--text-2xs); color:var(--color-text-dim); padding:1px 8px; border-radius:var(--radius-full); background:var(--color-surface-2);}
@media(max-width:640px){ .tr-row{flex-wrap:wrap;} .tr-dir{width:auto; padding:2px 8px;} }

/* Список сборных (NationsApp.vue) — плитки с флагом. */
.nt-toolbar{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-2) var(--space-3);}
.nt-search{
  width:220px; max-width:100%; padding:var(--space-1-5) var(--space-3); border-radius:var(--radius-full);
  border:1px solid var(--color-border); background:var(--color-surface-2); color:var(--color-text); font:inherit; font-size:var(--text-sm);
}
.nt-search:focus{outline:none; border-color:var(--color-primary);}
.nt-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:var(--space-2);}
.nt-tile{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1-5); padding:var(--space-3) var(--space-2);
  border-radius:var(--radius-md); background:var(--color-surface); border:1px solid var(--color-border); color:var(--color-text); text-align:center;
  transition:border-color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.nt-tile:hover{text-decoration:none; border-color:var(--color-border-strong); transform:translateY(-1px); box-shadow:0 0 16px rgba(212,167,60,.18);}
.nt-tile.free{border-color:rgba(212,167,60,.35);}
.nt-tile.free:hover{border-color:var(--color-primary);}
.nt-flag{width:56px; height:42px; object-fit:cover; border-radius:4px; box-shadow:0 0 0 1px var(--color-border), var(--shadow-sm);}
.nt-name{font-weight:700; font-size:var(--text-sm); line-height:1.25;}
.nt-status{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.06em; font-weight:600;}
.nt-tile.free .nt-status{color:var(--gold-400);}
@media(max-width:640px){ .nt-grid{grid-template-columns:repeat(2, minmax(0, 1fr));} .nt-search{width:100%;} }

/* Табло матча (MatchDetailCard.vue). */
.md-board{
  margin:calc(-1 * var(--card-padding)) calc(-1 * var(--card-padding)) 0; padding:var(--space-5) var(--card-padding) var(--space-4);
  border-radius:var(--card-radius) var(--card-radius) 0 0;
  background:radial-gradient(ellipse at 50% 0, rgba(212,167,60,.14), transparent 70%), linear-gradient(180deg, rgba(33,94,61,.16), transparent);
  border-bottom:1px solid var(--color-border);
}
.md-stage{text-align:center; font-size:var(--text-xs); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:.08em; font-weight:600;}
.md-teams{display:grid; grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr); align-items:center; gap:var(--space-4); max-width:720px; margin:var(--space-3) auto 0;}
.md-team{display:flex; flex-direction:column; align-items:center; gap:var(--space-2); min-width:0; font-weight:700; text-align:center;}
.md-team span{max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.md-score{display:flex; flex-direction:column; align-items:center;}
.md-score b{font-family:var(--font-display); font-size:3rem; line-height:1; letter-spacing:.04em; white-space:nowrap;}
.md-score b i{font-style:normal; color:var(--color-primary); margin:0 .12em;}
.md-score-note{font-size:var(--text-xs); color:var(--color-text-dim); margin-top:4px;}
@media(max-width:640px){
  .md-score b{font-size:2.2rem;}
  .md-team{font-size:var(--text-sm);}
}

/* Страница турнира (TournamentDetailApp.vue) и карточки списка турниров:
   сводка, полоса прогресса сезона. */
.td-stats{margin-top:var(--space-2);}
.td-leader b{display:flex; align-items:center; gap:6px; font-size:1rem;}
.td-leader b > div{flex:none;}
.td-mine{border:1px solid rgba(212,167,60,.45); background:var(--color-primary-subtle);}
.td-mine b{color:var(--color-primary);}
.td-progress{height:4px; margin-top:var(--space-2); border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.td-progress span{display:block; height:100%; border-radius:inherit; background:linear-gradient(90deg, var(--gold-600), var(--gold-400));}
.tournament-card .td-progress{margin-top:var(--space-2-5);}

/* Инфраструктура — плитки зданий вместо вкладок (InfrastructurePane.vue). */
.infra-tiles{display:grid; grid-template-columns:repeat(6, minmax(0, 1fr)); gap:var(--space-2); margin-bottom:var(--space-4);}
.infra-tile{
  position:relative; display:flex; flex-direction:column; align-items:center; gap:3px; min-width:0;
  padding:var(--space-3) var(--space-2) var(--space-2-5); border-radius:var(--radius-md); cursor:pointer;
  background:var(--color-surface); border:1px solid var(--color-border); color:var(--color-text-muted); font:inherit;
  transition:border-color var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.infra-tile:hover{border-color:var(--color-border-strong); color:var(--color-text); transform:translateY(-1px);}
.infra-tile.active{border-color:var(--color-primary); background:linear-gradient(180deg, var(--color-primary-subtle), var(--color-surface)); color:var(--color-text); box-shadow:0 0 18px rgba(212,167,60,.25);}
.infra-tile-icon{font-size:1.5rem; line-height:1.2;}
.infra-tile-name{font-size:var(--text-xs); font-weight:700; text-align:center; line-height:1.25;}
.infra-tile-stars{font-size:var(--text-xs);}
.infra-tile-build{font-size:var(--text-2xs); font-weight:700; color:var(--teal-300);}
@media(max-width:900px){ .infra-tiles{grid-template-columns:repeat(3, minmax(0, 1fr));} }

/* Финансы клуба (FinancesSection.vue). */
.fin{display:flex; flex-direction:column; gap:var(--space-4); min-width:0;}
.fin > *{min-width:0;}
.fin .ov-spark{margin:0;}
.fin-cols{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:var(--space-4); align-items:start;}
.fin-item{display:flex; flex-direction:column; gap:4px; padding:var(--space-2) 0; border-bottom:1px solid var(--color-border);}
.fin-item:last-of-type{border-bottom:0;}
.fin-item-top{display:flex; justify-content:space-between; gap:var(--space-3); font-size:var(--text-sm);}
.fin-item-top b{white-space:nowrap; font-variant-numeric:tabular-nums;}
.fin-track{height:6px; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.fin-fill{display:block; height:100%; border-radius:inherit;}
.fin-fill.in{background:linear-gradient(90deg, var(--green-600), var(--green-400));}
.fin-fill.out{background:linear-gradient(90deg, var(--red-600), var(--red-400));}
.fin-note{font-size:var(--text-2xs); color:var(--color-text-dim);}
@media(max-width:900px){ .fin-cols{grid-template-columns:minmax(0, 1fr);} }

/* Рынок игроков (FreeAgentsSectionStub.vue + public/js/freeAgents.js). */
.fa{display:flex; flex-direction:column; gap:var(--space-3); min-width:0;}
.fa > *{min-width:0;}
.fa-head{display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-3);}
.fa-balance{margin:0; font-size:var(--text-sm); font-weight:700; color:var(--gold-400);}
.fa-balance:empty{display:none;}
.fa-filters{
  display:grid; grid-template-columns:minmax(0, 1fr) auto; gap:var(--space-3); align-items:center;
  padding:var(--space-3) var(--space-4); border-radius:var(--radius-md); background:var(--color-surface); border:1px solid var(--color-border);
}
.fa-filter-age, .fa-filter-skills{grid-column:1 / -1;}
.fa-filter-age .hint{margin:0;}
.fa-table td{vertical-align:middle;}
.fa-table .fa-pos{white-space:nowrap;}
.fa-table .fa-name{min-width:180px;}
.fa-flag{width:18px; height:12px; object-fit:cover; border-radius:2px; margin-right:6px; vertical-align:-1px; box-shadow:0 0 0 1px var(--color-border);}
.fa-table .fa-age{color:var(--color-text-muted);}
.fa-table .fa-ad{white-space:nowrap; color:var(--color-text-muted); font-size:var(--text-xs);}
.fa-table .fa-ad i{font-style:normal; color:var(--color-text-dim); margin:0 2px;}
.fa-table .fa-rating{white-space:nowrap; text-align:center;}
.fa-table .fa-rating .rating-badge{margin-right:6px;}
.fa-table .fa-value{color:var(--gold-400); font-weight:700; white-space:nowrap;}
.fa-fit-badge{display:block; width:fit-content; margin-top:2px; cursor:help;}
.fa-more{display:flex; justify-content:center; margin-top:var(--space-3);}
@media(max-width:640px){
  .fa-filters{grid-template-columns:minmax(0, 1fr); padding:var(--space-3);}
  .fa-filters .roster-sort select{width:100%;}
  /* Телефон — строка в две линии на сетке, без горизонтального скролла:
     [поз] имя            скилл
     [возр] аукцион   стоимость */
  .fa-table thead{display:none;}
  .fa-table, .fa-table tbody{display:block; width:100%;}
  .fa-table tr.fa-row{
    display:grid; grid-template-columns:auto minmax(0, 1fr) auto;
    grid-template-areas:"pos name rating" "age auction value";
    align-items:center; column-gap:var(--space-2-5); row-gap:var(--space-1-5);
    padding:var(--space-2-5) var(--space-1); border-bottom:1px solid var(--color-border);
  }
  .fa-table tr.fa-row td{display:block; padding:0; border:none; min-width:0;}
  .fa-table .fa-ad{display:none !important;}
  .fa-table .fa-pos{grid-area:pos;} .fa-table .fa-name{grid-area:name; min-width:0;}
  .fa-table .fa-rating{grid-area:rating; text-align:right;}
  .fa-table .fa-age{grid-area:age; text-align:left; font-size:var(--text-2xs);}
  .fa-table .fa-age::before{content:'возр. ';}
  .fa-table .fa-auction{grid-area:auction; font-size:var(--text-xs);}
  .fa-table .fa-value{grid-area:value; text-align:right;}
  .fa-table .fa-pos .role-tag{display:none;}
  .fa-table .bid-history-tr, .fa-table .bid-history-tr td{display:block;}
  .fa .table-wrap{overflow:visible;}
}
.chart-legend{display:flex; gap:var(--space-4); flex-wrap:wrap; margin-bottom:var(--space-2); font-size:var(--text-xs); color:var(--color-text-muted);}
.chart-legend-item{display:inline-flex; align-items:center; gap:var(--space-1-5);}
.chart-legend-dot{width:9px; height:9px; border-radius:var(--radius-full); display:inline-block;}
.progression-chart{width:100%; height:auto; display:block;}
/* Компактные карточки графиков игрока (журнал п.212): заголовок и сводка
   в одну строку, легенда и таблица — с минимальными отступами. */
.player-chart-card{padding-top:var(--space-4); padding-bottom:var(--space-3);}
.player-chart-head{display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-3); flex-wrap:wrap; margin-bottom:var(--space-1-5);}
.player-chart-head h2{margin:0; font-size:var(--text-lg);}
.player-chart-summary{display:inline-flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap; font-size:var(--text-sm); color:var(--color-text-muted);}
.player-chart-summary b{color:var(--color-text);}
.player-chart-card .chart-legend{margin-bottom:var(--space-1);}
.player-chart-card .chart-table-toggle{margin-top:var(--space-1);}
.player-chart-card .chart-table-toggle table{margin-top:var(--space-2);}
/* «Роль игрока» (PlayerRoleEffectCard.vue): мини-поле с фитом роли по
   клеткам + описание, ключевые навыки, связки, текущая расстановка. */
.role-card-grid{display:grid; grid-template-columns:260px minmax(0, 1fr); gap:var(--space-6); align-items:start;}
.role-card-grid--gk{grid-template-columns:minmax(0, 1fr);}
@media(max-width:720px){ .role-card-grid{grid-template-columns:minmax(0, 1fr);} .role-map{max-width:320px; width:100%; margin:0 auto;} }
.role-map-title{font-size:var(--text-xs); font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:var(--color-text-dim); margin-bottom:var(--space-2);}
.role-map-pitch{
  position:relative; padding:var(--space-2); border-radius:var(--radius-md);
  background:linear-gradient(180deg, #1f5a37, #17462b); border:1px solid rgba(255,255,255,.12);
  display:grid; gap:4px;
}
.role-map-attack, .role-map-goal{text-align:center; font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:rgba(255,255,255,.55);}
.role-map-row{display:grid; grid-template-columns:repeat(5, 1fr); gap:4px;}
.role-map-cell{
  aspect-ratio:1.25; display:flex; align-items:center; justify-content:center; border-radius:6px;
  font-size:10px; font-weight:800; font-variant-numeric:tabular-nums; color:rgba(255,255,255,.92);
  border:1px solid rgba(255,255,255,.08); cursor:help;
}
.fit-best{background:#22c55e; color:#052e14;}
.fit-good{background:rgba(34,197,94,.45);}
.fit-ok{background:rgba(255,255,255,.1);}
.fit-weak{background:rgba(245,158,11,.5);}
.fit-bad{background:rgba(239,68,68,.6);}
.role-map-cell.current{outline:2px solid #fff; outline-offset:1px; box-shadow:0 0 10px rgba(255,255,255,.6);}
.role-map-legend{display:flex; flex-wrap:wrap; gap:var(--space-1-5) var(--space-3); margin-top:var(--space-2); font-size:var(--text-2xs); color:var(--color-text-muted);}
.role-map-legend-item{display:inline-flex; align-items:center; gap:5px;}
.role-map-legend-item i{width:12px; height:12px; border-radius:3px; display:inline-block;}
.role-map-legend-item i.current-swatch{background:transparent; outline:2px solid #fff; outline-offset:-2px;}
.role-info-head{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2) var(--space-5);}
.role-info-role{display:inline-flex; align-items:center; gap:var(--space-2);}
.role-info-role b{font-size:var(--text-lg);}
.role-info-eff{margin-left:auto; font-size:var(--text-sm); color:var(--color-text-muted);}
.role-info-eff b{margin-left:var(--space-1);}
.role-info-sig{margin:var(--space-3) 0 var(--space-2); color:var(--color-text);}
.role-info-proscons{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-1) var(--space-5);}
@media(max-width:560px){ .role-info-proscons{grid-template-columns:1fr;} }
.role-pros, .role-cons{list-style:none; margin:0; padding:0; display:grid; gap:var(--space-1); font-size:var(--text-sm);}
.role-pros li::before{content:'✓ '; color:var(--color-success); font-weight:800;}
.role-cons li::before{content:'✕ '; color:var(--color-danger); font-weight:800;}
.role-info-block{margin-top:var(--space-4);}
.role-info-block .squad-section-title{margin-bottom:var(--space-2);}
.role-skill-chips{display:flex; flex-wrap:wrap; gap:var(--space-1-5);}
.role-skill-chip{
  display:inline-flex; align-items:baseline; gap:6px; padding:var(--space-1) var(--space-3); border-radius:999px;
  background:var(--color-surface-2); border:1px solid var(--color-border); font-size:var(--text-sm); cursor:help;
}
.role-skill-chip em{font-style:normal; font-weight:800; color:var(--color-success); font-size:var(--text-xs);}
.role-synergy-list{display:grid; gap:var(--space-1-5);}
.role-synergy{display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); font-size:var(--text-sm);}
.role-synergy-partners{display:inline-flex; align-items:center; flex-wrap:wrap; gap:4px;}
.role-synergy b{color:var(--color-success); white-space:nowrap;}
.role-synergy.negative b{color:var(--color-danger);}
.role-now{padding:var(--space-3); border-radius:var(--radius-md); background:var(--color-surface-2); border:1px solid var(--color-border); font-size:var(--text-sm);}
.role-now .squad-section-title{margin-top:0;}
.role-now-fit{display:inline-block; margin-left:var(--space-2); padding:0 6px; border-radius:var(--radius-sm); font-size:var(--text-xs); font-weight:800;}
.role-now-totals{display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--space-1) var(--space-4); margin-top:var(--space-1-5);}
.role-now-totals b.pos{color:var(--color-success);}
.role-now-totals b.neg{color:var(--color-danger);}
/* Подразделы карточки «Общие данные» (PlayerOverviewCard.vue): рыночная
   стоимость, история клубов, трансферы — без своей рамки, через линию. */
.player-subsection{margin-top:var(--space-4); padding-top:var(--space-3-5); border-top:1px solid var(--color-border);}
.player-subsection.player-chart-card{padding-bottom:0;}
.player-subsection-title{margin:0 0 var(--space-2); font-size:var(--text-lg);}
.player-chart-head .player-subsection-title{margin:0;}
.player-subsection .career-club-seasons{width:80px;}
.delta-up{color:var(--color-success); font-weight:700;}
.delta-down{color:var(--color-danger); font-weight:700;}
.caps-summary{display:flex; align-items:center; gap:var(--space-3); margin-bottom:var(--space-3);}
.caps-result-badge{display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px; border-radius:var(--radius-full); font-size:var(--text-2xs); font-weight:800;}
.caps-result-badge.res-W{background:var(--color-success-subtle); color:var(--color-success);}
.caps-result-badge.res-D{background:var(--color-surface-2); color:var(--color-text-dim);}
.caps-result-badge.res-L{background:var(--color-danger-subtle); color:var(--color-danger);}

/* ---- Состав/тактика (портировано из engine/football-manager-mvp.html,
   на токенах дизайн-системы; без командного стиля/интенсивности/матча) ---- */
.squad-select{
  background:var(--color-surface-2); border:1px solid var(--color-border); color:var(--color-text);
  padding:var(--space-2-5) var(--space-3); border-radius:var(--radius-md); font-family:var(--font-body);
  font-size:var(--text-base); font-weight:600;
}
.pos-tag{font-family:'JetBrains Mono',monospace; font-size:var(--text-2xs); font-weight:700; padding:2px var(--space-1-5); border-radius:var(--radius-sm);}
.pos-GK{background:var(--color-accent-subtle); color:var(--color-accent);}
.pos-DF{background:rgba(68,114,202,0.18); color:#7fa4ee;}
.pos-MF{background:var(--color-success-subtle); color:var(--color-success);}
.pos-FW{background:var(--color-danger-subtle); color:var(--red-300);}
.role-tag{
  font-family:'JetBrains Mono',monospace; font-size:var(--text-2xs); font-weight:700; padding:2px var(--space-1-5);
  border-radius:var(--radius-sm); background:var(--color-surface-2); border:1px solid var(--color-border);
  color:var(--color-text-muted); white-space:nowrap;
}
.player-row{cursor:pointer; transition:background var(--duration-fast) var(--ease);}
.player-row:hover{background:var(--color-surface-2);}
.bid-toggle-flat{
  display:inline-block; margin-top:2px; background:none; border:none; padding:0;
  color:var(--color-text-dim); font-size:var(--text-2xs); cursor:pointer;
  transition:color var(--duration-fast) var(--ease);
}
.bid-toggle-flat:hover{color:var(--color-text);}
.bid-history-tr td{background:var(--color-surface-2); padding:0 !important;}
.bid-history-panel{padding:var(--space-2) var(--space-4) var(--space-3);}
.bid-history-item{display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); padding:var(--space-1-5) 0; border-bottom:1px solid var(--color-border); font-size:var(--text-xs);}
.bid-history-item:last-child{border-bottom:none;}
.bid-history-club{font-weight:700; color:var(--color-text);}
.bid-history-amount{font-family:'JetBrains Mono',monospace; color:var(--gold); font-weight:700;}
.bid-history-time{color:var(--color-text-dim); font-size:var(--text-2xs); white-space:nowrap;}

/* ---- Двойной ползунок "от/до" (фильтр возраста, freeAgents.js) ----
   Кастомные div-бегунки + Pointer Events (setPointerCapture) вместо пары
   наложенных <input type="range"> — та версия не давала надёжно
   "зацепить и потащить" (браузер не всегда однозначно решал, какому из
   двух наложенных input отдать указатель). touch-action:none на
   бегунке — иначе на тач-устройствах браузер пытается скроллить страницу
   вместо перетаскивания. */
.fa-range-slider{position:relative; height:24px; margin-top:10px;}
.fa-range-track{position:absolute; top:50%; left:0; right:0; height:4px; margin-top:-2px; background:var(--border); border-radius:2px;}
.fa-range-fill{position:absolute; top:50%; height:4px; margin-top:-2px; background:var(--gold); border-radius:2px;}
.fa-range-thumb{
  position:absolute; top:50%; left:0; width:16px; height:16px; margin-top:-8px; margin-left:-8px;
  border-radius:50%; background:var(--gold); border:2px solid var(--bg); cursor:pointer;
  box-shadow:0 0 0 1px rgba(0,0,0,.3); touch-action:none;
  transition:box-shadow var(--duration-fast) var(--ease);
}
.fa-range-thumb:hover, .fa-range-thumb:focus-visible{box-shadow:0 0 0 1px rgba(0,0,0,.3), 0 0 0 4px rgba(212,167,60,.25);}
.fa-range-thumb.dragging{box-shadow:0 0 0 1px rgba(0,0,0,.3), 0 0 0 5px rgba(212,167,60,.35);}
.player-row-photo{width:22px; height:22px; object-fit:cover; border-radius:var(--radius-sm); vertical-align:middle; margin-right:6px;}
.player-photo-edit-btn{
  background:none; border:none; cursor:pointer; font-size:12px; opacity:.55; padding:2px 4px; vertical-align:middle;
  transition:opacity var(--duration-fast) var(--ease);
}
.player-photo-edit-btn:hover{opacity:1;}
.player-release-btn{
  background:none; border:none; border-radius:50%; cursor:pointer; font-size:12px; opacity:.55; padding:2px 4px; vertical-align:middle;
  transition:opacity var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
}
.player-release-btn:hover{opacity:1; background:var(--color-danger-subtle);}
.player-list-btn:hover{background:rgba(255,200,60,.16);}
/* Трансферный лот в составе (журнал п.235, этап 2) — строка под именем. */
.transfer-badge{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1-5); margin-top:var(--space-1); font-size:var(--text-2xs); line-height:1.3;}
.transfer-badge-tag{
  background:rgba(255,200,60,.16); color:var(--gold); border:1px solid rgba(255,200,60,.35);
  border-radius:999px; padding:1px 8px; font-weight:700; white-space:nowrap;
}
.transfer-badge-info{color:var(--color-text-dim);}
.transfer-badge-cancel{
  background:none; border:1px solid var(--color-border); border-radius:999px; color:var(--color-text-dim);
  cursor:pointer; font-size:inherit; padding:1px 8px;
}
.transfer-badge-cancel:hover{color:var(--color-text); border-color:var(--color-text-dim);}
/* Сплошной фон: стеклянный .card (ниже по файлу) просвечивает страницу под модалкой. */
.card.transfer-list-dialog{background:var(--glass-card-sheen), var(--color-surface); height:auto;}
.transfer-list-dialog .tab-btn.active{color:var(--gold); border-bottom-color:var(--gold); font-weight:800;}
.transfer-list-field{display:flex; flex-direction:column; gap:var(--space-1-5);}
.transfer-list-field input{
  width:100%; max-width:220px; padding:8px 10px; border-radius:6px;
  background:var(--surface2); color:var(--text); border:1px solid var(--border); font-size:16px;
}
.transfer-list-summary{
  padding:var(--space-2-5) var(--space-3); border-radius:var(--radius-md);
  background:rgba(255,200,60,.08); border:1px solid rgba(255,200,60,.25);
}
.transfer-list-rules{margin:var(--space-2-5) 0 0; padding-left:18px; display:flex; flex-direction:column; gap:3px;}
.transfer-list-actions{display:flex; justify-content:flex-end; gap:var(--space-2); flex-wrap:wrap;}
/* Трансферное окно (журнал п.239): открыто — зелёная плашка, закрыто — серая. */
.transfer-list-window, .transfer-window-banner{
  padding:var(--space-2-5) var(--space-3); border-radius:var(--radius-md);
  background:rgba(60,200,120,.08); border:1px solid rgba(60,200,120,.3);
}
.transfer-list-window.closed, .transfer-window-banner.closed{
  background:rgba(150,150,170,.08); border-color:rgba(150,150,170,.3);
}
.transfer-window-banner{margin:var(--space-2-5) 0; font-size:.88rem; line-height:1.45;}
.transfer-window-banner b{color:var(--pitch-light);}
.transfer-window-banner.closed b{color:var(--text);}
/* Админка «Трансферные сделки» (журнал п.237). */
.deal-risk{display:inline-block; min-width:32px; padding:2px 8px; border-radius:999px; font-weight:800; text-align:center; background:var(--color-surface-2);}
.deal-risk.risk-low{color:var(--pitch-light);}
.deal-risk.risk-mid{color:var(--gold); background:rgba(255,200,60,.12);}
.deal-risk.risk-high{color:#fff; background:var(--color-danger);}
.deal-actions{display:flex; flex-wrap:wrap; gap:var(--space-1-5); justify-content:flex-end;}
.deal-details{padding:var(--space-3);}
.deal-reasons{margin:4px 0 0; padding-left:18px; display:flex; flex-direction:column; gap:3px;}
.deal-events{width:100%; font-size:var(--text-2xs);}
.deal-events td{padding:3px 6px; border:none;}
.squad-hint{color:var(--color-text-dim); font-size:var(--text-2xs); margin-top:var(--space-3); text-align:center;}
.squad-section-title{
  font-family:var(--font-display); letter-spacing:.5px; font-size:var(--text-xl); color:var(--color-text);
  margin-bottom:var(--space-2); padding-bottom:var(--space-2); border-bottom:1px solid var(--color-border);
}
.talent-icon-mini{margin-left:var(--space-1-5); font-size:14px; cursor:help;}
/* Таблица состава клуба (SquadTable.vue). ПК — узкие колонки чисел по
   центру, имя забирает остаток ширины, действия прижаты вправо. */
.squad-table th.sq-age, .squad-table th.sq-ovr, .squad-table th.sq-pot,
.squad-table td.sq-age, .squad-table td.sq-ovr, .squad-table td.sq-pot{width:72px; text-align:center; font-variant-numeric:tabular-nums;}
.squad-table th.sq-pot, .squad-table td.sq-pot{width:96px;}
.squad-table .sq-pos{width:1%; white-space:nowrap;}
.squad-table .sq-talents{width:28%;}
.squad-table--national .sq-talents{width:22%;}
.squad-table .sq-club{white-space:nowrap;}
.squad-table .sq-actions{width:1%; white-space:nowrap; text-align:right;}
.squad-table td{vertical-align:middle;}
.squad-table td.sq-ovr{font-weight:800; color:var(--pitch-light);}
.squad-table td.sq-pot{font-weight:700; color:var(--gold);}
.squad-table td.sq-age{color:var(--color-text-muted);}
.sq-pos-inner{display:inline-flex; align-items:center; gap:var(--space-1-5);}
.sq-name-line{display:inline-flex; align-items:center; min-width:0;}
/* Телефон — строка из двух линий на сетке:
   [поз] имя              Скилл Потенциал
   [поз] возраст таланты  действия */
@media(max-width:640px){
  .squad-table thead{display:none;}
  .squad-table, .squad-table tbody{display:block; width:100%;}
  .squad-table tr{
    display:grid; grid-template-columns:auto auto 1fr auto auto;
    grid-template-areas:"pos name name ovr pot" "pos age tal act act";
    align-items:center; column-gap:var(--space-2-5); row-gap:var(--space-1);
    padding:var(--space-2-5) var(--space-1); border-bottom:1px solid var(--color-border);
  }
  .squad-table td{display:block; padding:0; border:none; width:auto !important; min-width:0;}
  .squad-table td.sq-pos{grid-area:pos; align-self:start;}
  .squad-table .sq-pos-inner{flex-direction:column; align-items:flex-start; gap:var(--space-1);}
  .squad-table td.sq-name{grid-area:name; font-weight:600;}
  .squad-table td.sq-age{grid-area:age; text-align:left; font-size:var(--text-xs);}
  .squad-table td.sq-age::before{content:'возраст '; color:var(--color-text-dim);}
  .squad-table td.sq-talents{grid-area:tal;}
  .squad-table td.sq-ovr{grid-area:ovr;}
  .squad-table td.sq-pot{grid-area:pot;}
  .squad-table td.sq-ovr::before, .squad-table td.sq-pot::before{
    content:attr(data-label); display:block; font-size:9px; font-weight:700; letter-spacing:.04em; color:var(--color-text-dim);
  }
  .squad-table td.sq-actions{grid-area:act; text-align:right;}
  /* Сборная (NationalSquadTable.vue) — без действий, с клубом:
     [поз] имя              Скилл Потенциал
     [поз] клуб
     [поз] возраст таланты */
  .squad-table--national tr{grid-template-areas:"pos name name ovr pot" "pos club club ovr pot" "pos age tal tal tal";}
  .squad-table--national td.sq-club{grid-area:club; font-size:var(--text-xs); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
}
/* ---- Список состава клуба (SquadTable.vue, DESIGN.md) ----
   Строки на CSS-сетке: игрок (аватар+имя+мета) | таланты | состояние |
   стоимость | скилл | действия. Телефон (≤640px) — три линии:
   игрок…скилл / состояние, стоимость, действия / таланты. */
.roster{display:flex; flex-direction:column; gap:var(--space-3); min-width:0; max-width:100%;}
.roster > *{min-width:0;}
.roster-summary{display:grid; grid-template-columns:repeat(5, minmax(0, 1fr)); gap:var(--space-2);}
.roster-stat{
  display:flex; flex-direction:column; gap:1px; min-width:0; padding:var(--space-2) var(--space-3);
  border-radius:var(--radius-sm); background:var(--color-surface-2);
}
.roster-stat b{font-family:var(--font-display); font-size:1.3rem; font-weight:700; line-height:1.2; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.roster-stat span{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.06em; font-weight:600; white-space:nowrap;}

.roster-toolbar{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-2) var(--space-3);}
.roster-filters{display:flex; flex-wrap:wrap; gap:var(--space-1-5);}
.roster-filters .tab-btn-sub{display:inline-flex; align-items:center; gap:6px;}
.roster-count{font-size:var(--text-2xs); opacity:.7; font-variant-numeric:tabular-nums;}
.roster-dot{width:7px; height:7px; border-radius:1px; transform:rotate(45deg); display:inline-block;}
.pos-dot-GK{background:var(--pos-gk); box-shadow:0 0 6px var(--pos-gk);} .pos-dot-DF{background:var(--pos-df); box-shadow:0 0 6px var(--pos-df);}
.pos-dot-MF{background:var(--pos-mf); box-shadow:0 0 6px var(--pos-mf);} .pos-dot-FW{background:var(--pos-fw); box-shadow:0 0 6px var(--pos-fw);}
.roster-sort select{
  appearance:none; padding:var(--space-1-5) var(--space-6) var(--space-1-5) var(--space-3);
  border-radius:var(--radius-full); border:1px solid var(--color-border); color:var(--color-text);
  font:inherit; font-size:var(--text-xs); font-weight:600; cursor:pointer;
  background:var(--color-surface-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238b93a7' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 10px center;
}
.roster-sort select:focus{outline:none; border-color:var(--color-primary);}

.roster-list{display:flex; flex-direction:column;}
.roster-head, .roster-row{
  display:grid; align-items:center; column-gap:var(--space-3);
  grid-template-columns:minmax(0, 2.6fr) minmax(0, 1.2fr) 112px 104px 92px;
}
.roster--actions .roster-head, .roster--actions .roster-row{grid-template-columns:minmax(0, 2.6fr) minmax(0, 1.2fr) 112px 104px 92px 96px;}
/* Без талантов у всего состава — колонки нет. */
.roster--no-tal .rh-tal, .roster--no-tal .roster-tal{display:none;}
.roster--no-tal .roster-head, .roster--no-tal .roster-row{grid-template-columns:minmax(0, 1fr) 140px 120px 92px;}
.roster--no-tal.roster--actions .roster-head, .roster--no-tal.roster--actions .roster-row{grid-template-columns:minmax(0, 1fr) 140px 120px 92px 96px;}
.roster-head{
  padding:0 var(--space-3) var(--space-2); border-bottom:1px solid var(--color-border);
  font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; font-weight:600; color:var(--color-text-dim);
}
.rh-value, .rh-rating{text-align:center;}
.roster-group{
  display:flex; align-items:baseline; gap:var(--space-2); padding:var(--space-3) var(--space-3) var(--space-1-5);
  border-bottom:1px solid var(--color-border);
}
.roster-group-name{font-family:var(--font-display); font-size:var(--text-md); letter-spacing:.04em; text-transform:uppercase;}
.roster-group-meta{font-size:var(--text-2xs); color:var(--color-text-dim);}
.roster-group-GK .roster-group-name{color:var(--pos-gk);} .roster-group-DF .roster-group-name{color:#7fa4ee;}
.roster-group-MF .roster-group-name{color:var(--pos-mf);} .roster-group-FW .roster-group-name{color:#f87171;}

.roster-row{position:relative; padding:var(--space-2) var(--space-3); border-bottom:1px solid var(--color-border);}
.roster-row::before{content:''; position:absolute; left:0; top:8px; bottom:8px; width:3px; border-radius:2px; background:transparent;}
.roster-row.roster-pos-GK::before{background:var(--pos-gk);} .roster-row.roster-pos-DF::before{background:var(--pos-df);}
.roster-row.roster-pos-MF::before{background:var(--pos-mf);} .roster-row.roster-pos-FW::before{background:var(--pos-fw);}

.roster-player{display:flex; align-items:center; gap:var(--space-3); min-width:0;}
/* Аватар игрока — ромб (фирменная фигура, DESIGN.md §4, как фото на
   карточке игрока и таланты): рамка цвета позиции (::before) и свечение
   тем же цветом. Ромб — clip-path, поэтому флаг (не обрезанный сосед)
   висит у нижней вершины. */
.roster-avatar{
  --ring:var(--color-border-strong); --dmd:polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  position:relative; flex:none; width:46px; height:46px;
  filter:drop-shadow(0 0 5px color-mix(in srgb, var(--ring) 55%, transparent));
}
.roster-avatar::before{content:''; position:absolute; inset:0; background:var(--ring); clip-path:var(--dmd);}
/* Явные размеры, не inset+auto: у <img> width/height:auto = натуральный
   размер фото, и оно вылезало из аватара на пол-экрана (баг-репорт). */
.roster-avatar > img:first-child, .roster-initials{
  position:absolute; left:3px; top:3px; width:calc(100% - 6px); height:calc(100% - 6px);
  clip-path:var(--dmd); object-fit:cover; object-position:center top;
  display:grid; place-items:center; background:var(--color-bg-elevated);
}
.roster-initials{background:var(--color-bg-elevated); font-family:var(--font-display); font-size:.85rem; color:var(--color-text);}
.pos-ring-GK{--ring:var(--pos-gk);} .pos-ring-DF{--ring:var(--pos-df);}
.pos-ring-MF{--ring:var(--pos-mf);} .pos-ring-FW{--ring:var(--pos-fw);}
.roster-flag{position:absolute; left:50%; bottom:-5px; transform:translateX(-50%); width:18px; height:12px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 2px var(--color-surface);}
.roster-id{display:flex; flex-direction:column; gap:3px; min-width:0;}
.roster-name{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1-5); font-weight:600; min-width:0;}
.roster-name > a{overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%;}
.roster-meta{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1-5);}
.roster-age{font-size:var(--text-xs); color:var(--color-text-muted);}
.roster-chip{padding:0 6px; border-radius:var(--radius-full); font-size:var(--text-2xs); font-weight:700; line-height:1.6; white-space:nowrap;}
.roster-chip.xi{background:var(--color-primary-subtle); color:var(--color-primary);}
.roster-chip.bench{background:var(--color-surface-2); color:var(--color-text-dim);}
.roster-chip.injury{background:var(--color-danger-subtle); color:var(--red-300); cursor:help;}

.roster-cond{display:flex; flex-direction:column; gap:5px;}
.roster-meter{display:grid; grid-template-columns:34px 1fr; align-items:center; gap:6px; cursor:help;}
.roster-meter-label{font-size:var(--text-2xs); color:var(--color-text-dim);}
.roster-meter-track{height:5px; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.roster-meter-fill{display:block; height:100%; border-radius:inherit;}
.roster-meter-fill.ok{background:var(--green-500);}
.roster-meter-fill.warn{background:var(--gold-500);}
.roster-meter-fill.bad{background:var(--red-500);}

.roster-value{display:flex; flex-direction:column; align-items:center; gap:1px; font-variant-numeric:tabular-nums;}
.roster-value b{font-size:var(--text-sm); white-space:nowrap;}
.roster-value span{font-size:var(--text-2xs); color:var(--color-text-dim); white-space:nowrap;}

.roster-rating{display:flex; align-items:center; justify-content:center; gap:var(--space-2);}
.rating-badge{
  display:inline-grid; place-items:center; min-width:38px; height:30px; padding:0 6px; border-radius:var(--radius-sm);
  font-family:var(--font-display); font-size:1.15rem; font-weight:700; line-height:1; color:#0b1220;
  font-variant-numeric:tabular-nums;
}
/* rb-* — не rating-*: .rating-good/mid уже красят текст оценок за матч. */
.rb-elite{background:linear-gradient(160deg, #f6dd8f, var(--rating-elite) 55%, #c9a227); box-shadow:0 0 0 1px rgba(233,196,106,.5), 0 0 12px rgba(233,196,106,.25);}
.rb-great{background:var(--rating-great);}
.rb-good{background:var(--rating-good);}
.rb-mid{background:var(--rating-mid);}
.rb-low{background:var(--rating-low);}
.rb-poor{background:var(--rating-poor);}
.roster-pot{font-size:var(--text-xs); font-weight:700; color:var(--color-text-dim); white-space:nowrap; font-variant-numeric:tabular-nums; cursor:help;}
.roster-pot.grow{color:var(--gold-400);}

.roster-act{display:flex; justify-content:flex-end; gap:4px;}
.roster-btn{
  display:grid; place-items:center; width:28px; height:28px; padding:0; border-radius:var(--radius-sm);
  border:1px solid var(--color-border); background:var(--color-surface-2); font-size:14px; cursor:pointer;
  opacity:.75; transition:opacity var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
}
.roster-btn:hover{opacity:1; border-color:var(--color-text-dim);}
.roster-btn.danger:hover{border-color:var(--color-danger); background:var(--color-danger-subtle);}

@media(max-width:900px){
  .roster-summary{grid-template-columns:repeat(3, minmax(0, 1fr));}
  .roster-head{display:none;}
  /* Фиксированные ширины колонок 2–3: с auto растянутый на две колонки
     блок игрока отдавал свою ширину auto-колонке, и «состояние» в первой
     схлопывалось до нуля. */
  .roster-row, .roster--actions .roster-row,
  .roster--no-tal .roster-row, .roster--no-tal.roster--actions .roster-row{
    grid-template-columns:minmax(0, 1fr) 92px 96px;
    grid-template-areas:"player player rating" "cond value act" "tal tal tal";
    row-gap:var(--space-2); padding:var(--space-2-5) var(--space-2) var(--space-2-5) var(--space-3);
  }
  .roster-player{grid-area:player;} .roster-rating{grid-area:rating;}
  .roster-cond{grid-area:cond; max-width:220px;} .roster-value{grid-area:value; align-items:flex-end;}
  .roster-act{grid-area:act;} .roster-tal{grid-area:tal;}
  .roster-tal:has(.squad-talents-none){display:none;}
  .roster-row:not(:has(.roster-act)){grid-template-areas:"player player rating" "cond cond value" "tal tal tal";}
  .roster-rating{justify-content:flex-end;}
  .roster-name > a{white-space:normal;}
}
@media(max-width:640px){
  .roster-summary{grid-template-columns:repeat(2, minmax(0, 1fr));}
  .roster-summary .roster-stat:first-child{grid-column:1 / -1; flex-direction:row; align-items:baseline; gap:var(--space-2);}
  .roster-filters{flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; min-width:0; max-width:100%;}
  .roster-filters::-webkit-scrollbar{display:none;}
  .roster-filters .tab-btn-sub{flex:none;}
  .roster-toolbar{flex-direction:column; align-items:stretch;}
  .roster-sort select{width:100%;}
  .roster-avatar{width:38px; height:38px;}
  .roster-cond{max-width:none;}
}

/* ---- Вкладка «Тренировки» (TrainingsSection.vue, DESIGN.md) ----
   Сводка .tb-stat, правила раскрывашкой, фильтр пилюлями, группы по
   позициям и строки на сетке — как «Состав» (.roster-*). */
.trn{display:flex; flex-direction:column; gap:var(--space-3); min-width:0;}
.trn > *{min-width:0;}
.trn-stats{margin-top:var(--space-2);}
.tb-stat.trn-warn b{color:var(--gold-400);}
.tb-stat.trn-bad b{color:var(--red-400);}
.trn-rules{padding:var(--space-3) var(--space-4);}
.trn-rules > summary.tb-card-title{font-size:var(--text-md);}
.trn-rules-list{margin:0; padding-left:1.1em; display:flex; flex-direction:column; gap:4px; font-size:var(--text-xs); color:var(--color-text-muted);}
.trn-rules-list b{color:var(--color-text);}
.trn-list{display:flex; flex-direction:column;}
.trn-head, .trn-row{
  display:grid; align-items:center; column-gap:var(--space-3);
  grid-template-columns:minmax(0, 1.5fr) 110px 300px minmax(140px, .9fr) minmax(0, 1fr) 30px;
}
.trn-head{
  padding:0 var(--space-3) var(--space-2); border-bottom:1px solid var(--color-border);
  font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; font-weight:600; color:var(--color-text-dim);
}
.trn-row{position:relative; padding:var(--space-2) var(--space-3); border-bottom:1px solid var(--color-border);}
.trn-row::before{content:''; position:absolute; left:0; top:8px; bottom:8px; width:3px; border-radius:2px;}
.trn-row.roster-pos-GK::before{background:var(--pos-gk);} .trn-row.roster-pos-DF::before{background:var(--pos-df);}
.trn-row.roster-pos-MF::before{background:var(--pos-mf);} .trn-row.roster-pos-FW::before{background:var(--pos-fw);}
.trn-row.open{background:rgba(255,255,255,.02); border-bottom-color:transparent;}
.trn-player .roster-avatar{width:36px; height:36px;}
.trn-fatigue{display:grid; grid-template-columns:1fr auto; align-items:center; gap:6px; cursor:help;}
.trn-fatigue-val{font-size:var(--text-xs); font-weight:700; font-variant-numeric:tabular-nums;}
.trn-fatigue-val.ok{color:var(--green-400);} .trn-fatigue-val.warn{color:var(--gold-400);} .trn-fatigue-val.bad{color:var(--red-400);}
.trn-level{display:flex; flex-direction:column; gap:3px; min-width:0;}
.trn-sub{font-size:var(--text-2xs); color:var(--color-text-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.trn-select{
  appearance:none; width:100%; padding:var(--space-1-5) var(--space-6) var(--space-1-5) var(--space-3);
  border-radius:var(--radius-full); border:1px solid var(--color-border); color:var(--color-text);
  font:inherit; font-size:var(--text-xs); font-weight:600; cursor:pointer;
  background:var(--color-surface-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238b93a7' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 10px center;
}
.trn-select:focus{outline:none; border-color:var(--color-primary);}
.trn-select.empty{border-color:rgba(212,167,60,.55); color:var(--gold-400);}
.trn-progress{display:flex; flex-direction:column; gap:3px; min-width:0;}
.trn-progress-top{display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-2);}
.trn-skill-now{font-family:var(--font-display); font-size:1.05rem; line-height:1.1;}
.trn-gain{margin-left:4px; font-family:var(--font-body); font-size:var(--text-2xs); color:var(--green-400);}
.trn-bar{height:6px;}
.trn-bar-fill{background:linear-gradient(90deg, var(--gold-600), var(--gold-400));}
.trn-warn-text{font-size:var(--text-xs); color:var(--gold-400);}
.trn-expand svg{width:16px; height:16px; transition:transform var(--duration-fast) var(--ease);}
.trn-expand svg.open{transform:rotate(180deg);}
.trn-skills{padding:0 var(--space-3) var(--space-3) var(--space-5); border-bottom:1px solid var(--color-border); background:rgba(255,255,255,.02);}
@media(max-width:1100px){
  .trn-head{display:none;}
  .trn-row{
    grid-template-columns:minmax(0, 1fr) 30px;
    grid-template-areas:"player expand" "level level" "skill skill" "progress progress" "fatigue fatigue";
    row-gap:var(--space-2); padding:var(--space-2-5) var(--space-2) var(--space-2-5) var(--space-3);
  }
  .trn-player{grid-area:player;} .trn-expand{grid-area:expand; align-self:start;}
  .trn-level{grid-area:level;} .trn-skill{grid-area:skill;} .trn-progress{grid-area:progress;}
  .trn-fatigue{grid-area:fatigue;}
  .trn-fatigue::before{content:'Усталость'; grid-column:1 / -1; font-size:var(--text-2xs); color:var(--color-text-dim); margin-bottom:-4px;}
  .trn-skills{padding:0 var(--space-2) var(--space-3);}
}
@media(min-width:641px) and (max-width:1100px){
  .trn-row{
    grid-template-columns:minmax(0, 1fr) minmax(0, 1fr) 30px;
    grid-template-areas:"player fatigue expand" "level skill skill" "progress progress progress";
  }
}
@media(max-width:640px){
  .trn-filters{flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;}
  .trn-filters::-webkit-scrollbar{display:none;}
  .trn-filters .tab-btn-sub{flex:none;}
  .trn-stats{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr));}
  .trn-stats .tb-stat{min-width:0; padding:var(--space-1-5) var(--space-2);}
  .trn-stats .tb-stat span{white-space:normal; line-height:1.2;}
  .training-picker{display:flex; width:100%;}
}

/* ---- Вкладка «Лучшие игроки» (TopPlayersSection.vue, DESIGN.md) ----
   Пьедестал топ-3 (золото/серебро/бронза), ниже — список с полосой
   относительно лидера по выбранному показателю. */
.top{display:flex; flex-direction:column; gap:var(--space-3); min-width:0;}
.top > *{min-width:0;}
.top .tb-stats{margin-top:var(--space-2);}
.top-podium{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:var(--space-3); align-items:end;}
.top-card{
  --place:#8b93a7;
  position:relative; display:flex; flex-direction:column; align-items:center; gap:var(--space-1-5); min-width:0;
  padding:var(--space-5) var(--space-3) var(--space-4); border-radius:var(--radius-md); text-align:center;
  background:linear-gradient(180deg, color-mix(in srgb, var(--place) 16%, transparent), var(--color-surface) 70%);
  border:1px solid color-mix(in srgb, var(--place) 45%, var(--color-border));
}
.top-card.place-gold{--place:#e9c46a; order:2; padding-top:var(--space-8); box-shadow:0 0 24px rgba(233,196,106,.12);}
.top-card.place-silver{--place:#c0c7d4; order:1;}
.top-card.place-bronze{--place:#cd8a4f; order:3;}
.top-place{
  position:absolute; top:-12px; left:50%; transform:translateX(-50%);
  display:grid; place-items:center; width:30px; height:30px;
  clip-path:polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  background:var(--place); color:#0b1220; font-family:var(--font-display); font-weight:700; font-size:.95rem;
}
.top-avatar{width:72px; height:72px;}
.top-avatar .roster-initials{font-size:1.2rem;}
.place-gold .top-avatar{width:88px; height:88px; filter:drop-shadow(0 0 10px rgba(233,196,106,.55));}
/* Свечение номера места — снаружи ромба (clip-path обрезал бы тень). */
.top-card{isolation:isolate;}
.top-card::after{
  content:''; position:absolute; top:-12px; left:50%; width:30px; height:30px; transform:translateX(-50%);
  background:var(--place); filter:blur(10px); opacity:.55; z-index:-1;
}
.top-card-name{font-weight:700; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.top-card-meta{justify-content:center;}
.top-card-value{display:flex; flex-direction:column; align-items:center; line-height:1;}
.top-card-value b{font-family:var(--font-display); font-size:2.1rem; color:var(--place);}
.place-gold .top-card-value b{font-size:2.6rem;}
.top-card-value small{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.06em; margin-top:2px;}
.top-card-stats{display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:4px var(--space-2-5); font-size:var(--text-xs); color:var(--color-text-muted);}
.rating-badge.top-mini{min-width:32px; height:20px; font-size:.8rem; font-style:normal;}

.top-list{display:flex; flex-direction:column;}
.top-row{
  position:relative; display:grid; align-items:center; gap:var(--space-3);
  grid-template-columns:28px minmax(0, 1.4fr) minmax(0, 1fr) 56px;
  padding:var(--space-2) var(--space-3); border-bottom:1px solid var(--color-border);
}
.top-row::before{content:''; position:absolute; left:0; top:8px; bottom:8px; width:3px; border-radius:2px;}
.top-row.roster-pos-GK::before{background:var(--pos-gk);} .top-row.roster-pos-DF::before{background:var(--pos-df);}
.top-row.roster-pos-MF::before{background:var(--pos-mf);} .top-row.roster-pos-FW::before{background:var(--pos-fw);}
.top-rank{font-family:var(--font-display); font-size:1.1rem; color:var(--color-text-dim); text-align:center;}
.top-row-avatar{width:36px; height:36px;}
.top-bar{height:6px; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.top-bar-fill{display:block; height:100%; border-radius:inherit; background:linear-gradient(90deg, var(--gold-600), var(--gold-400));}
.top-row-value{display:flex; justify-content:center;}
.top-row-value i{font-style:normal;}
.top-row-value b{font-family:var(--font-display); font-size:1.2rem;}
@media(max-width:640px){
  .top .tb-stats{display:grid; grid-template-columns:repeat(4, minmax(0, 1fr));}
  .top .tb-stat{min-width:0; padding:var(--space-1-5) var(--space-2);}
  .top-podium{gap:var(--space-1-5);}
  .top-card{padding:var(--space-4) var(--space-1-5) var(--space-3);}
  .top-card.place-gold{padding-top:var(--space-6);}
  .top-avatar, .place-gold .top-avatar{width:48px; height:48px;}
  .top-card-name{font-size:var(--text-xs);}
  .top-card-meta .role-tag, .top-card-meta .roster-age{display:none;}
  .top-card-value b{font-size:1.6rem;} .place-gold .top-card-value b{font-size:1.9rem;}
  .top-card-stats{font-size:var(--text-2xs); gap:2px var(--space-1-5);}
  .top-card-stats span:last-child{display:none;}
  .top-row{
    grid-template-columns:22px minmax(0, 1fr) 52px; grid-template-areas:"rank player value" "rank bar bar";
    row-gap:var(--space-1-5); padding:var(--space-2);
  }
  .top-rank{grid-area:rank;} .top-row .roster-player{grid-area:player;}
  .top-bar{grid-area:bar;} .top-row-value{grid-area:value;}
}

/* Колонка «Таланты». */
.squad-talents{display:inline-flex; flex-wrap:wrap; gap:var(--space-1) var(--space-2-5);}
.squad-talent{display:inline-flex; align-items:baseline; gap:3px; font-size:15px; white-space:nowrap; cursor:help;}
.squad-talent-level{font-size:var(--text-2xs); font-weight:700; color:var(--gold); font-variant-numeric:tabular-nums;}
.squad-talents-none{color:var(--color-text-dim);}
.email-prefs-list{display:flex; flex-direction:column; gap:var(--space-2);}
.email-pref-row{display:flex; align-items:center; gap:var(--space-2); cursor:pointer;}

/* ---- Вкладка «Обзор» клуба (ClubOverview.vue) ----
   Плитки-показатели (4 в ряд, на телефоне 2×2) + сетка из двух колонок
   карточек (ближайший матч/форма | окно таблицы/лидеры), ≤900px — одна. */
.ov{display:flex; flex-direction:column; gap:var(--space-4);}
.ov-tiles{display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:var(--space-3);}
.ov-tile{
  position:relative; display:flex; flex-direction:column; gap:2px; min-width:0; overflow:hidden;
  padding:var(--space-3) var(--space-4); border-radius:var(--radius-md);
  background:linear-gradient(160deg, var(--color-surface-2), var(--color-surface)); border:1px solid var(--color-border);
}
.ov-tile::before{content:''; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--color-border-strong);}
.ov-tile.zone-direct::before{background:var(--color-success);}
.ov-tile.zone-playin::before{background:var(--teal-500);}
.ov-tile.zone-relegated::before{background:var(--color-danger);}
.ov-tile-label{font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.08em; color:var(--color-text-dim); font-weight:600;}
.ov-tile-value{
  display:flex; align-items:baseline; gap:var(--space-1-5); font-family:var(--font-display); font-size:2rem;
  line-height:1.15; color:var(--color-text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.ov-tile-value small{font-size:.5em; color:var(--color-text-dim);}
.ov-tile-value-sm{font-size:1.35rem; line-height:1.6;}
.ov-tile-value.gold{color:var(--gold-400);}
.ov-tile-sub{font-size:var(--text-xs); color:var(--color-text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.ov-delta{font-family:var(--font-body); font-size:var(--text-xs); font-weight:700; cursor:help;}
.ov-delta.up{color:var(--green-400);}
.ov-delta.down{color:var(--red-400);}

.ov-grid{display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); gap:var(--space-4); align-items:start;}
.ov-col{display:flex; flex-direction:column; gap:var(--space-4); min-width:0;}
.ov-card{padding:var(--space-4); border-radius:var(--radius-md); background:var(--color-surface); border:1px solid var(--color-border);}
.ov-card-title{
  display:flex; align-items:baseline; gap:var(--space-2); margin:0 0 var(--space-3);
  font-size:var(--text-lg); letter-spacing:.04em; text-transform:uppercase;
}
.ov-card-title .hint{font-family:var(--font-body); font-size:var(--text-xs); text-transform:none; letter-spacing:0;}
.ov-card-link{margin-left:auto; font-family:var(--font-body); font-size:var(--text-xs); text-transform:none; letter-spacing:0;}

.ov-next{background:radial-gradient(ellipse at 50% 0, rgba(212,167,60,.12), transparent 70%), var(--color-surface);}
.ov-next-teams{display:grid; grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr); align-items:center; gap:var(--space-3);}
.ov-next-team{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1-5); min-width:0;
  color:var(--color-text); font-weight:600; font-size:var(--text-sm); text-align:center;
}
.ov-next-team:hover{text-decoration:none; color:var(--color-primary);}
.ov-next-team span{max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.ov-next-mid{display:flex; flex-direction:column; align-items:center; gap:2px;}
.ov-next-vs{font-family:var(--font-display); font-size:1.5rem; color:var(--color-primary); line-height:1;}
.ov-next-when{font-size:var(--text-xs); color:var(--color-text); font-weight:600; white-space:nowrap;}
.ov-next-left{font-size:var(--text-2xs); color:var(--color-text-dim); white-space:nowrap;}
.ov-live{color:var(--red-400); font-weight:700; font-size:var(--text-sm);}
.ov-next-actions{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--space-2) var(--space-4); margin-top:var(--space-3);}

.ov-form{display:flex; gap:var(--space-2); flex-wrap:wrap;}
.ov-form-item{
  display:flex; flex-direction:column; align-items:center; gap:4px; min-width:52px; padding:var(--space-2) var(--space-1-5);
  border-radius:var(--radius-sm); background:var(--color-surface-2); color:var(--color-text);
  transition:background var(--duration-fast) var(--ease);
}
.ov-form-item:hover{background:var(--color-surface-2-hover); text-decoration:none;}
/* Исход матча — ромбом (DESIGN.md §4), не кружком. */
.ov-form-dot{
  display:grid; place-items:center; width:30px; height:30px;
  clip-path:polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  font-size:var(--text-xs); font-weight:700; color:#fff;
}
.ov-form-dot.o-W{background:var(--green-600);}
.ov-form-dot.o-D{background:var(--gray-500);}
.ov-form-dot.o-L{background:var(--red-600);}
.ov-form-score{font-family:'JetBrains Mono',monospace; font-size:var(--text-xs); color:var(--color-text-muted);}

.ov-table{width:100%; border-collapse:collapse; font-size:var(--text-sm);}
.ov-table td{padding:var(--space-1-5) var(--space-2); border-bottom:1px solid var(--color-border);}
.ov-table tr:last-child td{border-bottom:0;}
.ov-table-pos{width:28px; text-align:center; color:var(--color-text-dim); font-variant-numeric:tabular-nums;}
.ov-table-club{display:flex; align-items:center; gap:var(--space-2); min-width:0;}
.ov-table-club a{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.ov-table-pts{font-weight:800; color:var(--pitch-light);}
.ov-table tr.zone-direct td:first-child{box-shadow:inset 3px 0 0 var(--color-success);}
.ov-table tr.zone-playin td:first-child{box-shadow:inset 3px 0 0 var(--teal-500);}
.ov-table tr.zone-relegated td:first-child{box-shadow:inset 3px 0 0 var(--color-danger);}
.ov-table tr.me td{background:var(--color-primary-subtle);}
.ov-table tr.me .club-link{color:var(--color-primary); font-weight:700;}

.ov-leaders{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:var(--space-2);}
.ov-leader{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1); min-width:0; text-align:center;
  padding:var(--space-3) var(--space-2); border-radius:var(--radius-sm); background:var(--color-surface-2); color:var(--color-text);
}
a.ov-leader:hover{background:var(--color-surface-2-hover); text-decoration:none;}
.ov-leader-title{font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; color:var(--color-text-dim); font-weight:600;}
.ov-leader .roster-avatar{width:56px; height:56px;}
.ov-leader-empty{--ring:var(--color-border);}
.ov-leader-name{font-size:var(--text-xs); font-weight:600; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.ov-leader-value{font-family:var(--font-display); font-size:1.25rem; color:var(--gold-400); line-height:1.1;}
.ov-leader-value small{font-family:var(--font-body); font-size:var(--text-2xs); color:var(--color-text-dim);}

/* Состав в цифрах: полоса позиций, возрастные группы, флаги. */
.ov-posbar{display:flex; height:26px; border-radius:var(--radius-sm); overflow:hidden; gap:2px;}
.ov-posbar-seg{display:grid; place-items:center; min-width:22px; font-size:var(--text-xs); font-weight:700; color:#0b1220;}
.ov .pos-GK{background:var(--pos-gk); color:#2a1d00;} .ov .pos-DF{background:var(--pos-df); color:#fff;}
.ov .pos-MF{background:var(--pos-mf); color:#062b12;} .ov .pos-FW{background:var(--pos-fw); color:#fff;}
.ov-poslegend{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-3); margin-top:var(--space-2); font-size:var(--text-2xs); color:var(--color-text-muted);}
.ov-poslegend span{display:inline-flex; align-items:center; gap:5px;}
.ov-posdot{width:7px; height:7px; border-radius:1px; transform:rotate(45deg); display:inline-block;}
.ov-ages{display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--space-2); margin-top:var(--space-3);}
.ov-age{display:flex; flex-direction:column; align-items:center; padding:var(--space-1-5) 0; border-radius:var(--radius-sm); background:var(--color-surface-2);}
.ov-age-count{font-family:var(--font-display); font-size:1.25rem; line-height:1.2;}
.ov-age-label{font-size:var(--text-2xs); color:var(--color-text-dim);}
.ov-nats{display:flex; flex-wrap:wrap; gap:var(--space-1-5); margin-top:var(--space-3);}
.ov-nat{
  display:inline-flex; align-items:center; gap:5px; padding:2px 8px 2px 4px; border-radius:var(--radius-full);
  background:var(--color-surface-2); font-size:var(--text-xs); font-weight:600; cursor:default;
}
.ov-nat .nat-flag{width:18px; height:12px;}

/* Финансы сезона. График баланса по дням (migrations/076). */
.ov-spark{margin-bottom:var(--space-4);}
/* Предупреждение о скором уходе в минус (ProjectedBalanceSpark.vue, по
   прямому запросу) — тот же цвет, что error-box, но без display:none/
   .visible (видимость уже решает v-if, не форма). */
.ov-spark-warning{
  background:var(--color-danger-subtle); border:1px solid var(--color-danger); color:var(--red-300);
  padding:var(--space-2-5) var(--space-3-5); border-radius:var(--radius-md); font-size:var(--text-sm);
  margin:0 0 var(--space-3); line-height:var(--leading-snug);
}
.ov-spark-head{display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:var(--space-2);}
.ov-spark-change{font-size:var(--text-xs); font-weight:700;}
.ov-spark-change.pos{color:var(--green-400);}
.ov-spark-change.neg{color:var(--red-400);}
.ov-spark-svg{display:block; width:100%; height:64px; margin-top:var(--space-1);}
.ov-spark-line{fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;}
.ov-spark-svg.pos .ov-spark-line{stroke:var(--green-400);}
.ov-spark-svg.neg .ov-spark-line{stroke:var(--red-400);}
.ov-spark-svg.pos .ov-spark-area{fill:rgba(69,189,104,.14);}
.ov-spark-svg.neg .ov-spark-area{fill:rgba(226,106,106,.14);}
.ov-spark-axis{display:flex; justify-content:space-between; gap:var(--space-2); font-size:var(--text-2xs); color:var(--color-text-dim);}
.ov-spark-axis span:nth-child(2){text-align:center;}
.ov-spark-empty{margin:var(--space-1) 0 0; font-size:var(--text-xs);}
/* Прогноз доходов/расходов (ProjectedBalanceSpark.vue) — доход рисуется
   ПОВЕРХ расхода (порядок <polygon>/<polyline> в разметке), оба зелёный/
   красный как и везде на странице; легенда с подписями — зелёный/красный
   не проходит CVD-проверку (dataviz skill) как единственный канал
   identity, подпись рядом со свотчем — обязательный второй канал. */
.ov-spark-legend{display:flex; gap:var(--space-3); font-size:var(--text-2xs); color:var(--color-text-muted);}
.ov-spark-legend-item{display:inline-flex; align-items:center; gap:4px;}
.ov-spark-swatch{display:inline-block; width:9px; height:9px; border-radius:2px;}
.ov-spark-swatch.income{background:var(--green-400);}
.ov-spark-swatch.expense{background:var(--red-400);}
.ov-spark-line.income{stroke:var(--green-400);}
.ov-spark-line.expense{stroke:var(--red-400);}
.ov-spark-area.income{fill:rgba(69,189,104,.22);}
.ov-spark-area.expense{fill:rgba(226,106,106,.22);}
.ov-spark-dot{stroke:var(--color-surface); stroke-width:2; paint-order:stroke;}
.ov-spark-dot.income{fill:var(--green-400);}
.ov-spark-dot.expense{fill:var(--red-400);}
.ov-spark-note{margin:var(--space-2) 0 0; font-size:var(--text-xs); line-height:var(--leading-snug);}
.ov-fin-bars{display:flex; flex-direction:column; gap:var(--space-2);}
.ov-fin-row{display:grid; grid-template-columns:64px minmax(0, 1fr) auto; align-items:center; gap:var(--space-2);}
.ov-fin-label{font-size:var(--text-xs); color:var(--color-text-muted);}
.ov-fin-track{height:10px; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.ov-fin-fill{display:block; height:100%; border-radius:inherit;}
.ov-fin-fill.in{background:linear-gradient(90deg, var(--green-600), var(--green-400));}
.ov-fin-fill.out{background:linear-gradient(90deg, var(--red-600), var(--red-400));}
.ov-fin-value{font-size:var(--text-xs); font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap;}
.ov-fin-net{margin:var(--space-3) 0; font-family:var(--font-display); font-size:1.15rem; letter-spacing:.02em;}
.ov-fin-net.pos{color:var(--green-400);}
.ov-fin-net.neg{color:var(--red-400);}
.ov-fin-top{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-3);}
.ov-fin-top-title{display:block; margin-bottom:var(--space-1); font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; color:var(--color-text-dim); font-weight:600;}
.ov-fin-item{display:flex; justify-content:space-between; gap:var(--space-2); font-size:var(--text-xs); padding:2px 0;}
.ov-fin-item span{color:var(--color-text-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.ov-fin-item b{white-space:nowrap; font-variant-numeric:tabular-nums;}
.ov-fin-item b.in{color:var(--green-400);}
.ov-fin-item b.out{color:var(--red-400);}
.ov-fin-item b.warn{color:var(--gold-400);}

/* Лучшие связки — цвета ступеней как у линий на доске (журнал п.256). */
.ov-pairs{display:flex; flex-direction:column; gap:var(--space-3);}
.ov-pair-names{display:flex; align-items:center; gap:var(--space-1-5); font-size:var(--text-sm); font-weight:600; min-width:0;}
.ov-pair-names a{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.ov-pair-plus{color:var(--color-text-dim);}
.ov-pair-bonus{margin-left:auto; padding:1px 7px; border-radius:var(--radius-full); font-size:var(--text-2xs); font-weight:700; flex:none;}
.ov-pair-bonus.tier-0{background:var(--color-surface-2); color:var(--color-text-dim);}
.ov-pair-bonus.tier-1{background:#ef4444; color:#fff;}
.ov-pair-bonus.tier-2{background:#f59e0b; color:#2a1d00;}
.ov-pair-bonus.tier-3{background:#22c55e; color:#062b12;}
.ov-pair-track{height:6px; margin:var(--space-1-5) 0; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.ov-pair-fill{display:block; height:100%; border-radius:inherit;}
.ov-pair-fill.tier-0{background:var(--gray-400);}
.ov-pair-fill.tier-1{background:#ef4444;} .ov-pair-fill.tier-2{background:#f59e0b;} .ov-pair-fill.tier-3{background:#22c55e;}
.ov-pair-meta{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-3); font-size:var(--text-2xs); color:var(--color-text-dim);}
.ov-pair-status{font-weight:700;}
.ov-pair-status.ok{color:var(--green-400);}
.ov-pair-status.warn{color:var(--gold-400);}
.ov-pair-status.muted{color:var(--color-text-muted);}

/* Стадион. */
.ov-stadium{background:
  linear-gradient(180deg, rgba(33,94,61,.18), transparent 60%),
  repeating-linear-gradient(90deg, rgba(255,255,255,.015) 0 24px, transparent 24px 48px),
  var(--color-surface);}
.ov-stadium-head{display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:var(--space-1) var(--space-3);}
.ov-stadium-name{font-family:var(--font-display); font-size:1.2rem; letter-spacing:.02em;}
.ov-stadium-cap{font-size:var(--text-xs); color:var(--color-text-muted);}
.ov-fill{margin:var(--space-3) 0;}
.ov-fill-track{height:10px; border-radius:var(--radius-full); background:var(--color-surface-2); overflow:hidden;}
.ov-fill-bar{display:block; height:100%; border-radius:inherit; background:linear-gradient(90deg, var(--teal-600), var(--teal-300));}
.ov-fill-text{display:block; margin-top:var(--space-1); font-size:var(--text-xs); color:var(--color-text-muted);}
.ov-stadium-facts{display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:var(--space-2);}
.ov-stadium-facts > div{display:flex; flex-direction:column; gap:2px; padding:var(--space-1-5) var(--space-2); border-radius:var(--radius-sm); background:var(--color-surface-2); min-width:0;}
.ov-fact-label{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.05em;}
.ov-stars{color:var(--gold-400); letter-spacing:1px; font-size:var(--text-sm); white-space:nowrap;}
.ov-stars i{font-style:normal; color:var(--gray-600);}
.ov-stadium-facts b{font-size:var(--text-sm);}
.ov-stadium-note{margin:var(--space-2) 0 0; font-size:var(--text-2xs);}

@media(max-width:900px){
  .ov-tiles{grid-template-columns:repeat(2, minmax(0, 1fr));}
  .ov-grid{grid-template-columns:minmax(0, 1fr);}
}
@media(max-width:640px){
  .ov-tile{padding:var(--space-2-5) var(--space-3);}
  .ov-tile-value{font-size:1.6rem;}
  .ov-tile-value-sm{font-size:1.1rem; line-height:1.45;}
  .ov-form-item{min-width:0; flex:1;}
  .ov-leader-value small{display:block;}
  .ov-leader .roster-avatar{width:48px; height:48px;}
  .ov-stadium-facts{grid-template-columns:repeat(2, minmax(0, 1fr));}
  .ov-fin-top{grid-template-columns:minmax(0, 1fr);}
}
.num{font-family:'JetBrains Mono',monospace; text-align:center;}

.tactics-controls{display:flex; gap:var(--space-1-5); margin-bottom:var(--space-4); flex-wrap:wrap; align-items:center;}

/* ---- Вкладка «Тактика» (TacticsBoard.vue, DESIGN.md) ----
   Сводка+кнопки сверху; ≥1100px — поле слева, настройки/связки справа;
   скамейка и расшифровка амплуа — карточками ниже. */
.tb{display:flex; flex-direction:column; gap:var(--space-4); min-width:0;}
.tb > *{min-width:0;}
.tb-toolbar{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-3);}
.tb-toolbar .tactics-controls{margin:0;}
.tb-stats{display:flex; flex-wrap:wrap; gap:var(--space-2);}
.tb-stat{
  display:flex; flex-direction:column; min-width:78px; padding:var(--space-1-5) var(--space-3);
  border-radius:var(--radius-sm); background:var(--color-surface-2);
}
.tb-stat b{font-family:var(--font-display); font-size:1.2rem; line-height:1.2; white-space:nowrap;}
.tb-stat b small{font-size:.6em; color:var(--color-text-dim);}
.tb-stat b small.tb-neg{color:var(--red-400);}
.tb-stat span{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.06em; font-weight:600; white-space:nowrap;}
.tb-blue{color:#60a5fa;}
.tb-green{color:var(--green-400);}
.tb-gold{color:var(--gold-400);}

/* Федерация страны «Лиг» (FederationPanel.vue, migrations/100). */
.fed-grant-row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; margin-bottom:var(--space-2);}
.fed-amount-input{width:70px; padding:4px 6px; border-radius:6px; background:var(--color-surface-2); color:var(--color-text); border:1px solid var(--color-border);}
.fed-club-select{min-width:180px; padding:6px 10px; border-radius:6px; background:var(--color-surface-2); color:var(--color-text); border:1px solid var(--color-border);}
/* Заявка на выдвижение в президенты федерации (FederationPanel.vue) —
   текстовое поле, открывается кнопкой "Подать заявку". */
.fed-candidacy-form{display:flex; flex-direction:column; gap:var(--space-1-5); margin-bottom:var(--space-3);}
.fed-candidacy-form textarea{
  width:100%; box-sizing:border-box; padding:var(--space-2) var(--space-2-5); border-radius:var(--radius-md);
  background:var(--color-surface-2); color:var(--color-text); border:1px solid var(--color-border);
  font:inherit; resize:vertical;
}
.fed-candidate{padding:var(--space-2) 0; border-bottom:1px solid var(--color-border);}
.fed-candidate:last-child{border-bottom:none;}
.fed-candidate-head{display:flex; justify-content:space-between; align-items:center; gap:var(--space-2); font-size:var(--text-xs);}
.fed-candidate-statement{margin:var(--space-1) 0 0; white-space:pre-wrap;}

.tb-layout{display:grid; grid-template-columns:minmax(0, 1fr); gap:var(--space-4); align-items:start;}
.tb-pitch-col{display:flex; flex-direction:column; gap:var(--space-2); min-width:0;}
.tb-side{display:flex; flex-direction:column; gap:var(--space-3); min-width:0;}
@media(min-width:1100px){
  .tb-layout{grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);}
  .tb-pitch-col .pitch-wrap{max-width:480px;}
}
.tb-card{padding:var(--space-4); border-radius:var(--radius-md); background:var(--color-surface); border:1px solid var(--color-border);}
.tb-card-title{
  display:flex; align-items:center; gap:var(--space-1-5); margin:0 0 var(--space-3);
  font-family:var(--font-display); font-size:var(--text-lg); letter-spacing:.04em; text-transform:uppercase; font-weight:700;
}
.tb-card-desc{margin:var(--space-2-5) 0 0; font-size:var(--text-xs); color:var(--color-text-muted); line-height:var(--leading-snug);}
.tb-count{font-family:var(--font-body); font-size:var(--text-xs); color:var(--color-text-dim); letter-spacing:0;}

/* Не сыграют (травмы/дисквалификации) — TacticsBoard.vue */
.tb-unavail.warn{border-color:var(--color-danger);}
.tb-unavail .tb-card-title{margin-bottom:var(--space-2);}
.tb-unavail-warn{margin:0 0 var(--space-2); color:var(--red-300);}
.tb-unavail-list{display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr)); gap:var(--space-1) var(--space-4);}
.tb-unavail-row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; font-size:var(--text-sm); min-width:0;}
.tb-unavail-row.placed .tb-unavail-name{color:var(--red-300);}
.pitch-chip-mini.unavailable, .bench-tile.unavailable{opacity:.45; outline:2px dashed var(--color-danger); outline-offset:1px;}
/* Травма в живом матче — может доигрывать: не бледный, оранжевая рамка */
.pitch-chip-mini.hurt, .bench-tile.hurt{outline:2px solid var(--orange-400, #f59e0b); outline-offset:1px;}
@media(max-width:400px){ .tb-unavail-list{grid-template-columns:1fr;} }

.tb-intensity{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--space-2) var(--space-3);}
.tb-intensity-title{display:inline-flex; align-items:center; gap:4px; font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; color:var(--color-text-dim); font-weight:600;}
.tb-intensity .intensity-legend{gap:var(--space-1-5) var(--space-3); margin:0;}
.tb-intensity .intensity-legend-row{font-size:var(--text-xs);}
.tb-drag-hint{margin-top:0;}

/* Связки на поле — лента: бейдж цвета смысла | пара | пояснение. */
.tb .pitch-links-panel{margin:0; border-top:1px solid var(--color-border); padding-top:var(--space-4);}
.tb .pitch-links-head{margin-bottom:var(--space-1);}
.tb .pitch-links-head .tb-card-title{margin:0;}
.tb-eye{font-size:var(--text-xs);}
.tb-links{display:flex; flex-direction:column; gap:2px; margin-top:var(--space-2);}
.tb-link{
  display:grid; grid-template-columns:44px minmax(0, auto) minmax(0, 1fr); align-items:center; gap:var(--space-2);
  padding:5px var(--space-2); border-radius:var(--radius-sm); font-size:var(--text-xs);
}
.tb-link:nth-child(odd){background:rgba(255,255,255,.02);}
.tb-link-badge{text-align:center; padding:1px 0; border-radius:var(--radius-full); font-size:var(--text-2xs); font-weight:700; background:var(--color-surface-2); color:var(--color-text-dim);}
.tb-link-who{font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.tb-link-who .role-tag{font-size:9px; padding:1px 4px;}
.tb-link-text{color:var(--color-text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.tb-link.k-role .tb-link-badge{background:#3b82f6; color:#fff;}
.tb-link.k-anti .tb-link-badge{background:var(--red-600); color:#fff;}
.tb-link.k-tier-1 .tb-link-badge{background:#ef4444; color:#fff;}
.tb-link.k-tier-2 .tb-link-badge{background:#f59e0b; color:#2a1d00;}
.tb-link.k-tier-3 .tb-link-badge{background:#22c55e; color:#062b12;}
.tb-link.k-far, .tb-link.k-growing{opacity:.7;}
.tb-more{
  margin-top:var(--space-2); padding:0; border:0; background:none; cursor:pointer;
  color:var(--color-primary); font:inherit; font-size:var(--text-xs); font-weight:600;
}
.tb-more:hover{text-decoration:underline;}

.tb .bench-panel{margin:0; border-top:1px solid var(--color-border);}
.tb-roles > summary{cursor:pointer; list-style:none; margin:0; flex-wrap:wrap;}
.tb-roles > summary::-webkit-details-marker{display:none;}
.tb-roles > summary::before{content:'▸'; color:var(--color-text-dim); transition:transform var(--duration-fast) var(--ease);}
.tb-roles[open] > summary::before{transform:rotate(90deg);}
.tb-roles[open] > summary{margin-bottom:var(--space-3);}
.tb-summary-hint{font-family:var(--font-body); font-size:var(--text-2xs); text-transform:none; letter-spacing:0; color:var(--color-text-dim); font-weight:400;}
@media(max-width:640px){
  .tb-toolbar{flex-direction:column; align-items:stretch;}
  .tb-stats{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr));}
  .tb-stat{min-width:0; padding:var(--space-1-5) var(--space-2);}
  .tb-stat span{white-space:normal; line-height:1.2;}
  .tb-card{padding:var(--space-3);}
  .tb-link{grid-template-columns:40px minmax(0, 1fr); row-gap:0;}
  .tb-link-text{grid-column:2; white-space:normal;}
  .tb-summary-hint{flex-basis:100%;}
}
.formation-tag{
  font-size:var(--text-xs); color:var(--color-text-muted); margin-bottom:var(--space-3);
  padding:var(--space-1-5) var(--space-2-5); border-radius:var(--radius-md);
  background:var(--color-surface-2); border:1px solid var(--color-border);
}
.formation-tag b{color:var(--color-primary);}

/* ---- "Первые шаги менеджера" — чек-лист на "Общих данных" ----
   Пункты отражают реальное состояние клуба (лайнап/установки/отправленный
   матч), не отдельный прогресс-флаг — см. OnboardingChecklist.vue /
   useOnboardingChecklist.js. */
.onboarding-checklist{
  background:var(--color-surface-2); border:1px solid var(--color-border); border-radius:var(--radius-md);
  padding:var(--space-3-5) var(--space-4); margin:var(--space-4) 0;
}
.onboarding-checklist-head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-2);
  font-family:var(--font-display); letter-spacing:.3px; font-size:var(--text-sm); color:var(--color-text);
  margin-bottom:var(--space-2-5);
}
.onboarding-checklist-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--space-1-5);}
.onboarding-checklist-list li{
  display:flex; align-items:center; gap:var(--space-2-5); padding:var(--space-1-5) var(--space-2);
  border-radius:var(--radius-sm); font-size:var(--text-sm); color:var(--color-text-muted); cursor:pointer;
  transition:background var(--duration-fast) var(--ease);
}
.onboarding-checklist-list li:hover{background:var(--color-surface-2-hover);}
.onboarding-checklist-list li.done{color:var(--color-text-dim); cursor:default;}
.onboarding-checklist-list li.done:hover{background:none;}
.onboarding-checklist-box{
  flex:0 0 auto; width:18px; height:18px; border-radius:5px; border:1.5px solid var(--color-border-strong);
  display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:800; color:var(--color-success);
}
.onboarding-checklist-list li.done .onboarding-checklist-box{border-color:var(--color-success); background:var(--color-success-subtle);}
.onboarding-checklist-guide-link{margin:var(--space-2) 0 0; color:var(--color-text-dim); font-size:var(--text-xs); line-height:var(--leading-normal);}

.pitch-wrap{width:100%; max-width:420px; margin:0 auto; position:relative;}
.pitch{
  position:relative; width:100%; padding-bottom:150%;
  background:
    linear-gradient(180deg, rgba(59,165,92,0.10), transparent 40%),
    repeating-linear-gradient(180deg, rgba(255,255,255,0.03) 0 12%, rgba(255,255,255,0) 12% 24%),
    var(--pitch);
  border:2px solid rgba(255,255,255,0.18); border-radius:var(--radius-md); overflow:visible; touch-action:none;
}
.pitch-line{position:absolute; left:0; right:0; height:2px; background:rgba(255,255,255,0.25);}
.pitch-halfway{top:50%;}
.pitch-circle{
  position:absolute; left:50%; top:50%; width:22%; padding-bottom:22%;
  border:2px solid rgba(255,255,255,0.25); border-radius:var(--radius-full); transform:translate(-50%,-50%);
}
.pitch-box{position:absolute; left:50%; width:46%; padding-bottom:16%; border:2px solid rgba(255,255,255,0.25); transform:translateX(-50%);}
.pitch-box-top{top:0; border-top:none;}
.pitch-box-bottom{bottom:0; border-bottom:none;}
.pitch-slot{
  position:absolute; transform:translate(-50%,-50%); display:flex; align-items:center; justify-content:center;
  width:15%; padding-bottom:15%; border-radius:var(--radius-full);
  transition:background var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
/* Связки на поле (TacticsBoard.vue, roleEffect.js lineupLinks): синие —
   амплуа, красный пунктир — антисвязка, золотые — сыгранность соседей
   (толщина по уровню бонуса). Под фишками, клики не перехватывают. */
.pitch-links{position:absolute; inset:0; width:100%; height:100%; pointer-events:none; overflow:visible;}
.pitch-links line{vector-effect:non-scaling-stroke; stroke-linecap:round;}
.pitch-link-role{stroke:#3b82f6; stroke-width:3; opacity:.95;}
.pitch-link-role.negative{stroke:var(--color-danger, #e5484d); stroke-dasharray:5 4;}
.pitch-link-partner{stroke:#e0b341; opacity:.85;}
.pitch-link-partner.growing{stroke-width:2; stroke-dasharray:4 4; opacity:.9;}
.pitch-links-row.growing{opacity:.75;}
/* Сыгранные, но стоят не рядом — бонуса нет, тонкий редкий пунктир. */
.pitch-link-partner.far{stroke-width:1.5; stroke-dasharray:2 6; opacity:.7;}
/* Сплошные линии сыгранности — по ступени от красного к зелёному,
   полупрозрачные (по прямому запросу); пунктиры (копят / стоят далеко) — прежние. */
.pitch-link-partner.tier-1{stroke-width:2; stroke:#ef4444; opacity:.55;}
.pitch-link-partner.tier-2{stroke-width:4; stroke:#f59e0b; opacity:.55;}
.pitch-link-partner.tier-3{stroke-width:6; stroke:#22c55e; opacity:.55;}
/* Пара с обеими связками: золото рисуется под синей линией шире неё —
   получается золотая кайма; подписи встают рядом, а не друг под другом. */
.pitch-link-partner.with-role{opacity:.7;}
.pitch-link-partner.with-role.tier-1{stroke-width:7;}
.pitch-link-partner.with-role.tier-2{stroke-width:8;}
.pitch-link-partner.with-role.tier-3{stroke-width:9;}
.pitch-link-label.combo{display:flex; padding:0; overflow:hidden;}
.pitch-link-label.combo > span{padding:0 4px;}
.pitch-link-label-partner{background:#f5b82e; color:#2a1d00;}
.pitch-link-label-partner.far{background:#6b5a2e; color:rgba(255,255,255,.6); text-decoration:line-through;}
.pitch-link-label{
  position:absolute; transform:translate(-50%,-50%); z-index:2; pointer-events:none;
  padding:0 4px; border-radius:var(--radius-sm); font-size:10px; font-weight:800; line-height:15px; white-space:nowrap;
  color:#fff; box-shadow:0 1px 2px rgba(0,0,0,.4);
}
/* Метка — кнопка (поповер «за что бонус», TacticsBoard.vue): место ей
   подбирает раскладка без наложений, поэтому клики по фишкам не перекрывает. */
button.pitch-link-label{pointer-events:auto; border:0; margin:0; font-family:inherit; cursor:help; touch-action:manipulation;}
button.pitch-link-label:focus-visible{outline:2px solid #fff; outline-offset:1px;}
.pitch-link-label.active{box-shadow:0 0 0 2px #fff, 0 1px 2px rgba(0,0,0,.4); z-index:3;}
.pitch-link-popup{
  position:absolute; z-index:6; width:max-content; max-width:min(210px, 70%); padding:6px 9px; border-radius:var(--radius-md);
  background:var(--color-bg-elevated); border:1px solid var(--color-border-strong); box-shadow:0 6px 18px rgba(0,0,0,.45);
  font-size:12px; line-height:1.4; color:var(--color-text); pointer-events:none;
  transform:translate(-50%, calc(-100% - 12px));
}
.pitch-link-popup.below{transform:translate(-50%, 12px);}
/* У краёв — прижат к краю поля (left/right: 2% в TacticsBoard.vue), сдвиг только по вертикали. */
.pitch-link-popup.align-left, .pitch-link-popup.align-right{transform:translateY(calc(-100% - 12px));}
.pitch-link-popup.align-left.below, .pitch-link-popup.align-right.below{transform:translateY(12px);}
.pitch-link-popup p{margin:4px 0 0; color:var(--color-text-muted);}
.pitch-link-popup-title{font-weight:800; font-size:12px;}
.pitch-link-label.role{background:#2563eb;}
.pitch-link-label.role.negative{background:var(--color-danger, #e5484d);}
.pitch-link-label.partner{background:#f5b82e; color:#2a1d00;}
/* Метки сыгранности — в цвет своей линии (ступень 1/2/3: красный → жёлтый → зелёный). */
.pitch-link-label.partner.tier-1, .pitch-link-label-partner.tier-1{background:#ef4444; color:#fff;}
.pitch-link-label.partner.tier-2, .pitch-link-label-partner.tier-2{background:#f59e0b; color:#2a1d00;}
.pitch-link-label.partner.tier-3, .pitch-link-label-partner.tier-3{background:#22c55e; color:#062b12;}
.pitch-link-label-partner.far[class*="tier-"]{background:#6b5a2e; color:rgba(255,255,255,.6);} /* стоят далеко — бледная, как раньше */
.pitch-links-panel{margin-top:var(--space-5); border-top:1px solid var(--color-border); padding-top:var(--space-3-5);}
.pitch-links-head{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2); flex-wrap:wrap;}
.pitch-links-list{display:grid; grid-template-columns:1fr; gap:6px var(--space-6); font-size:var(--text-sm);}
@media (min-width:900px){ .pitch-links-list{grid-template-columns:1fr 1fr;} }
.pitch-links-row{display:flex; align-items:flex-start; gap:var(--space-2);}
.pitch-links-row > span:not(.pitch-links-dot){flex:1 1 auto; min-width:0;}
.pitch-links-row b{flex:none; white-space:nowrap;}
.pitch-links-dot{margin-top:5px;}
.pitch-links-row b.pos{color:var(--color-success);}
.pitch-links-row b.neg{color:var(--color-danger, #e5484d);}
.pitch-links-dot{width:10px; height:10px; border-radius:var(--radius-full); flex:none;}
.pitch-links-dot.role{background:#3b82f6;}
.pitch-links-dot.role.negative{background:var(--color-danger, #e5484d);}
.pitch-links-dot.partner{background:#e0b341;}
.pitch-slot.dropzone-hover{background:rgba(59,165,92,0.28); box-shadow:0 0 0 2px var(--color-primary);}
.pitch-chip-mini{
  position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  border-radius:var(--radius-sm); background:rgba(10,15,28,0.78); border:1px solid rgba(255,255,255,0.2);
  cursor:grab; touch-action:none;
}
.pitch-chip-empty{
  position:absolute; inset:14%; display:flex; align-items:center; justify-content:center;
  border-radius:var(--radius-full); border:1.5px dashed rgba(255,255,255,0.3); color:rgba(255,255,255,0.35);
  font-family:'JetBrains Mono',monospace; font-size:var(--text-2xs); font-weight:700;
}
.pitch-chip-ovr{font-family:'JetBrains Mono',monospace; font-weight:800; font-size:11px; color:var(--color-primary); line-height:1.1;}
.pitch-chip-name{font-size:10.5px; font-weight:700; color:var(--color-text); white-space:nowrap; max-width:90%; overflow:hidden; text-overflow:ellipsis; line-height:1.1;}
.pitch-chip-role{font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--color-text-dim); line-height:1.1; letter-spacing:.2px;}
.pitch-chip-flag{
  position:absolute; left:-4px; bottom:-4px; width:15px; height:11px; object-fit:cover;
  border-radius:2px; box-shadow:0 0 0 1px rgba(255,255,255,.5);
  transform:rotate(-18deg); filter:drop-shadow(0 1px 2px rgba(0,0,0,.6));
}

/* Усталость игрока (0-100) — зелёная/жёлтая/красная шкала, тот же порог
   (70%), с которого сервер начинает штрафовать attack/defense в матче. */
.fatigue-bar{position:relative; height:3px; border-radius:var(--radius-full); background:rgba(255,255,255,0.12); overflow:hidden;}
.fatigue-bar-fill{height:100%; border-radius:var(--radius-full); transition:width var(--duration-fast) var(--ease);}
.fatigue-low{background:var(--color-success);}
.fatigue-mid{background:var(--gold-500);}
.fatigue-high{background:var(--color-danger);}
.fatigue-bar-pitch{position:absolute; left:14%; right:14%; bottom:3px; width:72%;}
/* Живой матч: усталость по ходу матча (штраф к навыкам) — угол фишки. */
.pitch-chip-tired{
  position:absolute; right:-6px; bottom:-6px; padding:0 3px; border-radius:var(--radius-sm);
  font-family:'JetBrains Mono',monospace; font-size:9.5px; font-weight:700; line-height:14px;
  background:var(--gold-500); color:#111; box-shadow:0 1px 2px rgba(0,0,0,.5); pointer-events:auto;
}
.pitch-chip-tired.high{background:var(--color-danger); color:#fff;}
/* Доска тактики: «Игра от счёта» — подпись строки и пилюли. */
.tb-gs-row{display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-1-5) var(--space-3); margin-bottom:var(--space-2);}
.tb-gs-label{min-width:112px; font-size:var(--text-xs); color:var(--color-text-muted);}
.tb-gs-row .tactics-pills{margin:0;}
.fatigue-bar-bench{margin:3px var(--space-1-5) 0;}

/* Мораль игрока (0-100) — та же шкала, что усталость, но ОБРАТНАЯ
   полярность (высокое значение — хорошо), поэтому свои классы
   .morale-good/mid/bad, не .fatigue-low/mid/high (тот же принцип, что и
   у .rating-good/mid/bad для оценок за матч). */
.morale-bar{position:relative; height:3px; border-radius:var(--radius-full); background:rgba(255,255,255,0.12); overflow:hidden;}
.morale-bar-fill{height:100%; border-radius:var(--radius-full); transition:width var(--duration-fast) var(--ease);}
.morale-good{background:var(--color-success);}
.morale-mid{background:var(--gold-500);}
.morale-bad{background:var(--color-danger);}
.morale-bar-card{height:6px;}

/* Установка интенсивности на клетку (портировано из движка, раздел 16
   библии) — 5 кружочков вверху карточки игрока на поле (не на скамейке —
   установка привязана к клетке, не к игроку). Полный градиент по всем 5
   уровням (не просто «пассивно/агрессивно» на двоих): холодный тёмно-синий
   (очень пассивно) → светло-синий (пассивно) → серый (нейтрально) →
   оранжевый (агрессивно) → красный (очень агрессивно) — активный уровень
   заливается цветом, остальные — приглушённая версия того же цвета, чтобы
   градиент был виден целиком даже до выбора. Кружки и клик-зона увеличены
   (было 5px — курсором было не попасть); .pitch-chip-intensity даёт
   дополнительный вертикальный отступ под клик поверх padding самих точек. */
.pitch-chip-intensity{
  /* top:0 + translateY(-100%-3px) вместо top:-29.4% — сдвиг тогда считался
     от высоты .pitch-chip-mini, а она нигде не задана явно (только
     inset:0 от слота, чья высота сама берётся из padding-bottom трюка
     ещё уровнем выше) — на части мобильных браузеров (замечено на
     реальных устройствах) такая цепочка процентов от неявной высоты
     считалась иначе, бейдж проваливался на цифру OVR. translateY(-100%)
     сдвигает на собственную высоту бейджа (она всегда однозначна),
     работает одинаково для свёрнутого бейджа и для развёрнутого ряда. */
  position:absolute; top:0; left:50%; transform:translate(-50%, calc(-100% - 3px));
  display:flex; z-index:2; border-radius:var(--radius-full);
  /* Свёрнутое состояние — везде, не только на мобилке (см. ниже): у ряда
     из 5 точек фиксированная ширина (~85px), которая на любом экране
     легко превышает расстояние между соседними игроками в плотных
     построениях — сворачиваем в узкий 20x10 индикатор цвета текущего
     уровня, тап разворачивает его в полоску-«ползунок». */
  width:20px; height:10px; padding:0; gap:0; overflow:hidden;
}
.pitch-chip-intensity .intensity-dot{display:none;}
.pitch-chip-intensity.cur-lv-n2{background:#2f5aa8;}
.pitch-chip-intensity.cur-lv-n1{background:#7fa4ee;}
.pitch-chip-intensity.cur-lv-0{background:var(--color-text-dim);}
.pitch-chip-intensity.cur-lv-p1{background:#e08c3a;}
.pitch-chip-intensity.cur-lv-p2{background:var(--color-danger);}
.pitch-chip-intensity.expanded{
  width:auto; height:auto; padding:3px 4px; gap:3px; overflow:visible; z-index:3;
  background:linear-gradient(90deg,#2f5aa8,#7fa4ee,var(--color-text-dim),#e08c3a,var(--color-danger));
}
.pitch-chip-intensity.expanded .intensity-dot{display:block;}
.intensity-dot{
  width:9px; height:9px; border-radius:var(--radius-full); box-sizing:content-box;
  padding:2px; background-clip:content-box;
  background-color:rgba(255,255,255,0.16); border:1px solid rgba(255,255,255,0.4);
  cursor:pointer; transition:transform var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.intensity-dot:hover{transform:scale(1.3);}
.intensity-dot.active{border-color:rgba(255,255,255,0.85);}
.intensity-dot.lv-n2{background-color:rgba(47,90,168,0.35);}
.intensity-dot.lv-n1{background-color:rgba(127,164,238,0.35);}
.intensity-dot.lv-0{background-color:rgba(255,255,255,0.16);}
.intensity-dot.lv-p1{background-color:rgba(224,140,58,0.35);}
.intensity-dot.lv-p2{background-color:rgba(214,69,69,0.35);}
.intensity-dot.active.lv-n2{background-color:#2f5aa8;}
.intensity-dot.active.lv-n1{background-color:#7fa4ee;}
.intensity-dot.active.lv-0{background-color:var(--color-text-dim);}
.intensity-dot.active.lv-p1{background-color:#e08c3a;}
.intensity-dot.active.lv-p2{background-color:var(--color-danger);}

/* Пикер тренировочной интенсивности (TrainingLevelPicker.vue) — всегда
   видимый ряд из 5 кнопок, не свёрнутый индикатор (см. её комментарий) —
   та же цветовая логика по уровню, что и .intensity-dot выше (синий=
   спокойно, серый=нейтрально, оранжево-красный=нагрузка), но как фон
   кнопки с текстом, не точка. */
/* Сегментный переключатель в одну строку (DESIGN.md). */
.training-picker{display:inline-flex; gap:2px; padding:2px; border-radius:var(--radius-full); background:var(--color-surface-2); border:1px solid var(--color-border); max-width:100%;}
.training-level-btn{
  flex:1 1 auto; padding:3px 8px; border-radius:var(--radius-full); border:1px solid transparent;
  background:none; color:var(--color-text-muted); font-size:var(--text-2xs); font-weight:700;
  cursor:pointer; white-space:nowrap; transition:background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.training-level-btn:hover{color:var(--color-text);}
.training-level-btn.active.lv-n2{background:#2f5aa8; border-color:#2f5aa8; color:#fff;}
.training-level-btn.active.lv-n1{background:#7fa4ee; border-color:#7fa4ee; color:#0a0f1c;}
.training-level-btn.active.lv-0{background:var(--color-text-dim); border-color:var(--color-text-dim); color:#0a0f1c;}
.training-level-btn.active.lv-p1{background:#e08c3a; border-color:#e08c3a; color:#0a0f1c;}
.training-level-btn.active.lv-p2{background:var(--color-danger); border-color:var(--color-danger); color:#fff;}

/* Название клуба как ссылка на club.html — везде, где отображается текстом
   (таблица, расписание, списки в админке). Не выглядит как «обычная»
   синяя ссылка (наследует цвет текста), подсвечивается только при hover —
   чтобы не отвлекать от плотных таблиц, но оставаться узнаваемо кликабельным. */
.club-link{color:inherit; text-decoration:none; transition:color var(--duration-fast) var(--ease);}
.club-link:hover{color:var(--color-primary); text-decoration:underline;}

.intensity-legend{display:flex; flex-wrap:wrap; gap:var(--space-4) var(--space-5); margin-bottom:var(--space-2);}
.intensity-legend-row{display:flex; align-items:center; gap:var(--space-1-5); font-size:var(--text-sm); color:var(--color-text-muted);}
.intensity-legend-row .intensity-dot{cursor:default;}
.intensity-legend-row .intensity-dot:hover{transform:none;}

.bench-panel{margin-top:var(--space-5); border-top:1px solid var(--color-border); padding-top:var(--space-3-5); border-radius:var(--radius-md); transition:background var(--duration-fast) var(--ease);}
.bench-panel.dropzone-hover{background:rgba(59,165,92,0.06);}
/* Уменьшено по прямому запросу («крайне неудобно пользоваться») — было
   minmax(84px,...), плашка почти квадратная фотка+текст, на скамейке
   из 10+ игроков занимала слишком много места, приходилось много
   скроллить, чтобы найти нужного игрока и точно попасть перетаскиванием.
   Пропорционально уменьшены все внутренние элементы (фото и так
   масштабируется через padding-bottom:100% от новой меньшей ширины). */
.bench-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(60px, 1fr)); gap:var(--space-1-5); min-height:40px;}
.bench-tile{
  display:flex; flex-direction:column; border-radius:var(--radius-md);
  background:var(--color-surface-2); border:1px solid var(--color-border); cursor:grab; touch-action:none; user-select:none;
  transition:border-color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
.bench-tile:hover{border-color:var(--color-primary);}
.bench-tile:active{transform:scale(.97);}
.bench-tile-photo{
  border-radius:var(--radius-md) var(--radius-md) 0 0; overflow:hidden; position:relative; width:100%; padding-bottom:100%;
  display:flex; align-items:center; justify-content:center;
}
.bench-tile-initials{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-size:17px; letter-spacing:.5px; color:rgba(255,255,255,0.92);
  text-shadow:0 1px 3px rgba(0,0,0,0.35);
}
.pos-bg-GK{background:linear-gradient(150deg,#8a6a1f,#5c4712);}
.pos-bg-DF{background:linear-gradient(150deg,#3a5b96,#22355a);}
.pos-bg-MF{background:linear-gradient(150deg,#2f7a4a,#1c4a2c);}
.pos-bg-FW{background:linear-gradient(150deg,#a13f3f,#5e2323);}
.bench-tile-ovr{
  position:absolute; bottom:3px; right:3px; font-family:'JetBrains Mono',monospace; font-weight:800; font-size:9px;
  color:#fff; background:rgba(0,0,0,0.45); border-radius:var(--radius-sm); padding:0 3px;
}
.bench-tile-flag{
  position:absolute; left:-2px; bottom:-2px; width:14px; height:10px; object-fit:cover;
  border-radius:2px; box-shadow:0 0 0 1px rgba(255,255,255,.5);
  transform:rotate(-18deg); filter:drop-shadow(0 1px 2px rgba(0,0,0,.6));
}
.bench-tile-name{font-size:8.5px; font-weight:700; padding:var(--space-1) var(--space-1) 1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.bench-tile-meta{display:flex; align-items:center; justify-content:space-between; gap:3px; padding:0 var(--space-1) 5px;}
.bench-tile-meta .pos-tag{font-size:7.5px; padding:1px 4px;}

.drag-ghost{
  position:fixed; top:0; left:0; transform:translate(-50%,-50%); z-index:200; pointer-events:none;
  padding:var(--space-1-5) var(--space-3); border-radius:var(--radius-md); background:rgba(18,27,46,0.95);
  border:1.5px solid var(--color-primary); font-family:'JetBrains Mono',monospace; font-weight:700; font-size:12px;
  color:var(--color-text); box-shadow:var(--shadow-md);
}
.drag-ghost.pos-GK{border-color:var(--color-accent);}

.skill-tooltip{
  display:none; position:fixed; z-index:300; width:220px; max-height:min(340px, 70vh); overflow-y:auto;
  background:rgba(13,19,34,0.98); border:1px solid var(--color-primary); border-radius:var(--radius-md);
  padding:var(--space-3) var(--space-3-5); box-shadow:var(--shadow-lg);
}
.skill-tooltip-head{
  display:flex; align-items:center; gap:var(--space-1-5); flex-wrap:wrap; font-size:var(--text-xs); font-weight:700;
  margin-bottom:var(--space-2-5); padding-bottom:var(--space-2); border-bottom:1px solid var(--color-border); padding-right:20px;
}
.skill-tooltip-close{
  position:absolute; top:8px; right:8px; background:none; border:none; color:var(--color-text-muted);
  font-size:15px; line-height:1; cursor:pointer; padding:4px;
}
.skill-tooltip-close:hover{color:var(--color-text);}
.instr-line{font-size:var(--text-2xs); color:var(--color-text-muted); margin-bottom:var(--space-2-5);}
.role-sig-line{
  font-size:var(--text-2xs); color:var(--color-text-muted); line-height:var(--leading-snug);
  background:var(--color-surface-2); border-left:3px solid var(--color-primary);
  padding:var(--space-1-5) var(--space-2-5); border-radius:var(--radius-sm); margin-bottom:var(--space-2-5);
}
.role-effect-line{margin-top:var(--space-1-5);}

.talent-block{
  margin:0 0 var(--space-3-5); padding:var(--space-3) var(--space-3-5); border-radius:var(--radius-md);
  background:linear-gradient(135deg, rgba(212,167,60,0.14), rgba(212,167,60,0.03)); border:1px solid var(--color-accent);
}
.talent-badge{display:flex; align-items:center; gap:var(--space-2); font-weight:800; font-size:var(--text-sm); color:var(--color-accent); margin-bottom:4px;}
.talent-icon{font-size:16px;}
.talent-desc{font-size:var(--text-2xs); color:var(--color-text-muted); line-height:var(--leading-normal);}

.skill-group{margin-bottom:var(--space-4-5);}
.skill-group:last-child{margin-bottom:0;}
.skill-group-title{font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.6px; font-weight:700; color:var(--color-text-dim); margin-bottom:var(--space-2-5);}
.skill-row{margin-bottom:var(--space-2-5);}
.skill-row:last-child{margin-bottom:0;}
.skill-row-top{display:flex; justify-content:space-between; font-size:var(--text-xs); margin-bottom:4px;}
.skill-val{font-family:'JetBrains Mono',monospace; font-weight:700; color:var(--color-text);}
.skill-bar{height:6px; border-radius:var(--radius-sm); background:var(--color-surface-2); overflow:hidden;}
.skill-bar-fill{height:100%; border-radius:var(--radius-sm);}

/* ---- Турнир сборных (кабинет) ---- */
.nat-flag{width:20px; height:14px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 1px var(--color-border); flex-shrink:0;}
.nat-flag-lg{width:32px; height:22px; border-radius:3px;}
.nat-flag-hero{width:64px; height:44px; border-radius:6px; object-fit:cover; box-shadow:0 0 0 1px var(--color-border);}
.nat-teams-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:var(--space-3);}
.nat-team-card{border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; background:var(--color-surface-2);}
.nat-team-head{display:flex; align-items:center; gap:var(--space-2-5); padding:var(--space-3) var(--space-3-5); border-bottom:1px solid var(--color-border);}
.nat-team-name{font-weight:700; font-size:var(--text-sm);}
.nat-squad-list{padding:var(--space-1-5) var(--space-3-5) var(--space-2-5);}
.nat-squad-row{display:flex; align-items:center; gap:var(--space-2); padding:5px 0; font-size:var(--text-xs); border-bottom:1px dashed var(--color-border);}
.nat-squad-row:last-child{border-bottom:none;}
.nat-squad-name{flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nat-squad-ovr{font-family:'JetBrains Mono',monospace; color:var(--color-text-dim); font-size:var(--text-2xs);}

/* ---- Турнир: таблица + расписание (кабинет и админка) ---- */
.standings-own{background:var(--color-primary-subtle);}
.fixture-row{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-3);
  padding:var(--space-3) var(--space-3-5); border:1px solid var(--color-border); border-radius:var(--radius-md);
  margin-top:var(--space-2); transition:border-color var(--duration-fast) var(--ease);
}
.fixture-row.own{border-color:var(--color-primary); background:var(--color-primary-subtle);}
.fixture-row[onclick]{cursor:pointer;}
.fixture-row[onclick]:hover{border-color:var(--color-border-strong);}
/* Хозяева | счёт плашкой | гости — сетка, счёт всегда по центру (DESIGN.md). */
.fixture-clubs{display:grid; grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr); align-items:center; gap:var(--space-3); flex:1 1 auto; min-width:260px;}
.fixture-club{display:flex; align-items:center; gap:var(--space-2); min-width:0; font-size:var(--text-sm); font-weight:600;}
.fixture-club .club-link{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.fixture-club-away{flex-direction:row-reverse; text-align:right;}
.fixture-clubs > .match-score-link, .fixture-clubs > .fixture-score-empty{
  min-width:56px; padding:2px var(--space-2-5); border-radius:var(--radius-sm); background:var(--color-surface-2);
  text-align:center; font-family:var(--font-display); font-size:1.1rem; letter-spacing:.04em; white-space:nowrap;
}
.fixture-clubs > .fixture-score-empty{color:var(--color-text-dim); font-size:.95rem;}
/* Стадия плей-офф вместо «Тур N» (HeroActions.vue): стадия и номер матча в две строки. */
.fixture-stage{display:flex; flex-direction:column; align-items:center; line-height:1.15; font-size:.95rem;}
.fixture-stage small{font-family:var(--font-body, inherit); font-size:10px; letter-spacing:0; color:var(--color-text-dim);}
@media(max-width:640px){ .fixture-clubs{min-width:0; gap:var(--space-2);} .fixture-row{padding:var(--space-2-5);} }
.fixture-meta{display:flex; align-items:center; gap:var(--space-2-5); flex-wrap:wrap;}
.fixture-events{padding:var(--space-2) var(--space-3-5) var(--space-2) calc(var(--space-3-5) + var(--space-3)); margin-top:-4px;}

.match-banner{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-3);
  background:var(--color-primary-subtle); border:1px solid var(--color-primary); border-radius:var(--radius-md);
  padding:var(--space-3) var(--space-3-5); margin-bottom:var(--space-4); font-size:var(--text-sm);
}

/* ---- Просмотр матча по клику на счёт (MatchDetailModal.vue,
   AdminScheduleSection.vue) — первый настоящий модальный диалог в
   проекте (не якорный тултип, как .skill-tooltip/.legend-tooltip):
   z-index выше их обоих (300), т.к. открывается кликом внутри страницы
   админки, которая сама может показывать всплывающие подсказки. ---- */
.match-score-link{cursor:pointer; color:inherit; text-decoration:none; transition:color var(--duration-fast) var(--ease);}
.match-score-link:hover{color:var(--color-primary);}
.modal-backdrop{
  position:fixed; inset:0; z-index:400; background:rgba(6,10,20,0.72);
  display:flex; align-items:center; justify-content:center; padding:var(--space-5);
}
.modal-card{max-width:560px; width:100%; max-height:85vh; overflow-y:auto; position:relative;}
.modal-close{
  position:absolute; top:var(--space-3); right:var(--space-3); background:none; border:none; cursor:pointer;
  color:var(--color-text-dim); font-size:16px; line-height:1; padding:var(--space-1);
  transition:color var(--duration-fast) var(--ease);
}
.modal-close:hover{color:var(--color-text);}
.match-goals-list{display:flex; flex-direction:column; gap:var(--space-1-5); margin-top:var(--space-2);}
.goal-row{
  display:flex; align-items:center; gap:var(--space-2-5); padding:var(--space-2) var(--space-3);
  border:1px solid var(--color-border); border-radius:var(--radius-md); font-size:var(--text-sm);
}
.goal-row-minute{font-family:'JetBrains Mono',monospace; font-weight:700; color:var(--gold); flex-shrink:0; width:32px; text-align:right;}
.goal-row-scorer{font-weight:700; flex:1; min-width:0;}
.goal-row-club{display:flex; align-items:center; gap:var(--space-1-5); color:var(--color-text-muted); font-size:var(--text-xs); flex-shrink:0;}

/* ---- "Составы" в попапе результата матча (MatchDetailModal.vue) — из
   0-минутного lineup-снэпшота, строки по зонам сетки 6×5 (те же подписи,
   что и остальная тактика на сайте), без отдельного запроса состава. */
.match-lineups{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4);}
@media(max-width:520px){ .match-lineups{grid-template-columns:1fr;} }
.match-lineup-head{display:flex; align-items:center; gap:var(--space-1-5); font-weight:700; margin-bottom:var(--space-2); padding-bottom:var(--space-1-5); border-bottom:1px solid var(--color-border);}
.match-lineup-row{display:flex; gap:var(--space-2); padding:var(--space-1) 0; font-size:var(--text-xs); line-height:var(--leading-normal);}
.match-lineup-row b{flex-shrink:0; width:112px; color:var(--color-text-muted); font-weight:600;}
.match-lineup-row span{min-width:0;}

/* ---- "Полный матч" — проигрывание лога владений (MatchPitchViz.vue,
   useMatchPlayback.js) — портировано из engine/football-manager-mvp.html
   (разделы "Match visualization"/"Match tab"), переменные прототипа
   заменены на токены прода (var(--bg2)→var(--color-surface-2),
   var(--border)→var(--color-border), var(--text-muted)/var(--text-dim)→
   var(--color-text-muted)/var(--color-text-dim); var(--pitch-light)/
   var(--gold) совпадают дословно — не тронуты). .pitch/.pitch-wrap/
   .pitch-line/.pitch-circle/.pitch-box уже есть выше (тактическая доска,
   тот же прототип-источник) — не дублируются. Полоски усталости под
   футболками (viz-fatigue-*) сознательно не перенесены — V1 без
   внутриматчевой усталости, см. matchEngine.js. ---- */
/* Одна строка (по прямому запросу — раньше команды и значки событий были
   двумя отдельными flex-wrap:wrap блоками, на узких экранах расползались
   на 4 строки сразу). flex-wrap:nowrap + overflow-x:auto — тот же приём,
   что у .table-wrap: не влезло — горизонтальный скролл внутри строки, а
   не перенос и не сжатие текста/иконок до нечитаемого размера. */
.viz-legend{display:flex; align-items:center; gap:var(--space-4); flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; font-size:var(--text-xs); color:var(--color-text-muted); margin:var(--space-3) 0; padding-bottom:2px;}
.viz-legend span{display:flex; align-items:center; gap:var(--space-1-5); flex:0 0 auto; white-space:nowrap;}
.viz-legend-sep{width:1px; height:14px; background:var(--color-border); flex:0 0 auto;}
.viz-dot{width:9px; height:9px; border-radius:var(--radius-full); display:inline-block; flex:0 0 auto;}
.viz-pitch-wrap{width:100%; max-width:420px; margin:var(--space-3) auto 0;}
/* Поле на Pixi (MatchPitchPixi.vue) — те же пропорции, что у DOM-поля
   (.pitch: 2:3, на ≥900px горизонтально 100:64); canvas внутри — на всю площадь. */
.pitch-pixi{position:relative; width:100%; aspect-ratio:2/3; border-radius:var(--radius-md); overflow:hidden; background:var(--pitch);}
.pitch-pixi.horizontal{aspect-ratio:100/64;}
.pitch-pixi canvas{display:block; width:100%; height:100%;}
/* Камера Pixi-поля на телефоне: «следить за мячом / всё поле». */
.pitch-cam-toggle{
  position:absolute; top:8px; right:8px; z-index:2; width:32px; height:32px; border-radius:var(--radius-full);
  border:1px solid rgba(255,255,255,0.35); background:rgba(0,0,0,0.45); color:#fff; font-size:16px; line-height:1;
  display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
}
.pitch-cam-toggle:hover{background:rgba(0,0,0,0.6);}
/* Два последних комментария ленты поверх поля (PitchCommentary.vue) — внизу
   поля, новый снизу; поле под плашкой не кликабельно, ссылки в тексте — да. */
.pitch-comm{
  position:absolute; left:6px; right:6px; bottom:6px; z-index:3; pointer-events:none;
  display:flex; flex-direction:column; gap:2px; padding:5px 8px; border-radius:var(--radius-sm);
  background:rgba(6,12,20,0.62); color:#fff; font-size:12px; line-height:1.35; text-shadow:0 1px 2px rgba(0,0,0,0.6);
}
.pitch-comm-line{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.pitch-comm-line:not(:last-child){opacity:0.6;}
.pitch-comm-line a{pointer-events:auto; color:inherit;}
.pitch-comm-min{color:var(--teal-100); font-variant-numeric:tabular-nums;}
.pitch-comm-goal{color:var(--gold-300, #f3d27a); font-weight:600;}
.pitch-comm-enter-active{transition:opacity .25s ease, transform .25s ease;}
.pitch-comm-enter-from{opacity:0; transform:translateY(6px);}
.pitch-comm-leave-active{display:none;}
@media(max-width:480px){ .pitch-comm{font-size:11px; left:4px; right:4px; bottom:4px; padding:4px 6px;} }
/* Сетка плей-офф деревом (PlayoffTree.vue): 5 колонок, пары следующей
   стадии — посередине между своими; на узком экране — прокрутка вбок. */
.ptree-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; margin:0 calc(-1 * var(--space-2)); padding:0 var(--space-2) var(--space-2);}
.ptree{display:grid; grid-template-columns:repeat(5, minmax(184px, 1fr)); gap:var(--space-3); min-width:980px;}
.ptree-col{display:flex; flex-direction:column; min-width:0;}
.ptree-col-title{font-size:var(--text-2xs); text-transform:uppercase; letter-spacing:.06em; color:var(--color-text-dim); font-weight:700; text-align:center; margin-bottom:var(--space-2);}
.ptree-col-body{flex:1; display:flex; flex-direction:column; justify-content:space-around; gap:var(--space-2);}
.ptree-box{position:relative; border:1px solid var(--color-border); border-radius:var(--radius-md); background:var(--color-surface-2, rgba(255,255,255,0.03)); padding:6px 8px;}
.ptree-box.projected{border-style:dashed; opacity:.85;}
.ptree-final .ptree-box{border-color:var(--gold); box-shadow:0 0 0 1px rgba(212,167,60,0.25);}
.ptree-col:not(.ptree-final) .ptree-box::after{content:''; position:absolute; right:calc(-1 * var(--space-3)); top:50%; width:var(--space-3); border-top:1px solid var(--color-border);}
.ptree-team{display:flex; align-items:center; gap:6px; min-height:22px; font-size:var(--text-xs);}
.ptree-team.win .ptree-name{font-weight:800;}
.ptree-team.lose{opacity:.55;}
.ptree-team.mine{background:var(--color-primary-subtle); border-radius:var(--radius-sm); margin:0 -4px; padding:0 4px;}
.ptree-name{flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.ptree-seed{font-size:10px; color:var(--color-text-dim); font-family:'JetBrains Mono',monospace;}
.ptree-agg{min-width:16px; text-align:right; font-family:'JetBrains Mono',monospace; color:var(--pitch-light);}
.ptree-tbd{flex:1; min-width:0; color:var(--color-text-dim); font-style:italic; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.ptree-legs{display:flex; justify-content:flex-end; gap:8px; margin-top:2px; font-size:10.5px;}
.ptree-hint{margin:0 0 var(--space-2);}

/* Разбор матча под Pixi-полем: режимы и выбор команды. */
.pitch-analysis{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--space-1-5); margin-top:var(--space-2);}
.pitch-renderer-switch{display:flex; align-items:center; justify-content:center; gap:var(--space-1-5); margin-top:var(--space-2);}

/* ---- Составы слева/справа от поля на вкладке "Полный матч"
   (MatchDetailCard.vue) — по прямому запросу, скилл/полоска усталости рядом
   с именем. На узких экранах — колонкой (сначала домашний состав, потом
   поле, потом гостевой), на широких — по бокам от поля.
   ⚠️ .match-viz-pitch-col ОБЯЗАТЕЛЕН — MatchPitchViz.vue рендерит НЕСКОЛЬКО
   корневых элементов (viz-legend/match-scoreboard/match-clock/viz-pitch-
   wrap, не один div), и без обёртки Vue разложил бы их ЧЕТЫРЬМЯ отдельными
   flex-item'ами прямо в match-viz-layout вперемешку с составами — сама
   разметка "поехала" именно поэтому при первой попытке. */
/* Легенда цветов формы/табло/часы — теперь рисуются MatchDetailCard.vue
   САМ, одним блоком НАД всем рядом "состав/поле/состав" (MatchPitchViz.vue
   получает hide-header и не дублирует их у себя) — раньше они жили ВНУТРИ
   узкой центральной колонки, из-за чего верх поля не совпадал по
   вертикали с верхом панелей составов. max-width совпадает с
   .viz-pitch-wrap (420px) и центрируется тем же приёмом (margin:auto) —
   так табло гарантированно центрируется именно над полем, а не над всей
   (более широкой из-за составов по бокам) шириной страницы. */
.match-viz-header{max-width:420px; margin:0 auto;}
.match-viz-layout{display:flex; align-items:flex-start; justify-content:center; gap:var(--space-4); flex-wrap:wrap;}
.match-viz-pitch-col{flex:1 1 420px; min-width:280px;}
.match-viz-pitch-col .viz-pitch-wrap{margin-top:0;}
/* Ширина панелей составов — по прямому запросу считается от ширины
   экрана (vw), а не от фиксированного пикселя: раньше max-width:240px
   не давал составам занять освободившееся место на широких мониторах
   после перехода страницы матча на 100% ширины (раздел 101/п.101) — вся
   лишняя ширина уходила пустым полем вокруг поля (у самого поля свой
   потолок 420px, .viz-pitch-wrap). flex:0 0 20vw — фиксированная доля
   экрана, не зависящая от того, сколько места просит колонка поля;
   min-width — пол читаемости на средних экранах (на <900px это всё
   равно перекрывается медиа-запросом ниже, там колонка на 100%).
   Журнал п.222 (по прямому запросу): сыгранный матч теперь в стандартном
   контейнере сайта (1250px), не на 100% ширины — доля считается от
   контейнера (%), а не от экрана (vw): на широком мониторе 2×20vw + поле
   не помещались бы в 1250px и колонки уезжали бы на новую строку. */
.match-viz-squad{flex:0 0 22%; max-width:22%; min-width:180px; font-size:calc(var(--text-2xs) * 1.3);}
.match-viz-squad-head{display:flex; align-items:center; gap:var(--space-1-5); font-weight:700; margin-bottom:var(--space-1-5); padding-bottom:var(--space-1); border-bottom:1px solid var(--color-border);}
.match-viz-squad-row{display:flex; align-items:center; gap:var(--space-1-5); padding:3px 0; border-bottom:1px solid var(--color-border);}
.match-viz-squad-name{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.match-viz-squad-ovr{color:var(--color-text-muted); flex-shrink:0; width:2.2em; text-align:right;}
.match-viz-squad-fatigue{width:2.6em; flex-shrink:0;}
/* Оценка за матч (frontend/src/matchRatings.js, база 5.0, диапазон 0-10) — обратная
   полярность цвета относительно .fatigue-*: высокое значение здесь
   хорошо (зелёный), поэтому отдельные классы, не переиспользуем
   .fatigue-low/mid/high, чтобы не путать смысл цвета в двух контекстах. */
.match-viz-squad-rating{flex-shrink:0; width:2em; text-align:center; font-weight:700;}
.rating-good{color:var(--color-success);}
.rating-mid{color:var(--gold-500);}
.rating-bad{color:var(--color-danger);}
@media(max-width:899px){ .match-viz-squad{max-width:none; flex-basis:100%;} .match-viz-pitch-col{flex-basis:100%;} }
.viz-player{
  position:absolute; transform:translate(-50%,-50%); width:6.1%; aspect-ratio:1;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,0.45));
  transition:left .9s ease, top .9s ease;
  z-index:5;
}
/* Имя под футболкой (по умолчанию) — по прямому запросу переопределяется
   для "домашней" стороны ниже (.viz-player-home) на "над футболкой", у
   "выездной" (.viz-player-away) остаётся как было — снизу. */
.viz-player::after{
  content:attr(title); position:absolute; top:100%; left:50%; transform:translateX(-50%);
  font-size:8px; color:rgba(255,255,255,0.75); white-space:nowrap; margin-top:1px;
}
.viz-player-home::after{ top:auto; bottom:100%; margin-top:0; margin-bottom:1px; }
.viz-player.viz-player-carrier{
  z-index:10;
  filter:drop-shadow(0 0 3px rgba(0,0,0,0.4)) drop-shadow(0 0 8px var(--pitch-light)) drop-shadow(0 0 8px var(--pitch-light));
  animation:carrierPulse 1s ease-in-out infinite;
}
@keyframes carrierPulse{
  0%,100%{transform:translate(-50%,-50%) scale(1);}
  50%{transform:translate(-50%,-50%) scale(1.16);}
}
.viz-ball{
  position:absolute; transform:translate(-50%,-50%); font-size:16px; line-height:1; z-index:20;
  transition:left 1.1s cubic-bezier(.4,0,.2,1), top 1.1s cubic-bezier(.4,0,.2,1);
  filter:drop-shadow(0 2px 4px rgba(0,0,0,0.6));
}
.viz-ball-trail{
  position:absolute; transform:translate(-50%,-50%); width:13px; height:13px; border-radius:var(--radius-full);
  background:radial-gradient(circle, rgba(255,255,255,0.85), rgba(255,255,255,0));
  pointer-events:none; z-index:15;
  animation:trailFade .75s ease-out forwards;
}
@keyframes trailFade{
  from{opacity:.9; transform:translate(-50%,-50%) scale(1);}
  to{opacity:0; transform:translate(-50%,-50%) scale(2.4);}
}
/* .viz-struggle — контейнер "момента" (matchViz.js momentIcon), размер
   уменьшен вслед за футболками (по прямому запросу — на прежних 15%
   после недавнего -33% у .viz-player иконка момента стала непропорцио-
   нально огромной), амплитуда пульса тоже сглажена (0.85-1.2 → 0.92-1.08). */
.viz-struggle{
  position:absolute; transform:translate(-50%,-50%); width:9%; aspect-ratio:1; z-index:18;
  pointer-events:none; display:flex; align-items:center; justify-content:center;
  animation:struggleFlash 0.6s ease-in-out infinite alternate;
}
.viz-struggle-emoji{ font-size:15px; line-height:1; filter:drop-shadow(0 1px 3px rgba(0,0,0,0.6)); }
/* .viz-struggle-corner — по прямому запросу: иконка подката/отбора/
   подбора (🔥, раньше газонокосилка) рисуется не на месте мяча, а со
   сдвигом в верхний правый угол единоборства (ближе к футболкам), в
   отличие от teamPress-иконки (та же 🔥, без этого модификатора),
   которая остаётся на месте мяча, как и раньше. margin — не transform,
   чтобы не конфликтовать с уже имеющимся translate(-50%,-50%) на
   .viz-struggle (центрирование) и его же scale в @keyframes struggleFlash. */
.viz-struggle-corner{ margin-left:5%; margin-top:-5%; }
@keyframes struggleFlash{
  from{opacity:0.6; transform:translate(-50%,-50%) scale(0.92);}
  to{opacity:1; transform:translate(-50%,-50%) scale(1.08);}
}

/* Ворота (по прямому запросу) — простая рамка+сетка на обеих линиях
   ворот (та же зона, что и спецключ 'goal' в matchViz.js sharedPos,
   y≈2/98 — вплотную к краю .pitch). Чисто декоративная геометрия поля —
   портретная ориентация (горизонтальная полоса у верхнего/нижнего края);
   в горизонтальной десктоп-раскладке своя геометрия, см. медиа-запрос
   ниже (вертикальная полоса у левого/правого края). */
.viz-goal{
  position:absolute; left:50%; width:18%; height:3.5%; transform:translateX(-50%);
  border:2px solid rgba(255,255,255,0.55);
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.14) 0 1.5px, transparent 1.5px 6px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,0.14) 0 1.5px, transparent 1.5px 6px);
  z-index:2;
}
.viz-goal-top{ top:0; border-top:none; }
.viz-goal-bottom{ bottom:0; border-bottom:none; }

/* Вспышка попадания мяча в ворота (по прямому запросу) — на месте
   playback.ballPos, когда текущее событие ленты — 'goal' (тот же ключ
   'goal' у sharedPos, что уже используется для анимации удара). */
.viz-goal-flash{
  position:absolute; transform:translate(-50%,-50%); width:22%; aspect-ratio:1; z-index:21;
  border-radius:var(--radius-full); pointer-events:none;
  background:radial-gradient(circle, rgba(255,255,255,0.95), rgba(212,167,60,0.55) 45%, transparent 72%);
  animation:goalFlash 0.9s ease-out;
}
@keyframes goalFlash{
  0%{opacity:0; transform:translate(-50%,-50%) scale(0.3);}
  35%{opacity:1; transform:translate(-50%,-50%) scale(1.35);}
  100%{opacity:0; transform:translate(-50%,-50%) scale(1.9);}
}

/* Стрелки прессинга (оригинальный дизайн, вернули по прямому запросу —
   1-2 прессующих) — SVG-оверлей на всю площадь .pitch, координаты 0-100
   совпадают с left/top% остальных элементов (viewBox+preserveAspectRatio
   ="none" растягивает 1:1 без искажения математики, даже если .pitch не
   квадрат). z-index ниже игроков (5) — стрелки не должны перекрывать
   футболки. */
.viz-press-arrows{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:4; }
.viz-dribble-arrow{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:4; }

/* Индикатор "окружения" (для 3+ прессующих) — позиционируется как обычный
   элемент поля (left/top%, тот же приём, что у .viz-player), не SVG-оверлей.
   По прямому запросу — круговые стрелки заменены на пульсирующий красный
   круг (чистый CSS, без v-html SVG): радиальная заливка + контур, масштаб
   и прозрачность колеблются keyframes-анимацией. */
.viz-press-indicator{ position:absolute; pointer-events:none; z-index:4; }
.viz-press-indicator-circle{
  width:13%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle, rgba(255,64,48,0.9) 0%, rgba(255,64,48,0.5) 60%, rgba(255,64,48,0) 100%);
  box-shadow:0 0 0 2px rgba(150,20,15,0.95) inset;
  animation: pressPulse 0.9s ease-in-out infinite;
}
@keyframes pressPulse{
  0%{ transform:translate(-50%,-50%) scale(0.8); opacity:0.55; }
  50%{ transform:translate(-50%,-50%) scale(1.2); opacity:1; }
  100%{ transform:translate(-50%,-50%) scale(0.8); opacity:0.55; }
}

/* «Захват территории» (TerritoryApp.vue, план фаза 1) — клетки страны
   простой сеткой карточек, градиент владения — ширина заливки от счёта
   серии (attackerWins/3), не настоящая картографическая заливка (в
   проекте нет геоданных, см. план). */
.territory-cells{ display:grid; grid-template-columns:repeat(auto-fill, minmax(160px, 1fr)); gap:var(--space-2); }
.territory-cell{ border:1px solid var(--border); border-radius:8px; padding:var(--space-2); }
.territory-cell-head{ display:flex; justify-content:space-between; gap:var(--space-1); }
.territory-cell-note{ margin-top:var(--space-1); }
.territory-cell-bar{ height:6px; border-radius:3px; background:var(--surface2); overflow:hidden; margin-top:var(--space-1); }
.territory-cell-bar-fill{ height:100%; background:rgba(255,64,48,0.85); }

/* Горизонтальная раскладка для десктопа (по прямому запросу, ВТОРОЙ
   заход — первый через CSS rotate() всего .pitch выглядел плохо: футболки
   ложились на бок, всё оказывалось непропорционально крупным). Вместо
   поворота контейнера — координаты X/Y меняются местами ЕЩЁ В JS
   (MatchPitchViz.vue toScreen(), matchMedia('(min-width:900px)')) —
   игроки/мяч/имена остаются в НОРМАЛЬНОЙ ориентации, просто левая/
   правая половина экрана вместо верха/низа. Здесь — только геометрия
   СТАТИЧНОЙ разметки поля (та не завязана на JS-координаты): линия
   центра, штрафные и ворота поворачиваются на 90° явными правилами
   (не transform:rotate — тем же классом проблем, что и раньше, просто
   для меньшего числа элементов; переставлены сами left/top/width/height,
   геометрия остаётся простой прямоугольной, без искажений). Круг в
   центре (.pitch-circle) не трогаем — он уже квадратный по построению
   (width и padding-bottom заданы ОДНИМ и тем же % от ширины контейнера,
   см. правило выше) и остаётся кругом при любой пропорции .pitch. */
@media (min-width: 900px){
  .viz-pitch-wrap{ max-width:640px; }
  .viz-pitch-wrap .pitch{ width:100%; padding-bottom:64%; }
  .viz-pitch-wrap .pitch-line.pitch-halfway{
    top:0; bottom:0; left:50%; right:auto; height:auto; width:2px;
  }
  .viz-pitch-wrap .pitch-box{
    left:auto; right:auto; width:15%; height:46%; padding-bottom:0;
    top:50%; transform:translateY(-50%);
  }
  .viz-pitch-wrap .pitch-box-top{ left:0; border-top:2px solid rgba(255,255,255,0.25); border-left:none; }
  .viz-pitch-wrap .pitch-box-bottom{ left:auto; right:0; border-bottom:2px solid rgba(255,255,255,0.25); border-right:none; }
  .viz-pitch-wrap .viz-goal{
    left:auto; top:50%; width:3%; height:18%; transform:translateY(-50%);
  }
  .viz-pitch-wrap .viz-goal-top{ top:50%; left:0; border-top:2px solid rgba(255,255,255,0.55); border-left:none; }
  .viz-pitch-wrap .viz-goal-bottom{ bottom:auto; top:50%; left:auto; right:0; border-bottom:2px solid rgba(255,255,255,0.55); border-right:none; }
  .viz-pitch-wrap .viz-player{ width:4.4%; }
  .viz-pitch-wrap .viz-player::after{ font-size:10px; }
}

.match-scoreboard{display:flex; align-items:center; justify-content:center; gap:var(--space-5); margin:var(--space-4) 0 var(--space-1-5);}
.match-team{display:flex; align-items:center; gap:var(--space-2-5); font-size:var(--text-sm); font-weight:700;}
.match-team-right{flex-direction:row-reverse;}
.match-score{
  font-family:'JetBrains Mono',monospace; font-size:var(--text-3xl); font-weight:800; letter-spacing:.5px;
  background:var(--color-surface-2); border:1px solid var(--color-border); border-radius:var(--radius-md);
  padding:var(--space-1) var(--space-4); min-width:90px; text-align:center;
}
.match-clock{
  text-align:center; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:var(--text-sm); color:var(--gold);
  margin-bottom:var(--space-3);
}

.attack-log{display:flex; flex-direction:column; gap:var(--space-1-5); margin-top:var(--space-2); max-height:260px; overflow-y:auto;}
.attack-log-row{
  display:flex; align-items:baseline; gap:var(--space-2); padding:var(--space-2) var(--space-2-5); border-radius:var(--radius-md); font-size:var(--text-xs);
  background:var(--color-surface-2); border-left:3px solid var(--color-border);
}
.attack-log-success{border-left-color:var(--pitch-light);}
.attack-log-fail{border-left-color:var(--red-300);}
.match-goal-row{border-left-color:var(--gold); background:rgba(212,167,60,0.08); font-weight:700;}
.attack-log-step{font-family:'JetBrains Mono',monospace; font-weight:800; color:var(--color-text-dim); flex-shrink:0;}

.role-legend{display:grid; grid-template-columns:repeat(auto-fit, minmax(190px,1fr)); gap:var(--space-4); margin-top:var(--space-2-5);}
.role-legend-group-title{font-size:var(--text-2xs); font-weight:800; text-transform:uppercase; letter-spacing:.4px; margin-bottom:var(--space-2);}
.role-legend-row{display:flex; align-items:center; gap:var(--space-2); padding:3px 0; font-size:var(--text-xs); color:var(--color-text-muted);}

/* ---- Hover-подсказка с расшифровкой роли (значимость + плюсы/минусы) ---- */
.legend-tag-wrap{position:relative; cursor:help;}
.role-tag-hover{position:relative; display:inline-flex; cursor:help;}
.role-tag-hover:hover .legend-tooltip, .legend-tag-wrap:hover .legend-tooltip{display:block;}
.role-tag-hover.open .legend-tooltip, .legend-tag-wrap.open .legend-tooltip{display:block;}
.role-tag-hover .legend-tooltip{left:auto; right:0;}
.legend-tooltip{
  display:none; position:absolute; left:0; top:calc(100% + 8px); z-index:250; width:250px;
  background:rgba(13,19,34,0.98); border:1px solid var(--color-primary); border-radius:var(--radius-md);
  padding:var(--space-3) var(--space-3-5); box-shadow:var(--shadow-lg); cursor:default; text-align:left;
}
.legend-tooltip-title{font-size:var(--text-sm); font-weight:800; color:var(--color-text); margin-bottom:var(--space-1-5); display:flex; align-items:center; gap:var(--space-1-5);}
.legend-tooltip-sig{font-size:var(--text-xs); color:var(--color-text-muted); line-height:var(--leading-snug); margin-bottom:var(--space-2);}
.legend-tooltip-pros{font-size:var(--text-xs); color:var(--color-success); line-height:1.6;}
.legend-tooltip-cons{font-size:var(--text-xs); color:var(--red-300); line-height:1.6; margin-top:2px;}

/* Значок "ⓘ" рядом с текстом роли (RoleInfoIcon.vue) — та же .role-tag-hover
   механика, что и у самого тега роли (RoleTag.vue), другой визуальный
   триггер, поэтому и своё позиционирование тултипа: слева, не справа
   (справа у него в таблицах "Навыки и формулы" часто нет места). */
.role-info-icon{margin-left:var(--space-1-5); color:var(--color-text-dim); font-size:var(--text-sm); vertical-align:middle;}
.role-info-icon:hover, .role-info-icon.open{color:var(--color-primary);}
.role-info-icon .legend-tooltip{left:0; right:auto;}

/* Онбординг-попап HintIcon.vue/HintTooltipCard.vue — тот же .role-info-icon
   значок, содержимое шире, когда это список вариантов (группа кнопок
   тактики/стиля клуба), а не один абзац текста (отдельная кнопка). */
.legend-tooltip-wide{width:300px;}
.hint-tooltip-list{display:flex; flex-direction:column; gap:var(--space-2);}
.hint-tooltip-item-label{font-size:var(--text-xs); font-weight:700; color:var(--color-text);}
.hint-tooltip-item-text{font-size:var(--text-xs); color:var(--color-text-muted); line-height:var(--leading-snug);}

/* ---- Новости (лендинг + /news.html) ----
   Сетка на 4 колонки — «главная» новость (featured) занимает 2 клетки по
   ширине (grid-column:span 2), обычная — 1. См. selectNewsForHome() в
   js/news.js — количество новостей на главной считается именно от этой
   сетки (8 клеток = 2 строки). */
/* ---- Технический блок "Что под капотом" (лендинг, index.html) — для
   органического продвижения: развёрнутый, содержательный текст об
   устройстве игры, не просто маркетинговый слоган. Карточки крупнее и
   текстовее, чем .feature-card выше — там сжатые буллеты, здесь
   абзацы. */
.about-game{margin:var(--space-10) 0;}
.about-game-eyebrow{
  text-align:center; font-family:var(--font-display); font-size:var(--text-xs); letter-spacing:.22em;
  text-transform:uppercase; color:var(--teal-300); margin-bottom:var(--space-2);
}
.about-game h2{text-align:center; margin-bottom:var(--space-3);}
.about-game-lead{max-width:640px; margin:0 auto var(--space-8); text-align:center; color:var(--color-text-muted); font-size:var(--text-base); line-height:var(--leading-normal);}
.about-game-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); gap:var(--space-5);}
.about-game-block{background:var(--card-bg); border:1px solid var(--card-border); border-radius:var(--card-radius); padding:var(--space-5);}
.about-game-block h3{margin:0 0 var(--space-2); font-size:var(--text-lg); color:var(--color-accent);}
.about-game-block p{margin:0; color:var(--color-text-muted); font-size:var(--text-sm); line-height:var(--leading-normal);}

.news-section{margin:var(--space-10) 0;}
.news-section h2{text-align:center; margin-bottom:var(--space-6);}
.news-list{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--space-4);}
@media(max-width:899px){ .news-list{grid-template-columns:repeat(2,1fr);} }
@media(max-width:599px){ .news-list{grid-template-columns:1fr;} }
.news-card{
  background:var(--card-bg); border:1px solid var(--card-border); border-radius:var(--card-radius);
  overflow:hidden; display:flex; flex-direction:column;
  transition:border-color var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
/* По прямому запросу — тот же hover, что уже есть у .feature-card
   (line ~360): подсветка рамки бирюзовым + лёгкий подъём карточки. */
.news-card:hover{border-color:var(--teal-300); transform:translateY(-2px);}
.news-card.featured{grid-column:span 2; border-color:var(--color-accent);}
/* Сброс span'а главной новости на 1 колонку при <=599px ОБЯЗАТЕЛЬНО должен
   идти ПОСЛЕ базового правила `.news-card.featured{grid-column:span 2}`
   выше — при равной специфичности (тот же селектор) в CSS каскаде
   побеждает более позднее по тексту файла правило, а не более специфичный
   @media. Если поставить это правило раньше (как было изначально — баг,
   найденный по скриншоту с «рваными» отступами на мобилке) — reset вообще
   никогда не применяется ни на одной ширине: span:2 остаётся всегда,
   сетке из одной явной колонки не хватает места и она тихо достраивает
   ещё одну implicit-колонку под этот span, из-за чего все ПОСЛЕДУЮЩИЕ
   карточки расползаются по двум колонкам (одна из них схлопывается почти
   до 0px) вместо аккуратной вертикальной стопки — именно это и создавало
   гигантские пустые промежутки между карточками. */
@media(max-width:599px){ .news-card.featured{grid-column:span 1;} }
.news-card-img{width:100%; aspect-ratio:16/9; object-fit:cover; display:block;}
.news-card.featured .news-card-img{aspect-ratio:21/9;}
.news-card-body{padding:var(--space-5); flex:1; display:flex; flex-direction:column;}
.news-card-date{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.4px; margin-bottom:var(--space-2);}
.news-card h3{margin:0 0 var(--space-1-5); font-size:var(--text-lg); color:var(--color-text);}
.news-card.featured h3{font-size:var(--text-2xl);}
.news-card p{margin:0; color:var(--color-text-muted); font-size:var(--text-sm); line-height:var(--leading-normal);}

/* Мобилка/планшет (<900px) — вёрстка карточки как была (картинка сверху
   на всю ширину), три точечных уточнения: (1) бордер карточки убран
   целиком (включая акцентный у главной новости) — на узкой колонке,
   вплотную к краю экрана, рамка неуместна, карточки разделяет только
   gap сетки + фон; (2) align-items:start вместо дефолтного
   grid-стретча — раньше карточка с коротким текстом в одном ряду
   вытягивалась под самую длинную соседку и снизу оставалось пустое
   поле, из-за чего сетка «на глаз» выглядела неровной; (3) текст
   обрезается line-clamp'ом в 3 строки — карточки с длинным текстом
   новости растягивались на весь его объём и были заметно длиннее
   остальных. */
@media(max-width:899px){
  .news-list{align-items:start;}
  .news-card{border:none;}
  .news-card p{
    display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; line-clamp:3;
    overflow:hidden; text-overflow:ellipsis;
  }
}

/* Десктоп (≥900px) — картинка слева (float), с отступом 5px от рамки
   карточки, текст (дата/заголовок/текст) обтекает её и уходит на всю
   ширину карточки, как только опускается ниже нижнего края картинки.
   .news-card временно выходит из флекс-режима именно здесь: float
   игнорируется у флекс-элементов (CSS Flexbox spec, п.5.1) — при
   display:flex картинка и .news-card-body были бы просто двумя
   колонками/строками без обтекания. overflow:hidden на карточке (см.
   базовое правило выше) заодно «схлопывает» карточку по высоте float'а,
   если картинка выше текста — без него высота карточки не учитывала бы
   float вообще. */
@media(min-width:900px){
  .news-card{display:block;}
  .news-card-img{float:left; width:110px; aspect-ratio:4/3; margin:5px; border-radius:var(--radius-sm);}
  .news-card.featured .news-card-img{width:200px; aspect-ratio:16/10;}
}

/* ---- Список турниров (tournaments.html) — плитки по аналогии с
   .news-list/.news-card, но без картинки (у турнира её нет) и в две
   колонки максимум (сейчас только 2 турнира — Д1/Д2), auto-fit сам
   схлопнет в одну на узких экранах без отдельного @media. ---- */
.tournament-list{display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:var(--space-4);}
.tournament-card{
  display:block; background:var(--card-bg); border:1px solid var(--card-border); border-radius:var(--card-radius);
  padding:var(--space-5); text-decoration:none; color:inherit;
  transition:border-color var(--duration-base) var(--ease), transform var(--duration-base) var(--ease);
}
.tournament-card:hover{border-color:var(--color-accent); text-decoration:none; transform:translateY(-2px);}
.tournament-card-eyebrow{font-size:var(--text-2xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.4px; margin-bottom:var(--space-2);}
.tournament-card h3{margin:0 0 var(--space-3); font-size:var(--text-xl); color:var(--color-text);}
.tournament-card-leader{display:flex; align-items:center; gap:var(--space-2); font-size:var(--text-sm); color:var(--color-text-muted); margin-bottom:var(--space-2);}
.tournament-card-meta{font-size:var(--text-xs);}
/* Плашки «Лиг» на /tournaments (по прямому запросу «компактнее») — 15
   стран, флаг вместо кубка, строкой: флаг · название + страна · счёт. */
.tournament-list--compact{grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:var(--space-2);}
.tournament-card--compact{display:flex; align-items:center; gap:var(--space-2-5); padding:var(--space-2-5) var(--space-3);}
.tournament-card--compact:hover{transform:none;}
.tournament-card-flag{width:26px; height:18px; object-fit:cover; border-radius:3px; box-shadow:0 0 0 1px var(--color-border); flex-shrink:0;}
.tournament-card-compact-main{min-width:0; flex:1;}
.tournament-card-compact-title{font-size:var(--text-sm); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.tournament-card-compact-sub{font-size:var(--text-2xs);}
.tournament-card-compact-meta{font-size:var(--text-xs); font-variant-numeric:tabular-nums; flex-shrink:0;}
.tournament-detail-title{display:flex; align-items:center; gap:var(--space-3);}

/* =========================================================================
   GLASS CARDS — лёгкий эффект стекла для .card/.feature-card/.news-card/
   .news-card-body/.about-game-block, по прямому запросу пользователя.
   Намеренно НЕ добавлено правкой существующих правил этих классов выше по
   файлу (они остаются как были) — новый блок просто переопределяет
   background/border-color/тень КАСКАДОМ (та же специфичность, но идёт
   позже в файле → побеждает). Откат — удалить этот блок целиком (и не
   трогать больше ничего): все исходные .card/.feature-card/... правила
   продолжат работать ровно как до этой правки.

   .news-card-body — только заливка+блюр, БЕЗ своих border-color/box-shadow:
   это вложенный блок внутри уже стеклянного .news-card (у которого
   overflow:hidden), отдельная тень на нём обрезалась бы родителем и
   выглядела бы криво — двойное стекло (родитель+дочерний блик) без
   конкурирующей рамки/тени читается чище.

   Тон — по прямой обратной связи после первой версии («светлее/прозрачнее»,
   референс — плитки Яндекс Телемоста): alpha фона снижена (.62→.44) и база
   светлее (gray-800→смесь ближе к gray-650), рамка-блик ярче (.08→.16), плюс
   --glass-card-sheen — тонкий диагональный градиент-блик (имитация света на
   стекле), рисуется ВТОРЫМ слоем background поверх заливки. Палитра
   остаётся тёмной (сайт без свето/тёмной темы) — светлее означает более
   прозрачным/ярким СТЕКЛОМ, а не переходом на светлую тему. */
:root{
  --glass-card-bg:rgba(28,39,72,.44);
  --glass-card-sheen:linear-gradient(155deg, rgba(255,255,255,.09), rgba(255,255,255,0) 45%);
  --glass-card-border:rgba(255,255,255,.16);
  --glass-card-blur:14px;
  --glass-card-shadow:0 8px 28px rgba(0,0,0,.24), inset 0 1px 0 rgba(255,255,255,.08);
}
.card, .feature-card, .news-card, .about-game-block{
  background:var(--glass-card-sheen), var(--glass-card-bg);
  border-color:var(--glass-card-border);
  backdrop-filter:blur(var(--glass-card-blur));
  -webkit-backdrop-filter:blur(var(--glass-card-blur));
  box-shadow:var(--glass-card-shadow);
  /* По прямому запросу — в некоторых местах карточка сидит в flex/grid-
     ячейке, которая выше её собственного контента (сетки .features/
     .news-list растягивают через align-items:stretch, но не все контексты
     .card так устроены); без height:100% фон-стекло обрывался бы на
     границе контента, а не занятого визуально места, — снизу оставалась
     бы просто фоновая заливка страницы. */
  height:100%;
}
/* .news-card-body НЕ переопределяет --glass-card-sheen сама — наследует
   ровно то значение, что досталось родителю .news-card ниже (вариации по
   nth-child), поэтому блик внутри карточки и на самой карточке совпадают
   без дублирования правил. */
.news-card-body{
  background:var(--glass-card-sheen), var(--glass-card-bg);
  backdrop-filter:blur(var(--glass-card-blur));
  -webkit-backdrop-filter:blur(var(--glass-card-blur));
  height:100%;
}

/* Вариации "преломления" — по прямому запросу, чтобы соседние карточки в
   одной сетке/списке (.features/.news-list/стопка .card в разделе
   админки) не читались как близнецы: 3 варианта sheen-градиента (угол +
   лёгкий цветной оттенок в фирменных акцентах сайта — золото/бирюза,
   см. :root primitives выше), циклически через nth-child(3n+2)/nth-child(3n)
   — карточка 1,4,7... остаётся на базовом (нейтральном) блике из :root
   выше, 2,5,8... получает золотой, 3,6,9... бирюзовый. Меняется ТОЛЬКО
   --glass-card-sheen (сам блик) — заливка/блюр/тень общие, эффект
   остаётся "тем же стеклом под другим углом света", а не другим
   материалом. */
.card:nth-child(3n+2), .feature-card:nth-child(3n+2), .news-card:nth-child(3n+2), .about-game-block:nth-child(3n+2){
  --glass-card-sheen:linear-gradient(210deg, rgba(212,167,60,.09), rgba(255,255,255,0) 55%);
}
.card:nth-child(3n), .feature-card:nth-child(3n), .news-card:nth-child(3n), .about-game-block:nth-child(3n){
  --glass-card-sheen:linear-gradient(95deg, rgba(94,234,212,.08), rgba(255,255,255,0) 60%);
}

/* Медальон под /img/cup.png (Twemoji 🏆, CC-BY 4.0, см. атрибуцию на
   страницах турниров) — одна и та же картинка на оба турнира, различие
   только в цвете подложки/рамки: золото для Лиги чемпионов, серебристо-
   синий для Лиги Европы. */
.tournament-cup-badge{
  width:44px; height:44px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  flex:none; margin-bottom:var(--space-2); border:2px solid transparent;
}
.tournament-cup-badge img{width:28px; height:28px; display:block;}
.tournament-cup-badge.champions{background:radial-gradient(circle, rgba(212,167,60,.28), rgba(212,167,60,.08)); border-color:var(--color-accent);}
.tournament-cup-badge.europa{background:radial-gradient(circle, rgba(159,180,199,.28), rgba(159,180,199,.08)); border-color:#9FB4C7;}
/* Лига конференций (migrations/075) — зелёный, как фирменный цвет турнира. */
.tournament-cup-badge.conference{background:radial-gradient(circle, rgba(46,204,113,.28), rgba(46,204,113,.08)); border-color:#2ECC71;}
/* Лига наций (турнир сборных, журнал п.207) — кубок серебряный, как и
   настоящий трофей Лиги наций (та же картинка, обесцвеченная фильтром), на
   тёмно-синем медальоне — отличим и от золотой ЛЧ, и от серо-голубой ЛЕ. */
.tournament-cup-badge.nations{background:radial-gradient(circle, rgba(47,94,196,.45), rgba(20,40,110,.25)); border-color:#4C7BE0;}
.tournament-cup-badge.nations img{filter:grayscale(1) brightness(1.35) contrast(1.1);}
/* Национальный чемпионат режима «Лиги» (migrations/065) — зелёный медальон. */
.tournament-cup-badge.leagues{background:radial-gradient(circle, rgba(46,160,90,.32), rgba(46,160,90,.08)); border-color:#3FAE6A;}
/* Медальон рядом с заголовком h2 (админка / раздел кабинета) — в строку. */
.tournament-cup-inline{display:flex; align-items:center; gap:10px;}
.tournament-cup-inline .tournament-cup-badge{margin-bottom:0; width:36px; height:36px;}
.tournament-cup-inline .tournament-cup-badge img{width:22px; height:22px;}

/* Вкладка «Последние результаты» на странице клуба (ClubResultsPane.vue,
   журнал п.210): строка матча — дата/турнир сверху, клубы и счёт-ссылка,
   справа кружок итога В/Н/П. Свой клуб в строке выделен жирным. */
/* Результаты клуба (ClubResultsPane.vue, DESIGN.md): полоса исхода слева,
   счёт плашкой по центру, свой клуб жирным. */
.club-results{display:flex; flex-direction:column; gap:var(--space-1-5);}
.club-result-row{
  position:relative; border:1px solid var(--color-border); border-radius:var(--radius-md);
  padding:var(--space-2) var(--space-3) var(--space-2) var(--space-4); background:var(--color-surface);
}
.club-result-row::before{content:''; position:absolute; left:0; top:0; bottom:0; width:4px; border-radius:var(--radius-md) 0 0 var(--radius-md);}
.club-result-row.res-W::before{background:var(--green-600);}
.club-result-row.res-D::before{background:var(--gray-500);}
.club-result-row.res-L::before{background:var(--red-600);}
.club-result-meta{display:flex; gap:10px; align-items:baseline; flex-wrap:wrap; font-size:var(--text-xs); margin-bottom:4px;}
.club-result-date{font-weight:700; color:var(--color-text-muted);}
.club-result-match{display:grid; grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr) auto; align-items:center; gap:var(--space-3);}
.res-team{display:flex; align-items:center; gap:var(--space-2); min-width:0; font-size:var(--text-sm);}
.res-team.away{justify-content:flex-end; text-align:right;}
.res-team a{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.res-team > div{flex:none;}
.club-result-score{
  display:flex; flex-direction:column; align-items:center; min-width:64px; padding:3px var(--space-3);
  border-radius:var(--radius-sm); background:var(--color-surface-2); color:var(--color-text); white-space:nowrap;
}
.club-result-score:hover{text-decoration:none; background:var(--color-surface-2-hover);}
.club-result-score b{font-family:var(--font-display); font-size:1.25rem; letter-spacing:.04em; line-height:1.1;}
.club-result-score small{font-size:var(--text-2xs); color:var(--color-text-dim);}
.club-result-self{font-weight:800;}
.tb-neg-text{color:var(--red-400);}
.tb-stat b i{font-style:normal;}
.res-form{flex-direction:column;}
.res-form-dots{display:flex; gap:3px; padding:2px 0;}
.res-form-dots .ov-form-dot{width:22px; height:22px; font-size:9px; font-style:normal;}
@media(max-width:640px){
  .club-result-match{gap:var(--space-2);}
  .res-team{font-size:var(--text-xs);}
  .res-team > div{display:none;}
  .club-result-score{min-width:52px; padding:2px var(--space-2);}
  .club-result-badge{margin-left:0 !important;}
}

/* Матчи игрока (PlayerMatchesCard.vue) — те же строки, что у результатов
   клуба: соперник · значки действий · счёт своей команды первым · оценка. */
.pm-head{display:flex; justify-content:space-between; align-items:baseline; gap:var(--space-3); margin-bottom:var(--space-3);}
.pm-seasons{margin-bottom:var(--space-3);}
.pm-match{display:grid; grid-template-columns:minmax(0, 1fr) auto auto auto; align-items:center; gap:var(--space-3);}
.pm-venue{flex:none; font-size:var(--text-2xs);}
.pm-venue-short{display:none;}
.pm-actions{display:flex; flex-wrap:wrap; gap:2px; justify-content:flex-end; font-size:.95rem; line-height:1;}
.pm-rating.rating-badge{min-width:40px; height:26px; font-size:.95rem; font-style:normal;}
.pm-rating.hint{min-width:40px; text-align:center;}
@media(max-width:640px){
  .pm-match{gap:var(--space-2);}
  .pm-venue-full{display:none;}
  .pm-venue-short{display:inline;}
  .pm-actions{font-size:.8rem; max-width:64px;}
  .pm-rating.rating-badge{min-width:34px; height:24px; font-size:.85rem;}
}

/* Предстоящие матчи (UpcomingMatches.vue) — карточки, ближайший крупнее. */
.mc{display:flex; flex-direction:column; gap:var(--space-3);}
.mc-note{margin:0;}
.mc-list{display:flex; flex-direction:column; gap:var(--space-2);}
.mc-card{
  display:flex; flex-direction:column; gap:var(--space-2); padding:var(--space-3) var(--space-4);
  border-radius:var(--radius-md); background:var(--color-surface); border:1px solid var(--color-border);
}
.mc-card.next{background:radial-gradient(ellipse at 50% 0, rgba(212,167,60,.13), transparent 70%), var(--color-surface); border-color:rgba(212,167,60,.4); padding:var(--space-4); box-shadow:0 0 22px rgba(212,167,60,.16);}
.mc-card.live{border-color:rgba(226,106,106,.5);}
.mc-top{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2);}
.mc-round{font-family:var(--font-display); font-size:var(--text-md); letter-spacing:.04em; text-transform:uppercase;}
.mc-when{margin-left:auto; font-size:var(--text-xs); color:var(--color-text-muted);}
.mc-teams{display:grid; grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr); align-items:center; gap:var(--space-4); width:100%; max-width:640px; margin:0 auto;}
.mc-team{display:flex; align-items:center; gap:var(--space-2); min-width:0; color:var(--color-text); font-weight:600;}
.mc-team.away{justify-content:flex-end; text-align:right;}
.mc-team span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.mc-team.me{color:var(--color-primary);}
.mc-team:hover{text-decoration:none; color:var(--color-primary);}
.mc-card.next .mc-team{font-size:var(--text-lg);}
.mc-vs{font-family:var(--font-display); color:var(--color-primary); font-size:1.1rem;}
.mc-actions{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2) var(--space-3);}
.mc-status{font-size:var(--text-xs); font-weight:700; padding:2px 8px; border-radius:var(--radius-full);}
.mc-status.ok{background:var(--color-success-subtle); color:var(--green-400);}
.mc-status.warn{background:var(--color-primary-subtle); color:var(--gold-400);}
.mc-link{margin-left:auto; font-size:var(--text-xs);}
@media(max-width:640px){
  .mc-when{margin-left:0; flex-basis:100%;}
  .mc-card.next .mc-team{font-size:var(--text-sm);}
  .mc-link{margin-left:0;}
}
.club-result-badge{flex:none; width:28px; height:28px; clip-path:polygon(50% 0, 100% 50%, 50% 100%, 0 50%); display:inline-flex; align-items:center; justify-content:center; font-size:var(--text-xs); font-weight:800; color:#fff; margin-left:8px;}
.club-result-badge.result-win{background:var(--color-success);}
.club-result-badge.result-draw{background:var(--gray-400);}
.club-result-badge.result-loss{background:var(--color-danger);}
.club-results-pager{display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-top:var(--space-3);}

/* Вкладка «Статистика» матча (MatchStatsPanel.vue, журнал п.221): строка —
   значение хозяев / название / значение гостей, под ней полоска
   соотношения (хозяева слева, гости справа); у точности пасов — две
   независимые шкалы по 100%, растущие от центра. */
.match-stats{max-width:560px; margin:var(--space-3) auto 0;}
.match-stats-head{display:flex; justify-content:space-between; gap:var(--space-2); font-weight:700; font-size:var(--text-sm); margin-bottom:var(--space-3);}
.match-stats-team{display:inline-flex; align-items:center; gap:6px; min-width:0;}
.match-stats-team-away{justify-content:flex-end;}
.match-stats-row{margin-bottom:var(--space-2-5);}
.match-stats-values{display:flex; justify-content:space-between; align-items:baseline; font-variant-numeric:tabular-nums; font-size:var(--text-sm);}
.match-stats-label{color:var(--color-text-muted); font-size:var(--text-xs);}
.match-stats-lead{font-weight:800; color:var(--color-text);}
.match-stats-bars{display:flex; height:6px; margin-top:3px; border-radius:var(--radius-full); overflow:hidden; background:var(--color-border); gap:2px;}
.match-stats-bar-home-part{background:var(--color-success); border-radius:var(--radius-full) 0 0 var(--radius-full);}
.match-stats-bar-away-part{background:#4c7be0; border-radius:0 var(--radius-full) var(--radius-full) 0; margin-left:auto;}
.match-stats-bars-split{background:none; gap:6px;}
.match-stats-bar{flex:1; height:6px; background:var(--color-border); border-radius:var(--radius-full); overflow:hidden; display:flex;}
.match-stats-bar > span{display:block; height:100%; background:#4c7be0;}
.match-stats-bar-home{justify-content:flex-end;}
.match-stats-bar-home > span{background:var(--color-success);}

/* Тренировки — раскрытые навыки игрока (TrainingsSection.vue, журнал
   п.214): компактная сетка по группам, у каждого навыка — уровень,
   прибавка от тренировок, полоска прогресса к следующему +1 и очки.
   Тренируемый сейчас навык подсвечен. */
.training-player-cell{cursor:pointer;}
.training-player-cell .row-header-inner{display:flex; align-items:center; gap:var(--space-2);}
.training-chevron{margin-left:auto;}
.training-total-gain{font-size:var(--text-2xs); font-weight:800; color:var(--color-success); background:rgba(59,165,92,.12); border-radius:var(--radius-full); padding:1px 6px;}
.training-skills-row > td{background:rgba(255,255,255,.02); padding:var(--space-2) var(--space-3) var(--space-3);}
.training-skills-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:var(--space-2) var(--space-4);}
.training-skill-group-title{font-size:var(--text-2xs); font-weight:700; text-transform:uppercase; letter-spacing:.05em; margin-bottom:2px;}
.training-skill{display:grid; grid-template-columns:1fr auto 54px 44px; align-items:center; gap:6px; font-size:var(--text-xs); padding:1px 4px; border-radius:var(--radius-sm);}
.training-skill.is-trained{background:rgba(212,167,60,.14); outline:1px solid rgba(212,167,60,.45);}
.training-skill-name{color:var(--color-text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.training-skill-value{font-weight:700; font-variant-numeric:tabular-nums; text-align:right;}
.training-skill-gain{color:var(--color-success); font-size:var(--text-2xs); margin-left:2px;}
.training-skill-bar{height:5px; border-radius:var(--radius-full); background:var(--color-border); overflow:hidden;}
.training-skill-bar > span{display:block; height:100%; background:var(--color-success);}
/* Ключевые навыки (журнал п.217): ★ — ключевой для позиции (имя ярче и
   жирнее), бейдж роли — требование основной роли с порогом. */
.training-skills-legend{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-4); font-size:var(--text-2xs); margin-bottom:var(--space-2);}
.training-skill.is-key .training-skill-name{color:var(--color-text); font-weight:700;}
.training-key-star{color:var(--color-accent); margin-right:3px; font-size:var(--text-2xs);}
.training-role-key{color:#5bc0be; margin-right:3px; font-size:var(--text-2xs);}
.training-role-bonus{margin-left:4px; font-size:9px; font-weight:800; color:#5bc0be;}
.training-role-badge{display:inline-block; margin-left:4px; padding:0 4px; border-radius:var(--radius-xs); font-size:9px; font-weight:800; line-height:14px; vertical-align:1px;}
.training-role-badge.met{background:rgba(59,165,92,.18); color:var(--color-success);}
.training-role-badge.unmet{background:rgba(214,69,69,.16); color:var(--color-danger);}
.training-potential-note{color:var(--color-accent); font-size:var(--text-2xs); margin-top:2px;}
.training-skill-pts{font-size:var(--text-2xs); color:var(--color-text-dim); text-align:right; font-variant-numeric:tabular-nums;}
.tournament-detail-title .tournament-cup-badge{margin-bottom:0;}

/* ---- Отдельная страница новости (news-article.html) ---- */
.article-card{max-width:760px; margin:var(--space-6) auto;}
.article-img{width:100%; max-height:420px; object-fit:cover; border-radius:var(--radius-md); display:block; margin:var(--space-4) 0;}
.article-date{font-size:var(--text-xs); color:var(--color-text-dim); text-transform:uppercase; letter-spacing:.4px; margin-top:var(--space-4);}
.article-title{margin:var(--space-2) 0 var(--space-4); font-size:var(--text-3xl);}
.article-body{margin:0; color:var(--color-text-muted); font-size:var(--text-base); line-height:var(--leading-normal); white-space:pre-wrap;}
/* Ссылки внутри текста новости (newsFormat.js renderNewsBody) — заметно
   отличаются от основного текста (muted), не "сливаются": НЕ .club-link
   (та нарочно color:inherit, для другого случая — см. его комментарий). */
.news-body-link{color:var(--color-primary); text-decoration:underline; text-underline-offset:2px;}
.news-body-link:hover{color:var(--color-primary-hover, var(--color-primary));}

/* ---- Подвал сайта (AppFooter.vue, на всех страницах) ---- */
.site-footer{margin-top:var(--space-10); padding:var(--space-6) var(--space-4); border-top:1px solid var(--color-border); text-align:center;}
.site-footer-links{display:flex; justify-content:center; flex-wrap:wrap; gap:var(--space-2) var(--space-5); margin-bottom:var(--space-3);}
.site-footer-links a{color:var(--color-text-muted); font-size:var(--text-sm); transition:color var(--duration-fast) var(--ease);}
.site-footer-links a:hover{color:var(--color-accent);}
.site-footer-copy{margin:0; color:var(--color-text-dim); font-size:var(--text-xs);}
.site-footer-links a.site-footer-support{color:var(--color-accent);}
.site-footer-links a.site-footer-tg{display:inline-flex; align-items:center; gap:4px;}
.site-footer-links a.site-footer-tg svg{width:16px; height:16px; flex:none;}
/* Окно «Поддержать проект» (SupportModal.vue): QR по центру на белой подложке. */
.support-modal{max-width:380px; height:fit-content; text-align:center;}
.support-qr{display:block; width:280px; max-width:100%; height:auto; aspect-ratio:766/682; margin:var(--space-3) auto; background:#fff; border-radius:var(--radius-md);}

/* ---- Документы подвала (legal.html/LegalApp.vue: правила/политики) ---- */
.legal-doc{margin-top:var(--space-6);}
.legal-doc-title{margin:0 0 var(--space-1); font-size:var(--text-3xl);}
.legal-doc-section{margin-top:var(--space-6);}
.legal-doc-section h2{font-size:var(--text-xl); margin:0 0 var(--space-3);}
.legal-doc-section p{margin:0 0 var(--space-3); color:var(--color-text-muted); font-size:var(--text-base); line-height:var(--leading-normal);}
.legal-doc-section p:last-child{margin-bottom:0;}

/* ---- Иконки-кнопки (редактировать/удалить в таблицах админки) ---- */
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:var(--radius-md);
  border:1px solid var(--button-border); background:transparent; color:var(--color-text-muted);
  cursor:pointer; transition:background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.icon-btn:hover{background:var(--color-surface-2); color:var(--color-text);}
.icon-btn + .icon-btn{margin-left:var(--space-1-5);}
.icon-btn-danger:hover{background:var(--color-danger-subtle); color:var(--red-300); border-color:var(--button-danger-bg);}

.badge-featured{background:rgba(212,167,60,.2); color:var(--color-accent);}
/* Режим сборной в каталоге админки (AdminNationsSection.vue, migrations/095)
   — те же цвета, что у переключателя режима в шапке (.mode-legends/.mode-leagues). */
.badge-mode-legends{background:rgba(212,167,60,.2); color:var(--gold-400);}
.badge-mode-leagues{background:rgba(106,168,255,.14); color:#6aa8ff;}
.news-admin-thumb{width:56px; height:36px; object-fit:cover; border-radius:var(--radius-sm); display:block;}
.checkbox-row{display:flex; align-items:center; gap:var(--space-2); font-weight:600; color:var(--color-text-muted); font-size:var(--text-sm); cursor:pointer;}
.checkbox-row input{width:auto; accent-color:var(--color-accent);}

.hint{color:var(--color-text-dim); font-size:var(--text-xs); line-height:var(--leading-normal);}
.center{text-align:center;}
.mt{margin-top:var(--space-5);}
.flex-between{display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-2-5);}

/* Заголовок-переключатель сворачиваемого блока (NationCard.vue "Свободные
   сборные") — .flex-between внутри &lt;button&gt;, поэтому сбрасываем нативные
   стили кнопки, чтобы выглядело как обычный заголовок карточки. */
.collapse-toggle{width:100%; background:none; border:none; padding:0; cursor:pointer; font:inherit; color:inherit; text-align:left;}
.collapse-chevron{width:16px; height:16px; display:inline-block; vertical-align:middle; margin-left:var(--space-1); transition:transform var(--duration-base) var(--ease);}
.collapse-chevron.open{transform:rotate(180deg);}

/* Глобальный прелоадер (public/js/api.js ensureLoaderEl/loaderRequestStart) —
   появляется, если запрос висит дольше 100мс. Полноэкранный backdrop с лёгким
   затемнением и blur, спиннер увеличен и центрирован по viewport. pointer-events:none
   сохраняет прежнее поведение: оверлей визуальный и не блокирует клики. Сам спиннер
   (::before у -ring) крутится всегда, пока внешняя обёртка прозрачна — невидим. */
/* ---- Спотлайт-тур нового менеджера (TourBubble.vue) — подсветка целевого
   элемента (cutout через box-shadow: один элемент точно поверх target,
   тень 9999px затемняет весь остальной экран) + пузырь с текстом рядом.
   z-index выше .global-loader (500) — тур должен перекрывать вообще всё,
   включая прелоадер, пока пользователь не нажмёт "Далее"/"Пропустить". ---- */
.tour-spotlight{
  position:fixed; z-index:650; pointer-events:none; border-radius:var(--radius-md);
  box-shadow:0 0 0 9999px rgba(6,10,20,0.72); transition:top .2s ease, left .2s ease, width .2s ease, height .2s ease;
}
.tour-bubble{
  position:fixed; z-index:651; width:280px; max-width:calc(100vw - 16px);
  background:rgba(13,19,34,0.98); border:1px solid var(--color-primary); border-radius:var(--radius-md);
  padding:var(--space-3) var(--space-3-5); box-shadow:var(--shadow-lg);
}
.tour-bubble-title{font-weight:800; font-size:var(--text-sm); margin-bottom:var(--space-1-5);}
.tour-bubble-text{font-size:var(--text-xs); color:var(--color-text-muted); line-height:var(--leading-normal); margin:0 0 var(--space-3);}
.tour-bubble-actions{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2);}
.tour-bubble-skip{background:none; border:none; padding:0; color:var(--color-text-dim); font-size:var(--text-2xs); cursor:pointer; text-decoration:underline;}
.tour-bubble-skip:hover{color:var(--color-text-muted);}

.global-loader{
  position:fixed; inset:0; z-index:500;
  display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none;
  background:rgba(8,12,22,.22);
  -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px);
  transition:opacity .25s ease;
}
.global-loader.visible{opacity:1;}
.global-loader-ring{
  width:72px; height:72px; border-radius:50%;
  background:var(--color-surface); border:1px solid var(--color-border);
  box-shadow:0 8px 28px rgba(0,0,0,.42);
  display:flex; align-items:center; justify-content:center;
}
.global-loader-ring::before{
  content:''; width:40px; height:40px; border-radius:50%;
  border:4px solid var(--color-border-strong); border-top-color:var(--color-primary);
  animation:globalLoaderSpin .8s linear infinite;
}
@media(max-width:480px){
  .global-loader-ring{width:64px;height:64px;}
  .global-loader-ring::before{width:36px;height:36px;}
}
@keyframes globalLoaderSpin{to{transform:rotate(360deg);}}
