/* =========================================================================
   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);
}

/* ---- 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);}

: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:2px;
}
.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-divider{height:1px; background:var(--color-border); margin:var(--space-1) 2px;}
.nav-menu-user{font-size:var(--text-xs); color:var(--color-text-muted); padding:var(--space-1) var(--space-2-5);}

/* Горизонтальное меню разделов личного кабинета (AppHeader.vue) — только
   десктоп, скрывается на том же пороге, что .nav уже переходит на мобильную
   раскладку ниже (max-width:640px). Дублирует часть выпадающего меню
   намеренно — быстрый переход в конкретный раздел кабинета, а не замена
   общей навигации по сайту. */
.nav-desktop-links{display:flex; gap:var(--space-5); align-items:center;}
.nav-desktop-links a{color:var(--color-text-muted); text-decoration:none; font-size:var(--text-sm); font-weight:600; white-space:nowrap;}
.nav-desktop-links a:hover{color:var(--color-text); text-decoration:none;}
/* 640px скрывало nav-desktop-links только в портретной мобилке — но весь
   .nav (лого+поиск+ссылки+значок клуба/флаг сборной+меню) в реальности
   требует ~846px (замерено Playwright), поэтому в landscape-телефоне
   (667-844px — шире 640, но уже 846) значок сборной/кнопка меню уезжали
   ЗА край экрана и становились недостижимы (не просто некрасиво — меню
   входа/выхода физически недоступно). 900px с запасом покрывает все
   обычные landscape-телефоны; планшеты/мелкие ноуты в этом диапазоне
   просто тоже получают гамбургер-меню вместо обрезанной шапки. */
@media(max-width:900px){ .nav-desktop-links{display:none;} }

/* Правый кластер шапки (AppHeader.vue) — секции кабинета + эмблема
   управляемого клуба + меню, единый flex-контейнер вместо трёх прямых
   детей .nav, чтобы justify-content:space-between не растягивало их
   поодиночке, когда nav-desktop-links скрыт (гость/мобилка). */
.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;}
@media(max-width:640px){ .nav-search{width:120px;} .nav-search-input:focus{width:160px;} }
.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);}

.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%;}

/* =========================================================================
   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 записей). */
.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;}

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-cell{gap:4px !important;}
  .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);}
.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:10px; height:10px; border-radius:50%; display:inline-block;}
.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);}

/* ---- Админка: боковое меню ---- */
.admin-layout{display:flex; gap:var(--space-6); align-items:flex-start; margin-top:20px;}
.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;
}
.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);}
.admin-content{flex:1; min-width:0;}
.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;}
  .admin-sidebar{flex:1 1 auto; width:100%; position:static; 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-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 (эмблема клуба /
   фото игрока) — без подписи, круглая, в углу картинки. ---- */
.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;}
.player-head-photo{position:relative; flex-shrink:0;}
.player-head-photo img{width:72px; height:72px; object-fit:cover; border-radius:var(--radius-md); display:block; box-shadow:0 2px 8px rgba(0,0,0,.35);}
.player-head-photo-placeholder{
  width:72px; height:72px; border-radius:var(--radius-md); display:flex; align-items:center; justify-content:center;
  background:var(--color-surface-2); border:1px solid var(--color-border); color:var(--color-text-dim);
}
.player-head-photo-placeholder svg{width:30px; height:30px;}
.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-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-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;}

/* ---- Карьера игрока: история клубов / прогрессия / сборная (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;}
.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);}
.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);}
.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;}
.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;}
.num{font-family:'JetBrains Mono',monospace; text-align:center;}

.tactics-controls{display:flex; gap:var(--space-2-5); margin-bottom:var(--space-4); flex-wrap:wrap; align-items:center;}
.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);
}
.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%;}
.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 выше (синий=
   спокойно, серый=нейтрально, оранжево-красный=нагрузка), но как фон
   кнопки с текстом, не точка. */
.training-picker{display:flex; gap:4px; flex-wrap:wrap;}
.training-level-btn{
  padding:var(--space-1) var(--space-2); border-radius:var(--radius-sm); border:1px solid var(--color-border);
  background:var(--color-surface-2); 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{background:var(--color-surface-2-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);}
.fixture-clubs{display:flex; 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); flex:1; font-size:var(--text-sm); font-weight:600;}
.fixture-club-away{flex-direction:row-reverse; text-align:right;}
.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. ---- */
.viz-legend{display:flex; gap:var(--space-4); flex-wrap:wrap; font-size:var(--text-xs); color:var(--color-text-muted); margin:var(--space-3) 0;}
.viz-legend span{display:flex; align-items:center; gap:var(--space-1-5);}
.viz-dot{width:9px; height:9px; border-radius:var(--radius-full); display:inline-block;}
.viz-pitch-wrap{width:100%; max-width:420px; margin:var(--space-3) auto 0;}

/* ---- Составы слева/справа от поля на вкладке "Полный матч"
   (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-оверлей. */
.viz-press-indicator{ position:absolute; pointer-events:none; z-index:4; }
.viz-press-indicator-circle{ width:13%; aspect-ratio:1; transform:translate(-50%,-50%); }

/* Горизонтальная раскладка для десктопа (по прямому запросу, ВТОРОЙ
   заход — первый через 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;}

/* ---- Новости (лендинг + /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);}
.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;}
/* Лига наций (турнир сборных, журнал п.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);}
/* Медальон рядом с заголовком 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): строка матча — дата/турнир сверху, клубы и счёт-ссылка,
   справа кружок итога В/Н/П. Свой клуб в строке выделен жирным. */
.club-results{display:flex; flex-direction:column; gap:var(--space-2);}
.club-result-row{border:1px solid var(--color-border); border-radius:var(--radius-md); padding:8px 12px;}
.club-result-meta{display:flex; gap:10px; align-items:baseline; flex-wrap:wrap; font-size:var(--text-sm); margin-bottom:4px;}
.club-result-date{font-weight:700; color:var(--color-text-muted);}
.club-result-match{align-items:center;}
.club-result-score{flex-shrink:0; white-space:nowrap;}
.club-result-self{font-weight:800;}
.club-result-badge{flex:none; width:24px; height:24px; border-radius: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;}

/* ---- Подвал сайта (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);}

/* ---- Документы подвала (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);}
.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мс. Фиксированный угол — ненавязчиво, поверх любого содержимого
   (z-index выше модалки .modal-backdrop:400), pointer-events:none — никогда
   не мешает кликам под собой. Внешний .global-loader только управляет
   fade/scale через .visible — сам спиннер (::before у -ring) крутится
   всегда, просто не виден, пока обёртка invisible/scale(.7). */
/* ---- Спотлайт-тур нового менеджера (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; right:20px; bottom:20px; z-index:500;
  width:38px; height:38px; opacity:0; transform:scale(.7); pointer-events:none;
  transition:opacity .25s ease, transform .25s ease;
}
.global-loader.visible{opacity:1; transform:scale(1);}
.global-loader-ring{
  width:100%; height:100%; border-radius:50%;
  background:var(--color-surface); border:1px solid var(--color-border);
  box-shadow:0 4px 16px rgba(0,0,0,.35);
  display:flex; align-items:center; justify-content:center;
}
.global-loader-ring::before{
  content:''; width:20px; height:20px; border-radius:50%;
  border:3px solid var(--color-border-strong); border-top-color:var(--color-primary);
  animation:globalLoaderSpin .8s linear infinite;
}
@keyframes globalLoaderSpin{to{transform:rotate(360deg);}}
