:root {
  /* VS Code Dark+-inspired palette: near-black editor/panel surfaces, a
     muted low-contrast border (not a stark black line), light gray body
     text, and a bright accent reserved for text/links vs. a deeper shade
     for solid fills (buttons, active tabs) -- the two need to differ
     because a light accent used as a solid fill would lose contrast
     against the white text sitting on top of it. */
  --bg: #1e1e1e;
  --panel: #252526;
  --border: #3c3c3c;
  --text: #d4d4d4;
  --muted: #9d9d9d;
  --accent-purple: #7c3aed;
  --accent-purple-dark: #c4b5fd;
  --accent-purple-deep: #5b21b6;
  --accent-purple-tint: #2a2140;
  --accent-green: #4ec9b0;
  --accent-green-tint: #123832;
  --font-mono: "Cascadia Code", Consolas, "SF Mono", Menlo, monospace;
  /* Bold bitmap/pixel display face for headlines and big stat numbers only
     (never body text/tables -- illegible at small sizes, and the whole
     site is mostly Cyrillic -- Press Start 2P was picked specifically
     because it has real Cyrillic glyphs; most "pixel" Google Fonts
     (Silkscreen included) are Latin-only and would silently fall back to
     --font-mono on every Russian headline). Loaded in index.html's <head>. */
  --font-display: "Press Start 2P", var(--font-mono);
  /* Logo-only -- "Purple Eye" is always Latin regardless of site language,
     so Silkscreen's missing Cyrillic doesn't apply here, and it's the
     exact face the approved wordmark look used. */
  --font-logo: "Silkscreen", var(--font-display);
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: dark;
}

/* A thin, muted scrollbar reads as "editor chrome" instead of the default
   OS scrollbar -- Firefox uses the two-value shorthand, WebKit/Chromium
   needs the pseudo-elements since it ignores that shorthand. */
* {
  scrollbar-width: thin;
  scrollbar-color: #5a5a5a var(--bg);
}

*::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

*::-webkit-scrollbar-track {
  background: var(--bg);
}

*::-webkit-scrollbar-thumb {
  background: #5a5a5a;
  border-radius: 6px;
  border: 3px solid var(--bg);
}

*::-webkit-scrollbar-thumb:hover {
  background: #6e6e6e;
}

* {
  box-sizing: border-box;
  /* Belt-and-braces against horizontal scroll: a long unbroken token (a real
     player/team name, an account_id, a URL in an error message) can force a
     box wider than its grid track even when the track itself can shrink. */
  overflow-wrap: anywhere;
}

html {
  overflow-x: hidden;
  /* Fallback so any residual sub-pixel gap below body's box shows this
     instead of the browser's stark default white -- body's own
     min-height below is what actually keeps the gradient reaching the
     bottom of the screen (relying on the browser's html/body background
     -propagation spec behavior to do that instead turned out unreliable
     combined with the non-standard "zoom" property below -- the canvas
     paint didn't extend the way the spec describes, leaving the exact
     gap this was meant to prevent whenever body was shorter than the
     viewport). */
  background: var(--bg);
}

body {
  overflow-x: hidden;
  margin: 0;
  padding: 16px 16px 24px;
  /* The user found the page noticeably more comfortable at the browser's own
     110% zoom step (bigger text, more breathing room) than at 100% -- rather
     than re-guess every font-size/padding by hand, scale the whole page by
     the same factor so 100% already looks like that. The history list's
     JS-measured sizing (sizeHistoryList in app.js) reads real on-screen
     pixel positions, so it keeps fitting the viewport correctly at this
     scale with no separate adjustment needed. */
  zoom: 1.1;
  /* Guarantees the gradient below always reaches the bottom of the
     screen, at any content length/viewport size -- a 100vh box zoomed by
     1.1 would render 10% taller than the viewport (a guaranteed
     scrollbar regardless of content, which is exactly the bug this
     caused when it was tried unscoped before), so divide the zoom back
     out here to land on exactly 100vh rendered.
     100vh itself is the largest possible mobile-browser viewport (address
     bar hidden) -- on a short page (e.g. "Что мне пикнуть" before results)
     this made the page taller than what's actually visible with the address
     bar showing, which reads as "scrolls into emptiness" at the bottom.
     100dvh tracks the real, currently-visible viewport instead; declared
     second so it only overrides vh in browsers that support it. */
  min-height: calc(100vh / 1.1);
  min-height: calc(100dvh / 1.1);
  /* Flat, not a soft glow -- the reference look (both images) is a single
     stark background with hard-edged type sitting directly on it, no
     ambient light/blur anywhere. The old radial-gradient purple glow was
     the single biggest reason the redesign still read as "generic AI SaaS
     site" despite the font swap. */
  background: var(--bg);
  color: var(--text);
  min-width: 0;
}

header {
  max-width: 1180px;
  width: 100%;
  margin: 0 auto 12px;
  padding-right: 56px;
}

/* Pixel glyphs are much wider per character than the old gradient
   sans-serif was at the same nominal size -- font-size dropped hard to
   compensate (a direct rem-for-rem swap at 2.5rem would overflow the
   mobile header next to the game switcher). Check the real header width
   against the game switcher once live and nudge if it still crowds. */
h1 {
  margin: 0;
  font-family: var(--font-logo);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.5;
  text-transform: uppercase;
  color: #f3edfd;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
}

/* The pixel eye-mandala mark (favicon.svg), reused inline next to the
   wordmark -- shared by the mobile h1 and desktop .topNavTitle. */
.siteTitleIcon {
  flex: none;
  display: block;
  /* The icon is real pixel-grid art (24x24 individual rects) -- without
     this the browser smooths/blurs it when scaling down to ~20px, which
     reads as a fuzzy grey blob instead of a crisp mark. */
  image-rendering: pixelated;
}

/* Safety-net base rule: every h2/h3/h4 on the site gets the pixel display
   face and uppercase treatment by default, even ones with no dedicated
   class rule of their own (several existed -- "Premium", "Результат",
   the how-it-works sub-headings -- that a full audit found completely
   unstyled). A more specific class rule (.team h2, .guideCard h3, etc.)
   still wins where one exists and needs its own size/weight; this is
   just the floor every heading lands on when nothing else applies. */
h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Same safety-net idea as h2/h3/h4 above, for every interactive text
   control -- confirmed explicitly: uppercase everywhere on the site, no
   mix of plain-case subsections/draft-form controls next to an uppercase
   nav. A class rule with its own text-transform (none currently) would
   still win by specificity; this is just the floor. */
button, input, select, textarea, option {
  text-transform: uppercase;
}

/* Same "flat highlight block behind a word" move as the free-font-pack
   reference the redesign is based on -- a solid fill, not a soft accent.
   Shared by the mobile h1 logo and the desktop .topNavTitle button below
   (both wrap "Eye" in this span), not scoped to either. */
.siteTitleHighlight {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  background: var(--accent-purple);
  color: #1e1e1e;
  padding: 2px 8px;
}

@media (max-width: 480px) {
  /* #mobileHeader h1 (id selector, higher specificity) is what actually
     renders inside #mobileHeader on every phone width -- a bare `h1` rule
     here would never win against it, so the real narrow-phone override
     lives there too, not as a second bare `h1` rule. */
  #mobileHeader h1 { font-size: 0.95rem; }
}

/* Desktop top nav: replaces the mobile hamburger+drawer with an always-
   visible header bar (title left, section links centered, profile/auth
   right) above a min-width breakpoint -- the drawer/hamburger stay exactly
   as they were below it, per "мобильная версия остаётся как есть". The
   actual rules are appended at the very end of this file, not here --
   #mobileHeader/.menuBtn have unconditional base rules defined later in
   the file, and same-specificity rules resolve by source order regardless
   of which is wrapped in a media query (a bug this file's already hit
   twice this session), so an override here would just lose. */
.topNav {
  display: none;
}

main {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}

.homeSection {
  max-width: 1040px;
  margin: 28px auto 0;
}

.homeIntro h2 { margin: 0 0 10px; font-size: clamp(1rem, 2.4vw, 1.6rem); line-height: 1.6; }
.homeIntro p { color: var(--muted); margin: 0 0 22px; line-height: 1.5; }
.heroGuideForm {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 220px) auto;
  gap: 12px;
  align-items: end;
  margin-bottom: 20px;
}
.heroGuideForm label { display: grid; gap: 6px; font-weight: 600; }
.heroGuideForm select {
  width: 100%;
  min-height: 39px;
  padding: 7px 10px;
  color: var(--text);
  background: var(--panel);
  border: 2px solid var(--border);
  border-radius: 0;
}
.heroGuideForm button { min-height: 39px; }
.guideLead { padding: 16px; margin-bottom: 12px; background: var(--panel); border: 2px solid var(--border); border-radius: 0; }
.guideLead h3, .guideCard h3 { margin: 0 0 8px; }
.guideLead p { margin: 4px 0; }
.guideGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.guideCard { padding: 16px; background: var(--panel); border: 2px solid var(--border); border-radius: 0; line-height: 1.5; }
.guideCard--wide { grid-column: 1 / -1; }
.guideCard ul { margin: 8px 0; padding-left: 22px; }
.guideCard li { margin: 4px 0; }
.guideCard h4 { margin: 10px 0 2px; }
.guidePhase p { margin: 0; }
.guideCard dt { font-weight: 700; margin-top: 10px; }
.guideCard dd { margin: 3px 0 0; }
.guideCard .historyHint { margin-top: 12px; }
.tournamentFilterRow { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; }
.tournamentFilterRow select { max-width: 360px; min-width: 180px; padding: 6px; color: var(--text); background: var(--panel); border: 2px solid var(--border); border-radius: 0; }

@media (max-width: 700px) {
  .homeSection { margin-top: 12px; }
  .heroGuideForm, .guideGrid { grid-template-columns: 1fr; }
  .guideCard--wide { grid-column: auto; }
}

/* Game selector uses the same URLs on desktop and mobile. */
.gameSwitcher { position: relative; align-self: center; margin-left: 10px; }
.gameSwitchBtn { white-space: nowrap; padding: 5px 9px; font-size: 0.72rem; }
.gameSwitchMenu {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  min-width: 185px;
  padding: 5px;
  background: var(--panel);
  border: 2px solid var(--border);
  border-radius: 0;
}
.gameSwitchMenu a { display: block; padding: 9px 11px; border-radius: 0; color: var(--text); text-decoration: none; font-size: .84rem; }
.gameSwitchMenu a:hover, .gameSwitchMenu a[aria-current="page"] { background: var(--accent-purple-tint); color: var(--accent-purple-dark); }
.homeSection .howItWorksSection h2 { display: block; }
#mistakePrepPanel .homeIntro { margin-top: 10px; }
@media (max-width: 700px) {
  #mobileHeader { display: flex; align-items: center; gap: 8px; }
  /* Was a flat 1.65rem override here, from before the h1 rule itself used
     a pixel display face -- that would have silently undone the sizing
     fix in the bare h1 rule above (more specific selector, later in the
     cascade). Scoped the same way, just no longer a hardcoded value. */
  #mobileHeader h1 { font-size: 1.15rem; }
  #mobileHeader .gameSwitcher { margin-left: 0; }
  #mobileHeader .gameSwitchMenu { left: auto; right: 0; }
}

.teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 24px;
  min-width: 0;
}

/* Mobile team switcher -- hidden on wider screens where both sides already
   sit next to each other; below the breakpoint it replaces stacking (which
   forced scrolling through both teams) with a tab toggle showing one side
   at a time, driven by the container's data-mobile-team attribute. */
.teamSwitcher {
  display: none;
}

@media (max-width: 700px) {
  .teams,
  .draftTeams {
    grid-template-columns: 1fr;
  }

  .teamSwitcher {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
  }

  .teamSwitcherBtn {
    flex: 1;
    min-width: 0;
    padding: 8px 10px;
    font-size: 0.85rem;
    /* the tab shows the typed team name, which can be long */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .teamSwitcherBtn--active {
    background: var(--accent-purple);
    color: #1e1e1e;
    border-color: var(--accent-purple);
  }

  .teams[data-mobile-team="A"] > [data-team="B"],
  .draftTeams[data-mobile-team="A"] > [data-team="B"] {
    display: none;
  }

  .teams[data-mobile-team="B"] > [data-team="A"],
  .draftTeams[data-mobile-team="B"] > [data-team="A"] {
    display: none;
  }

  /* The switcher tab already says which side is showing -- repeating it as
     a heading inside the panel (Команда 1 / Мои герои) is redundant there. */
  .team h2,
  .draftTeam h3 {
    display: none;
  }
}

.team {
  min-width: 0;
  container-type: inline-size;
  container-name: teampanel;
  background: var(--panel);
  border: 2px solid var(--accent-purple);
  border-radius: 0;
  padding: 22px;
}

/* .teamTitle can become an editable field holding a user-typed team name
   (arbitrary length, e.g. a full roster string) -- same reasoning as
   .probLabels below: no pixel face on content that isn't a fixed short
   string, just a bolder readable treatment. */
.team h2 {
  margin: 0 0 10px;
  font-size: 0.78rem;
  line-height: 1.6;
}

.slot {
  display: grid;
  /* Position gives up width down to the digit before the two fields shrink.
     Below, a narrow team drops those minimums so the fields stay inside it. */
  grid-template-columns: minmax(52px, 150px) minmax(188px, 1.4fr) minmax(88px, 1fr);
  gap: 10px;
  margin-bottom: 8px;
  min-width: 0;
  align-items: start;
}
.slot > * { min-width: 0; }
#analyzeForm { container-type: inline-size; container-name: draftform; }
@container draftform (max-width: 940px) {
  #analyzeForm .teams { grid-template-columns: minmax(0, 1fr); }
  #analyzeForm .teamSwitcher { display: flex; gap: 8px; margin-bottom: 12px; }
  #analyzeForm .teams[data-mobile-team="A"] > [data-team="B"],
  #analyzeForm .teams[data-mobile-team="B"] > [data-team="A"] { display: none; }
  #analyzeForm .team h2 { display: none; }
}
@container teampanel (max-width: 460px) {
  .slot { grid-template-columns: 52px minmax(0, 1.4fr) minmax(0, 1fr); }
}

@media (max-width: 480px) {
  /* Stacked single-column layout -- without a visible boundary per slot,
     "hero" for player 1 sits right above "player 2" with the same gap as
     everything else, reading as if it belonged to player 2. Box each slot
     so position+player+hero visually read as one unit. */
  .slot {
    grid-template-columns: 1fr;
    gap: 6px;
    border: 2px solid var(--border);
    border-radius: 0;
    padding: 10px;
    margin-bottom: 14px;
  }
}

.ac-wrap {
  position: relative;
  min-width: 0;
}

.slot input,
.position-select {
  background: var(--panel);
  border: 2px solid var(--border);
  color: var(--text);
  border-radius: 0;
  padding: 6px 12px;
  font-size: 0.98rem;
  width: 100%;
  min-width: 0;
  height: 40px;
}
.position-select { padding-left: 8px; padding-right: 16px; text-overflow: ellipsis; }

.slot input::placeholder { color: var(--muted); }

input:focus,
select:focus,
button:focus {
  outline: 2px solid var(--accent-purple);
  outline-offset: 1px;
}

.ac-list {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--panel);
  border: 2px solid var(--border);
  border-radius: 0;
  max-height: 220px;
  overflow-y: auto;
}

.ac-item {
  padding: 6px 10px;
  font-size: 0.85rem;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  text-transform: uppercase;
}

.ac-item:last-child { border-bottom: none; }

.ac-item:hover,
.ac-item--active {
  background: var(--accent-purple);
  color: #ffffff;
}

.ac-item:hover .ac-sub,
.ac-item--active .ac-sub {
  color: #e5d9fc;
}

.ac-sub {
  color: var(--muted);
  font-size: 0.78rem;
}

.player-preview {
  min-height: 1.1em;
  margin-top: 2px;
  font-size: 0.78rem;
  color: var(--accent-green);
  font-weight: 600;
}

button {
  background: var(--panel);
  color: var(--accent-purple-dark);
  border: 2px solid var(--accent-purple);
  border-radius: 0;
  padding: 8px 14px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}

button:hover:not(:disabled) {
  background: var(--accent-purple);
  color: #ffffff;
}

button:disabled {
  opacity: 0.5;
  cursor: default;
}

button[type="submit"] {
  background: var(--accent-purple);
  color: #ffffff;
  border-color: var(--accent-purple);
}

.premiumSubscribeBtn {
  display: inline-block;
  margin-top: 4px;
  padding: 8px 14px;
  border: 2px solid var(--accent-purple);
  border-radius: 0;
  background: var(--accent-purple);
  color: #ffffff;
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  text-align: center;
}

.premiumSubscribeBtn:hover {
  opacity: 0.9;
}

button[type="submit"]:hover:not(:disabled) {
  background: var(--accent-purple-deep);
  border-color: var(--accent-purple-deep);
}

.analyzeBtnWrap {
  display: flex;
  justify-content: center;
  margin-top: 14px;
}

/* Matches the outlined look used on the mistake-analysis/draft-assistant
   action buttons (#mistakeAnalyzeBtn/#draftSuggestBtn, both plain
   type="button" so they get the base outlined style below) instead of the
   solid always-filled look the browser default type="submit" rule gives
   this button -- an ID beats the type-attribute rule regardless of order. */
/* Solid flat block by default, not outline-until-hover -- the same "flat
   highlight chip" move as the reference's FREE badge, not a soft button.
   No box-shadow -- removed per feedback ("тени эти под кнопками, они мне
   не нравятся"), flat color change is the only feedback now. */
#analyzeBtn {
  padding: 14px 48px;
  font-size: 1.15rem;
  font-weight: 700;
  background: var(--accent-purple);
  color: #1e1e1e;
  border: 3px solid var(--accent-purple);
}

#analyzeBtn:hover:not(:disabled) {
  background: var(--accent-purple-dark);
  border-color: var(--accent-purple-dark);
}

#analyzeBtn:active:not(:disabled) {
  background: var(--accent-purple-deep);
  border-color: var(--accent-purple-deep);
  color: #ffffff;
}

.error {
  margin-top: 16px;
  background: var(--panel);
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-purple);
  color: var(--text);
  padding: 12px 14px;
  border-radius: 0;
}

/* Solid-fill accent "window" -- same move as the approved look reference's
   "(ДАННЫХ НЕТ)" callout block, for empty-state messages that deserve
   more weight than a plain paragraph. */
.emptyStateBlock {
  background: var(--accent-purple);
  padding: 24px 28px;
  margin: 12px 0;
}

.emptyStateBlock__title {
  font-family: var(--font-display);
  font-size: 1.1rem;
  line-height: 1.6;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: #1e1e1e;
}

.emptyStateBlock p {
  margin: 8px 0 0;
  color: #1e1e1e;
}

/* ---- homepage: tier-1 meta heroes + latest match ---- */
.homeMetaSection {
  margin-top: 8px;
}

.homeMetaSection h2::before {
  content: "// ";
  color: var(--accent-purple-dark);
}

.homeMetaGrid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}

.homeMetaCol {
  background: var(--panel);
  border: 2px solid var(--border);
  padding: 10px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.homeMetaColHead {
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent-purple-dark);
  margin: 0;
  padding-bottom: 6px;
  border-bottom: 2px solid var(--border);
}

.homeMetaColEmpty {
  color: var(--muted);
  font-size: 0.78rem;
  margin: 0;
  text-transform: uppercase;
}

.homeMetaHeroCard {
  position: relative;
  overflow: hidden;
  background: var(--bg);
  border: 2px solid var(--border);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  cursor: pointer;
}
.homeMetaHeroCard:hover,
.homeMetaHeroCard--top {
  border-color: var(--accent-purple);
}

/* Large, faint hero portrait as a background texture -- the duotone SVG
   filter (grayscale, then shadows->black / highlights->accent purple) is a
   CSS-only stand-in for true per-pixel halftone dithering, which would need
   server-side image processing of each portrait; this reads the same way
   at a glance without that cost. */
.homeMetaHeroPortrait {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 12%;
  opacity: 0.22;
  filter: url(#homeHeroDuotone);
  pointer-events: none;
}

.homeMetaHeroCardHead,
.homeMetaHeroStat {
  position: relative;
  z-index: 1;
}

.homeMetaHeroCardHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.homeMetaHeroCardName {
  min-width: 0;
  font-family: var(--font-logo);
  font-size: 1rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.homeMetaHeroCardBadge {
  flex: none;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--accent-purple-tint);
  color: var(--accent-purple-dark);
  padding: 3px 8px;
}
.homeMetaHeroCard--top .homeMetaHeroCardBadge {
  background: var(--accent-purple);
  color: #1e1e1e;
  font-weight: 700;
}

.homeMetaHeroStat {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
}

.homeMetaHeroStat__v {
  color: var(--text);
  font-weight: 600;
}
.homeMetaHeroStat__v--good {
  color: var(--accent-green);
}

.homeLatestMatch { margin-bottom: 20px; }

.homeLatestMatchCard {
  background: var(--panel);
  border: 2px solid var(--border);
  padding: 16px;
  cursor: pointer;
}
.homeLatestMatchCard:hover { border-color: var(--accent-purple); }

.homeLatestMatchLeague {
  font-size: 0.74rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 10px;
}

.homeLatestMatchTeams {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.homeLatestMatchTeam {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 0;
  opacity: 0.6;
}
.homeLatestMatchTeam--win { opacity: 1; }

.homeLatestMatchLogo {
  width: 48px;
  height: 48px;
  object-fit: contain;
  image-rendering: pixelated;
}

.homeLatestMatchTeamName {
  font-family: var(--font-logo);
  font-size: 0.82rem;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.homeLatestMatchTeam--win .homeLatestMatchTeamName { color: var(--accent-green); }

.homeLatestMatchVs {
  font-family: var(--font-display);
  font-size: 0.8rem;
  color: var(--muted);
}

.homeLatestMatchCta {
  text-align: center;
  margin-top: 14px;
  font-family: var(--font-display);
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent-purple-dark);
}

@media (max-width: 700px) {
  .homeMetaGrid { grid-template-columns: repeat(2, 1fr); }
}

.hidden { display: none !important; }

.result {
  margin-top: 32px;
}

.resultTopBar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.resultBackBtn {
  margin-bottom: 10px;
  background: transparent;
  border: none;
  color: var(--accent-purple-dark);
  font-weight: 600;
  padding: 4px 0;
}

.resultTopBar .resultBackBtn {
  margin-bottom: 0;
}

.resultBackBtn:hover:not(:disabled) {
  background: transparent;
  color: var(--accent-purple);
  text-decoration: underline;
}

.editLineupBtn {
  background: var(--panel);
  border: 1px solid var(--accent-purple);
  color: var(--accent-purple-dark);
  font-weight: 600;
}

.editLineupBtn:hover:not(:disabled) {
  background: var(--accent-purple);
  color: #ffffff;
}

.probBar {
  display: flex;
  height: 84px;
  border-radius: 0;
  overflow: hidden;
  border: 3px solid var(--accent-purple);
}

/* The headline stat of the whole result page -- the one number on the
   site worth treating like the giant "AaAa"/"(ERROR 404)" display type
   in the reference, not a label-sized footnote. Content is always just
   "NN%" (see app.js's fillA/fillB), so there's no wrap risk going this big. */
.probBar__fillA,
.probBar__fillB {
  background: var(--panel);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 400;
}

.probBar__fillA { border-right: 3px solid var(--accent-purple); }

/* Team names are arbitrary-length user/roster text (not a fixed "NN%"),
   so this stays in the readable font -- only weight/spacing change, no
   pixel face here (risk of wrap/overflow on a long typed-in name). */
.probLabels {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

/* Team 1 and Team 2 stack instead of sitting side by side: with 8 columns,
   splitting the page width in half left each table too cramped to show its
   own columns (forcing heavy horizontal scrolling and, combined with each
   independently-sized table, visibly mismatched layouts between the two).
   Stacked, each table gets the full page width instead of half of it. */
.breakdown {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 24px;
}

.proTeaserSection {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}

.proTeaserTeams {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 16px 0;
}

.proTeaserTeam h3 {
  margin: 0 0 8px;
  font-size: 0.78rem;
  line-height: 1.6;
}

.proTeaserRoster {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.proTeaserRoster > div {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
}

.adSlot {
  margin: 16px 0;
  padding: 8px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  text-align: center;
  overflow: hidden;
}

.adSlotLabel {
  display: block;
  margin-bottom: 6px;
  font-size: 0.68rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.authGate {
  margin: 12px 0;
  padding: 18px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  text-align: center;
}

.authGate p {
  margin: 0 0 10px;
  color: var(--muted);
}

.proTeaserLockNote {
  margin-top: 12px;
  padding: 14px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
}

.proTeaserLockNote p {
  margin: 0 0 10px;
  color: var(--muted);
}

.breakdownTeam {
  min-width: 0;
}

/* Arbitrary team-name text (currentResultNames), not a fixed string --
   same reasoning as .team h2/.probLabels: bold readable font, no pixel
   face. */
.breakdownTeamTitle {
  margin: 0 0 8px;
  font-size: 0.82rem;
  line-height: 1.6;
  text-transform: uppercase;
}

.tableScroll {
  overflow-x: auto;
}

table {
  width: 100%;
  min-width: 860px;
  border-collapse: collapse;
  background: var(--panel);
  border: 2px solid var(--border);
  border-radius: 0;
  overflow: hidden;
  font-size: 0.82rem;
}

table th, table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

/* Solid flat fill, not a soft tint -- same "block, not blur" move used
   on every other active/emphasis state across the redesign. */
table th {
  background: var(--accent-purple);
  color: #1e1e1e;
  font-weight: 700;
}

/* The two breakdown tables (Team 1 / Team 2) are independent <table>
   elements, so browser auto-layout sized each one's columns from only its
   own content -- one team's longer note text could make its whole table
   render with very different (and much taller) rows than the other team's,
   even though they're meant to look like a matched pair. Fixed, identical
   percentage widths make both tables always line up the same way regardless
   of which team happens to have longer text in a given column. */
.breakdown table {
  table-layout: fixed;
}
/* 10 columns now (renderTable() in app.js added "Урон (кор-роли)" as the
   10th, nth-child(10) below) -- these 9 used to sum to exactly 100% on their
   own, leaving the 10th with no explicit width at all. Under table-layout:
   fixed a column with no width still gets rendered, just squeezed to ~0px,
   so its text wraps one character per line and inflates that row's height
   to match -- which is what was actually stretching rows so hard. */
.breakdown th:nth-child(1), .breakdown td:nth-child(1) { width: 7%; }
.breakdown th:nth-child(2), .breakdown td:nth-child(2) { width: 18%; }
.breakdown th:nth-child(3), .breakdown td:nth-child(3) { width: 8%; }
.breakdown th:nth-child(4), .breakdown td:nth-child(4) { width: 10%; }
.breakdown th:nth-child(5), .breakdown td:nth-child(5) { width: 11%; }
.breakdown th:nth-child(6), .breakdown td:nth-child(6) { width: 10%; }
.breakdown th:nth-child(7), .breakdown td:nth-child(7) { width: 8%; }
.breakdown th:nth-child(8), .breakdown td:nth-child(8) { width: 8%; }
.breakdown th:nth-child(9), .breakdown td:nth-child(9) { width: 8%; }
.breakdown th:nth-child(10), .breakdown td:nth-child(10) { width: 12%; }

.keyPlayer {
  margin-top: 20px;
  background: var(--panel);
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-purple);
  border-radius: 0;
  padding: 12px 14px;
  font-size: 0.9rem;
}

.keyPlayer b { font-weight: 700; }

.durationSpikes {
  margin-top: 20px;
  background: var(--panel);
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-green);
  border-radius: 0;
  padding: 12px 14px;
}

.durationSpikes:empty { display: none; }

.durationSpikes h3 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.8;
  text-transform: uppercase;
}

.durationHint {
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--text-muted, #666);
}

.durationTable {
  min-width: 0;
  font-size: 0.85rem;
}

.durationDelta--up { color: var(--accent-purple-dark); font-weight: 600; }
.durationDelta--down { color: #b45309; font-weight: 600; }
.durationDelta--flat { color: var(--text-muted, #666); }

.liveTrend {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0 0;
  color: var(--accent-purple-dark);
}
.liveTrend:empty { display: none; }
.liveTrend svg {
  width: 100%;
  max-width: 420px;
  height: auto;
}
.liveTrend span { font-size: 0.85rem; font-weight: 600; }

.liveNowPct { color: var(--accent-purple-dark); font-weight: 600; }

.drawerMenuBtn {
  width: 100%;
}

.howItWorksSection {
  margin-top: 8px;
  max-width: 760px;
}

.howItWorksSection h2 {
  margin: 0 0 16px;
  font-size: 1.1rem;
  line-height: 1.6;
}

.howItWorksSection p {
  margin: 0 0 14px;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.6;
}

.howItWorksSection p:last-child { margin-bottom: 0; }

code {
  font-family: var(--font-mono);
}

.howItWorksSection code {
  background: var(--accent-purple-tint);
  border: 1px solid var(--border);
  padding: 1px 5px;
  border-radius: 0;
}

/* Percentages/scores read as "editor numbers" -- a small, deliberate
   monospace touch on result cards, matching the same treatment as the
   win-probability bar, without switching body copy to monospace. */
.historyRow b,
.draftHeroCard b,
.draftBanNote,
#mistakeMatchIdInput {
  font-family: var(--font-mono);
}

/* ---- hamburger menu + side drawer ---- */
.menuBtn {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 100;
  width: 42px;
  height: 42px;
  border: 2px solid var(--accent-purple);
  border-radius: 0;
  background: var(--panel);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  cursor: pointer;
  padding: 0;
}

.menuBtn span {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--accent-purple);
}

.drawerOverlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 150;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: min(340px, 88vw);
  background: linear-gradient(165deg, var(--accent-purple-deep), var(--accent-purple));
  border-left: 3px solid rgba(255, 255, 255, 0.3);
  box-shadow: -6px 0 20px rgba(0, 0, 0, 0.18);
  z-index: 200;
  padding: 56px 20px 20px;
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 0.25s ease;
  display: flex;
  flex-direction: column;
  color: #ffffff;
}

.drawer--open {
  transform: translateX(0);
}

/* Scales with the phone's own screen instead of the 340px desktop cap
   (a true 100vw takeover read as oversized/empty rather than a drawer --
   this stays proportional without a low px ceiling). */
@media (max-width: 480px) {
  .drawer {
    width: 92vw;
  }
}

.drawerClose {
  position: absolute;
  top: 10px;
  right: 12px;
  border: none;
  background: transparent;
  color: #ffffff;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
}

.drawerClose:hover { background: transparent; color: var(--accent-purple-tint); }

.authBar {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.9rem;
}

.authBar button { width: 100%; }

.authUserName {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--accent-purple-dark);
  word-break: break-word;
}

.authForms {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 16px;
}

.authModalOverlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 20px; background: #0009; }
.authModal { position: relative; width: min(400px, 100%); max-height: 90vh; overflow-y: auto; padding: 25px; border: 2px solid var(--accent-purple); border-radius: 0; background: var(--panel); color: var(--text); }
.authModalClose { position: absolute; top: 9px; right: 12px; background: transparent; border: 0; color: var(--text); font-size: 26px; cursor: pointer; }
.authModeTabs { display: flex; gap: 8px; padding-right: 25px; }
.authModeTabs button { flex: 1; }
.authModeTabs button.active { background: var(--accent-purple); color: #fff; }
.authModal .authForms { margin: 12px 0 0; }
.authModal .authForm { background: transparent; border-color: var(--border); }
.authModal .authForm h2 { color: var(--text); }
.captchaBox { display: grid; gap: 7px; }
.captchaBox img { max-width: 100%; border-radius: 0; }
.authModalOpen { overflow: hidden; }
@media (min-width: 701px) { #drawer, #drawerOverlay, #menuBtn { display: none !important; } }

.authForm {
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-radius: 0;
  padding: 16px;
  background: rgba(255, 255, 255, 0.08);
}

.authForm h2 {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.6;
  text-transform: uppercase;
  color: #ffffff;
}

.authForm form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.authForm input {
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-radius: 0;
  padding: 8px 10px;
  font-size: 0.9rem;
  background: var(--panel);
  color: var(--text);
}

.drawerBottomGroup {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* "Выйти" sits at the very bottom of the profile page, set apart from the
   account/Telegram settings above it by a dashed rule. */
.profileLogoutWrap {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  display: flex;
  justify-content: center;
}

.logoutBtn {
  padding: 8px 32px;
  color: #c0392b;
  border-color: #c0392b;
  background: transparent;
  font-weight: 600;
}

.logoutBtn:hover:not(:disabled) {
  background: #c0392b;
  border-color: #c0392b;
  color: #ffffff;
}

.statsSection {
  margin-top: 8px;
}

/* "// " eyebrow prefix, same move as the approved look reference's
   "// предсказание матча" -- a separate pseudo-element (not typed into
   every heading string in index.html) so it stays purely decorative and
   never ends up copied into a toast/share-text/aria-label that reads the
   heading's own text. */
.statsSection h2::before {
  content: "// ";
  color: var(--accent-purple-dark);
}

.statsSection h2 {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: 1.4rem;
  line-height: 1.6;
  letter-spacing: 0.02em;
  font-weight: 400;
  text-transform: uppercase;
}

.statsSection h3 {
  margin: 18px 0 8px;
  font-family: var(--font-display);
  font-size: 0.8rem;
  line-height: 1.7;
  letter-spacing: 0.02em;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--accent-purple-dark);
}

.statsSection p {
  margin: 0 0 4px;
  font-size: 0.85rem;
}

.historyHint {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.76rem;
}

.statsModeToggle {
  display: flex;
  gap: 8px;
  margin: 0 0 12px;
}

.statsModeBtn {
  flex: 1;
  padding: 6px 10px;
  font-size: 0.85rem;
}

.statsModeBtn--active {
  background: var(--accent-purple);
  color: #1e1e1e;
  border-color: var(--accent-purple);
}

.statsModeBtn--active:hover:not(:disabled) {
  background: var(--accent-purple-deep);
  border-color: var(--accent-purple-deep);
  color: #ffffff;
}

#historyList,
#tournamentList,
#liveList,
.fitBox {
  max-height: 50vh; /* fallback until JS measures the exact available space */
  overflow-y: auto;
  padding-right: 4px;
}

/* In-page links (e.g. the patch page's link to the pro-scene stats): the
   browser-default blue is hard to read on both themes. */
.statsSection a {
  color: var(--accent-purple-dark);
  font-weight: 600;
}

.statsSection a:hover {
  color: var(--accent-purple);
}

/* "По турнирам": the tournaments are cards that sit centred on the page --
   one or two stay in the middle, more wrap into further centred lines. */
#tournamentList {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: flex-start;
  gap: 0 10px;
}

#tournamentList .tournamentRow {
  flex: 0 1 min(340px, 100%);
  justify-content: center;
  gap: 3px;
  text-align: center;
}

#tournamentList > p {
  flex: 1 1 100%;
  text-align: center;
}
.liveToggleRow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 0 0 6px;
}

.liveToggleLabel {
  margin: 0;
  font-size: 0.85rem;
}

.liveRoleHint {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.3;
}

@media (max-width: 700px) {
  .liveRoleHint {
    font-size: 0.74rem;
  }
}

/* The "Live-матчи" heading + its own tournament-filter row used to live
   here, above the list -- removed (see the HTML comment) and this margin
   moved onto #liveList directly, so the list keeps the same breathing room
   from the calibration table above it. */
#liveList {
  margin-top: 12px;
}

.liveLeagueLabel {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 0.78rem;
}

.liveLeagueLabel select {
  height: 28px;
  max-width: 240px;
  padding: 2px 8px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  color: var(--text);
  font-size: 0.8rem;
}

/* Small solid chip, not a soft outline pill -- same "FREE"/"POS 1" badge
   move used throughout. */
.liveTierBadge {
  margin-left: 6px;
  padding: 2px 7px;
  border: none;
  border-radius: 0;
  background: var(--accent-green);
  color: #0a1f1b;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 700;
  vertical-align: middle;
}

/* ---- team line-ups + tournament (prediction form, signed-in users) ---- */
.teamHead {
  display: flex;
  align-items: center;
  gap: 6px 12px;
  margin: 0 0 10px;
}

.teamHead h2 {
  margin: 0;
  flex: none;
}

/* For a signed-in user the heading is replaced by the team-name field. */
.teams--user .teamTitle {
  display: none;
}

.teamNameWrap {
  flex: 1 1 auto;
  min-width: 0;
}


.team-name-input,
.tournament-input {
  width: 100%;
  height: 34px;
  padding: 4px 10px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  color: var(--text);
  font-size: 0.88rem;
}

.team-name-input::placeholder,
.tournament-input::placeholder {
  color: var(--muted);
}

/* Reads like the heading it replaces ("Команда 1"), but is a field -- and the
   tournament field looks the same, with "Турнир" as its text. Pixel face
   like every other heading now, even though this one can hold a
   user-typed name -- short team/tournament names in practice, and the
   user explicitly asked for "Команда 1"/"Турнир" to read as headings. */
.teamHead .team-name-input,
.tournamentPicker .tournament-input {
  height: 38px;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* One field for the tournament, centred over the two teams. */
.tournamentPicker {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: 480px;
  margin: 0 auto 12px;
}

.tournamentWrap {
  flex: 1 1 auto;
  min-width: 0;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 400;
  max-width: min(90vw, 460px);
  padding: 10px 18px;
  border-radius: 0;
  border: 2px solid var(--accent-purple);
  background: var(--accent-purple-deep);
  color: #ffffff;
  font-size: 0.85rem;
}

/* Narrower desktop windows: the team header (title + picker + save tick)
   shrinks to stay on one line, and short windows get tighter panels so the
   prediction page still fits without scrolling. */
@media (min-width: 701px) and (max-width: 1100px) {
  .teamHead {
    margin-bottom: 8px;
  }

  .teamHead .team-name-input,
  .tournamentPicker .tournament-input {
    height: 34px;
    font-size: 0.64rem;
  }
}

@media (min-width: 701px) and (max-height: 760px) {
  .team {
    padding: 10px 12px;
  }

  .slot {
    margin-bottom: 5px;
  }

  .slot input,
  .slot .position-select {
    height: 34px;
  }

  .tournamentPicker {
    margin-bottom: 8px;
  }
}

@media (max-width: 700px) {
  /* the live tab's controls are the tallest thing on a small phone */
  .liveRoleHint {
    line-height: 1.25;
  }

  #livePanel h3 {
    margin: 8px 0 3px;
  }

  .statsModeToggle {
    margin-bottom: 8px;
  }

  .liveToggleRow {
    margin-bottom: 4px;
  }

  .liveLeagueLabel select {
    height: 26px;
  }

  #livePanel h3 {
    margin-top: 6px;
  }

  .tier1Controls {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 10px;
  }

  .tier1Controls .draftControlLabel select {
    width: 100%;
    min-width: 0;
    max-width: none;
  }
}

.tier1Pos {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border: none;
  border-radius: 0;
  background: var(--accent-purple-tint);
  color: var(--accent-purple-dark);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  vertical-align: middle;
}

/* ---- saved / live mistake analyses ---- */
.historyRow.mistakeHead {
  cursor: default;
}

.mistakeSummary {
  margin: 8px 0 0;
  padding: 10px 14px;
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-green);
  border-radius: 0;
  background: var(--accent-green-tint);
  font-size: 0.88rem;
  line-height: 1.45;
}

.mistakeActions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.mistakeSavedNote {
  margin: 0 0 8px;
}

/* Only useful on a phone, where the form is tucked away while a result is
   on screen (see the mobile block below). */
.mistakeNewBtn {
  display: none;
}

@media (max-width: 700px) {
  /* One saved analysis open on a phone: the tab row and a long summary would
     leave no room for the analysis text itself. */
  #mistakeSection.mistakeSection--detail #mistakeModeToggle {
    display: none;
  }

  .mistakeSummary {
    max-height: 6.4em;
    overflow-y: auto;
    padding: 6px 10px;
    font-size: 0.8rem;
  }

  .mistakeHead b {
    font-size: 0.8rem;
  }

  .mistakeSection--showingResult #mistakeForm {
    display: none;
  }

  .mistakeSection--showingResult .mistakeNewBtn {
    display: inline-block;
    margin-bottom: 6px;
  }
}

.historyRowTop b {
  flex: 1;
  min-width: 0;
}

.historySummary {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- tier-1 meta ---- */
.tier1Controls .draftControlLabel select {
  max-width: 280px;
}

.historyRow.tier1Row {
  flex-direction: row;
  align-items: center;
  gap: 10px;
}

.historyRow.tier1PlayerRow {
  cursor: default;
}

.historyRow.tier1PlayerRow:hover {
  background: var(--panel);
}

.historyRow.tier1Row--selected {
  border-left-color: var(--accent-purple);
  background: var(--accent-purple-tint);
}

.tier1Name {
  flex: 1;
  text-align: left;
  min-width: 0;
  font-weight: 700;
  font-size: 1.05rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tier1Sub {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.76rem;
}

/* Hero names are always Latin (OpenDota's localized_name, e.g.
   "Anti-Mage") regardless of site language, so Silkscreen's missing
   Cyrillic doesn't apply here -- same reasoning as the logo, and the
   exact face used for hero names in the approved look reference. */
.tier1HeroNameText {
  font-family: var(--font-logo);
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.tier1Num {
  flex: none;
  min-width: 96px;
  text-align: right;
  color: var(--muted);
  font-size: 0.78rem;
  font-family: var(--font-mono);
}

.tier1Bar {
  flex: none;
  width: 90px;
  height: 6px;
  border-radius: 0;
  background: rgba(128, 128, 128, 0.25);
  overflow: hidden;
}

.tier1Bar i {
  display: block;
  height: 100%;
  background: var(--accent-purple);
}

.tier1Bar.tier1Wr--good i {
  background: var(--accent-green);
}

.tier1Bar.tier1Wr--bad i {
  background: #c0392b;
}

.tier1Bar.tier1Wr--low i {
  background: var(--muted);
}

.tier1Wr {
  flex: none;
  min-width: 56px;
  text-align: right;
  font-weight: 700;
  font-size: 1.05rem;
  font-family: var(--font-mono);
}

.tier1Wr--good {
  color: var(--accent-green);
}

.tier1Wr--bad {
  color: #c0392b;
}

.tier1Wr--low {
  opacity: 0.7;
}

.tier1DetailHead {
  margin: 4px 0 8px;
  font-size: 0.92rem;
}

.tier1Tabs {
  margin-bottom: 8px;
}

/* ---- patches ---- */
.patchHeader {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 16px;
}

.patchHeader .historyHint {
  margin: 0;
}

/* The number itself is the solid accent-filled "window" (same move as
   .emptyStateBlock/(ДАННЫХ НЕТ)) -- no "Патч" label next to it, the picker
   button's own purpose (switch patch) is carried by the caret. align-items
   was baseline -- fine when every piece shared one font, but the pixel
   face's baseline sits at a different relative spot in its own em-box than
   the plain caret next to it, which read as "7.41" floating off-line.
   center compares actual rendered heights instead. */
.patchPickerBtn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 4px;
  border-color: var(--accent-purple);
  background: none;
}

.patchPickerBtn b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4em;
  padding: 10px 14px;
  font-size: 1.15rem;
  line-height: 1;
  font-family: var(--font-display);
  font-weight: 400;
  background: var(--accent-purple);
  color: #1e1e1e;
}

.patchPickerCaret {
  color: var(--muted);
  font-size: 0.85rem;
  padding-right: 8px;
}

.patchPickerMenu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 60;
  min-width: 240px;
  max-height: 50vh;
  overflow-y: auto;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  display: flex;
  flex-direction: column;
}

.patchPickerItem {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 8px 14px;
  text-align: left;
  background: transparent;
  color: var(--text);
}

.patchPickerItem:last-child {
  border-bottom: none;
}

.patchPickerItem--active {
  background: var(--accent-purple-tint);
}

/* Multi-select toggle filter, not tabs -- each button latches independently
   (buff/nerf/change all pressable at once) and narrows the one combined
   list below instead of switching between separate lists. No button
   pressed means no filter applied (show everything), which is also what
   pressing every button amounts to -- there's deliberately no separate
   "all" button for that reason. */
.patchFilterBar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.patchFilterBtn {
  padding: 8px 14px;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  border-color: var(--muted);
  color: var(--muted);
}

.patchFilterBtn--buff.patchFilterBtn--active {
  background: var(--accent-green);
  border-color: var(--accent-green);
  color: #1e1e1e;
}
.patchFilterBtn--nerf.patchFilterBtn--active {
  background: #c0392b;
  border-color: #c0392b;
  color: #ffffff;
}
.patchFilterBtn--change.patchFilterBtn--active {
  background: var(--accent-purple);
  border-color: var(--accent-purple);
  color: #1e1e1e;
}

.patchProse p {
  margin: 0 0 10px;
  font-size: 0.88rem;
  line-height: 1.55;
}

.patchProse .patchSummary {
  font-size: 0.95rem;
}

.patchEntry {
  padding: 8px 12px;
  margin-bottom: 6px;
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-purple);
  border-radius: 0;
  background: var(--panel);
  font-size: 0.85rem;
}

.patchEntry--buff {
  border-left-color: var(--accent-green);
}

.patchEntry--nerf {
  border-left-color: #c0392b;
}

.patchEntry--change {
  border-left-color: var(--accent-purple);
}

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

.patchEntryChange {
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
}

.patchEntryWhy {
  margin-top: 3px;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.4;
}

/* The magnitude bar: color = direction (green buff / red nerf / purple
   change, same mapping as the filter buttons above), fill width = impact
   where the model actually gave one (buffed/nerfed heroes only --
   patchBarWidth()'s neutral default covers everything else, it isn't a
   real measurement there). */
.patchBar {
  flex: none;
  width: 56px;
  height: 8px;
  margin-left: auto;
  background: var(--border);
  overflow: hidden;
}
.patchBar i {
  display: block;
  height: 100%;
}
.patchBar--buff i { background: var(--accent-green); }
.patchBar--nerf i { background: #c0392b; }
.patchBar--change i { background: var(--accent-purple); }

.patchChips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 8px;
}

.patchChip {
  padding: 3px 12px;
  border-radius: 0;
  font-size: 0.8rem;
  font-weight: 700;
  border: 2px solid;
}

.patchChip--up {
  border-color: var(--accent-green);
  color: var(--accent-green);
  background: var(--accent-green-tint);
}

.patchChip--down {
  border-color: #c0392b;
  color: #c0392b;
  background: rgba(192, 57, 43, 0.08);
}


@media (max-width: 700px) {
  /* The hero name routinely didn't fit next to the icon + games/winrate
     columns and just ellipsis-truncated into unreadable fragments ("Dark
     ...", "Ember...") -- the icon alone already identifies the hero (same
     icon the rest of the site uses), so drop the name text here and let the
     games/pick column use the freed space instead of leaving it blank. */
  .tier1HeroNameText {
    display: none;
  }

  .tier1Name {
    flex: 0 0 auto;
  }

  .tier1Num {
    flex: 1;
    min-width: 0;
    font-size: 0.72rem;
  }

  .tier1Bar {
    display: none;
  }

  /* Inside one hero's card a phone screen has no room for the filters,
     summary and explanations above it -- the card's own header already says
     which patch/tournament it is about. */
  #tier1Section.tier1Section--detail #tier1Note,
  #tier1Section.tier1Section--detail #tier1Controls,
  #tier1Section.tier1Section--detail #tier1Summary,
  #tier1Section.tier1Section--detail .tier1Tabs + .historyHint {
    display: none;
  }

  .statsModeBtn {
    padding: 6px 6px;
    font-size: 0.8rem;
  }
}

.telegramBox {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-purple);
  border-radius: 0;
  background: var(--panel);
  font-size: 0.85rem;
}

.telegramBox p {
  margin: 0 0 6px;
}

.telegramSteps {
  margin: 0 0 8px;
  padding-left: 20px;
}

.telegramSteps li {
  margin-bottom: 4px;
}

.liveModeToggleRow {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.telegramUnlinkBtn {
  color: #c0392b;
  border-color: #c0392b;
}

.telegramUnlinkBtn:hover:not(:disabled) {
  background: #c0392b;
  color: #ffffff;
}

.twoFactorToggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.twoFactorCancelBtn {
  margin-top: 10px;
  background: transparent;
  border: none;
  color: var(--accent-purple-dark);
  padding: 0;
  font-size: 0.85rem;
  text-decoration: underline;
}

.twoFactorCancelBtn:hover:not(:disabled) {
  background: transparent;
  color: var(--accent-purple);
}

.draftControls {
  display: flex;
  gap: 16px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin: 0 0 8px;
}

.draftControlLabel {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 0.8rem;
  color: var(--muted);
}

.draftControlLabel select,
.draftControlLabel input {
  height: 36px;
  padding: 4px 10px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  color: var(--text);
  font-size: 0.92rem;
  min-width: 150px;
}

/* Profile page: account_id and rank sit in the same row (draftControls'
   flex layout already does that); the account field just needs to claim
   more of the row than the rank dropdown. */
.profileRow {
  margin: 0 0 4px;
}

.profileField--account {
  flex: 1 1 260px;
}

.profileField--account input {
  width: 100%;
}

/* Read-only player/rank line on the draft page itself, with a quick inline
   rank editor and the "ignore pool" checkbox next to it -- both exist for
   watching a live match and wanting a last-pick suggestion at a different
   rank / without personal-pool bias, without leaving the page. */
.draftProfileSummary {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--muted);
}

.draftChangeRankBtn {
  padding: 3px 10px;
  font-size: 0.76rem;
}

.draftRankQuickEdit {
  display: flex;
  align-items: center;
  gap: 6px;
}

.draftRankQuickEdit select {
  height: 28px;
  padding: 2px 8px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  color: var(--text);
  font-size: 0.78rem;
}

.draftRankQuickEdit button {
  padding: 3px 10px;
  font-size: 0.78rem;
}

.draftTargetPositionLabel {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.78rem;
  color: var(--text);
}

.draftTargetPositionLabel select {
  height: 28px;
  padding: 2px 8px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  color: var(--text);
  font-size: 0.78rem;
}

.draftCheckboxLabel {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--text);
  cursor: pointer;
}

/* Section heading with an inline enable-toggle to its left, instead of a
   separate checkbox row below the heading -- one line saved, and the
   checkbox already reads left-to-right before the title it controls. */
.sectionHeaderRow {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sectionHeaderRow h2 {
  margin: 0;
}

/* Round radio-look checkbox: an outlined circle idle, a solid purple dot
   (the outer ring created by an inset shadow matching the page background)
   once checked, instead of the browser's default square box. */
.draftCheckboxLabel input {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  min-width: 18px;
  border-radius: 50%;
  border: 2px solid var(--muted);
  background: var(--panel);
  margin: 0;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.draftCheckboxLabel input:checked {
  border-color: var(--accent-purple);
  background: var(--accent-purple);
  box-shadow: inset 0 0 0 3px var(--panel);
}

.draftSubscriptionNote {
  font-size: 0.7rem;
  color: var(--muted);
  font-weight: 400;
}

.draftTeams {
  display: grid;
  gap: 20px;
  margin-bottom: 6px;
}

/* The mobile single-column override lives in the shared teamSwitcher media
   query above -- this two-column layout only applies once that stops
   overriding it, and has to be gated the same way (min-width, not just an
   unconditional default) since a later same-specificity rule always beats
   an earlier one regardless of which is wrapped in a media query. */
@media (min-width: 701px) {
  .draftTeams {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* Same-size boxes, just nudged down so the page doesn't read as
       top-heavy when there's no result below yet -- a bit more than before
       now that the removed "Назад" button left extra room up top. */
    margin-top: 56px;
  }
}

.draftTeam h3 {
  margin: 0 0 6px;
  font-size: 0.9rem;
}

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

.draftHeroSlot {
  min-width: 0;
}

.draftHeroSlot--withPosition {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: 8px;
}

.draftHeroSlot .position-select,
.draftHeroSlot input {
  background: var(--panel);
  border: 2px solid var(--border);
  color: var(--text);
  border-radius: 0;
  padding: 5px 10px;
  font-size: 0.9rem;
  width: 100%;
  min-width: 0;
  height: 36px;
}

.draftHeroSlot input::placeholder { color: var(--muted); }

.draftHeroCard {
  cursor: default;
}

/* The match-id field is the only control on this page -- centered (like the
   button below it already was) and sized up along with the button so the
   page reads as deliberate rather than left-aligned and sparse in an
   otherwise mostly-empty view. */
#mistakeForm .draftControls {
  justify-content: center;
}

#mistakeForm .draftControlLabel {
  font-size: 0.95rem;
}

#mistakeMatchIdInput {
  height: 40px;
  min-width: 240px;
  padding: 6px 12px;
  font-size: 0.98rem;
}

#mistakeAnalyzeBtn {
  padding: 10px 32px;
  font-size: 1rem;
}

#mistakeResults {
  margin-top: 20px;
}

/* Vertically centered on the page until the user actually asks for
   something -- once they do (mistakeSection--hasResult, set on submit, not
   just once a result lands, so this is already in place while waiting), it
   settles to the top like the rest of the site, staying fully usable for
   the next search instead of reverting. The field/button themselves stay
   standard-sized throughout (see the base #mistakeMatchIdInput/
   #mistakeAnalyzeBtn rules above) -- only the wrapper's position moves. */
#mistakeSection:not(.mistakeSection--hasResult) #mistakeForm {
  min-height: 46vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

#mistakeForm {
  transition: min-height 0.25s ease;
}

.mistakeWaiting {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin: 24px 0;
  padding: 20px 14px;
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
}

.spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--accent-purple-tint);
  border-top-color: var(--accent-purple);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.mistakeAnalysisText {
  margin: 8px 0 0;
  padding: 12px 14px;
  border: 2px solid var(--border);
  border-radius: 0;
  background: var(--panel);
  font-size: 0.85rem;
  line-height: 1.55;
}

/* Deliberately a different look from .mistakeAnalysisText above (border-left
   accent, not a plain box) -- this is real match data, not an AI write-up,
   and shouldn't read as one more paragraph of it. */
.mistakeBuildAdvice {
  margin: 10px 0 0;
  padding: 10px 14px;
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-purple);
  border-radius: 0;
  background: var(--panel);
  font-size: 0.83rem;
  line-height: 1.5;
}

.mistakeBuildAdvice h4 {
  margin: 0 0 4px;
  font-size: 0.6rem;
  line-height: 1.6;
}

.mistakeBuildAdvice .historyHint {
  margin: 0 0 8px;
}

.buildAdviceRow {
  margin-top: 4px;
}

#draftResults h3 {
  margin: 14px 0 6px;
  font-size: 0.9rem;
}

.tournamentRow {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.statsSection table {
  width: 100%;
  min-width: 0;
  border-collapse: collapse;
  font-size: 0.78rem;
}

.statsSection th,
.statsSection td {
  padding: 2px 8px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

/* The totals/accuracy line used to be a separate paragraph above this table
   -- now a <caption>, so the two read as one compact block instead of two. */
.calibrationTable {
  font-size: 0.74rem;
}

.calibrationTable caption {
  caption-side: top;
  text-align: left;
  padding: 0 0 6px;
  color: var(--muted);
  font-size: 0.76rem;
}

.calibrationTable th,
.calibrationTable td {
  padding: 2px 6px;
}

.historyRow {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 14px;
  margin-bottom: 7px;
  border: 2px solid var(--border);
  border-left: 5px solid #6e6e6e;
  border-radius: 0;
  font-size: 0.9rem;
  background: var(--panel);
  cursor: pointer;
}

.historyRow:hover {
  background: var(--accent-purple-tint);
}

.historyRow--win {
  border-left-color: var(--accent-green);
  background: var(--accent-green-tint);
}

.historyRow--loss {
  border-left-color: var(--accent-purple);
  background: var(--accent-purple-tint);
}

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

.historyTitleInput {
  border: none;
  background: transparent;
  font-weight: 700;
  font-size: 0.95rem;
  padding: 2px 0;
  cursor: text;
  width: 100%;
  min-width: 0;
}

.historyTitleInput:hover,
.historyTitleInput:focus {
  outline: none;
  text-decoration: underline dotted;
}

/* Share/tag/delete used to be a mix of text buttons and a full-width dashed
   input row on every card -- same small square icon button for all three now,
   and the tournament input only appears on demand (historyTournamentToggleBtn),
   so a card without a tournament set doesn't pay for that row at all. */
.historyIconBtn {
  flex: none;
  width: 22px;
  height: 22px;
  padding: 0;
  line-height: 1;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
  border-color: var(--muted);
}

.historyPublicBtn--on {
  color: var(--accent-green, #3ec5a0);
  border-color: var(--accent-green, #3ec5a0);
}

.historyDeleteBtn:hover:not(:disabled) {
  background: #c0392b;
  border-color: #c0392b;
  color: #ffffff;
}

.historyTagRow {
  margin-top: 4px;
}

.historyTournamentTag {
  color: var(--accent-purple-dark);
  font-weight: 600;
}

.historyTournamentInput {
  font-size: 0.72rem;
  padding: 1px 8px;
  border: 2px dashed var(--muted);
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  width: auto;
  max-width: 100%;
  height: auto;
}

.historyTournamentInput:hover,
.historyTournamentInput:focus {
  border-color: var(--accent-purple);
}

.historyTournamentInput:not(:placeholder-shown) {
  border-style: solid;
  border-color: var(--accent-purple);
  color: var(--accent-purple-dark);
  font-weight: 600;
  background: var(--accent-purple-tint);
}

.historyMeta {
  color: var(--muted);
  font-size: 0.78rem;
}

.draftBanNote {
  margin-top: 3px;
  color: var(--accent-purple-dark);
  font-size: 0.78rem;
  font-weight: 600;
}

.outcomePrompt {
  margin-top: 20px;
  padding: 12px 14px;
  border: 2px solid var(--border);
  border-left: 4px solid var(--accent-green);
  border-radius: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 0.88rem;
}

#outcomeSaved {
  color: var(--accent-green);
  font-weight: 600;
}

/* "Добавить аккаунт" modal trigger -- the compact list + modal is now the
   only way to add an account on any screen size, matching the mobile
   layout everywhere instead of showing an always-open form on desktop. */
.addAccountBtn {
  display: inline-flex;
}

#profileInlineForm {
  display: none;
}

#linkedAccountsList {
  /* max-height is set from JS (sizeScrollBox, same as the match-history
     list) to the space actually available on screen -- a fixed 40vh
     didn't account for how much room the rest of the page needed and
     could still overflow the viewport on shorter screens. This fallback
     only matters for the instant before that JS runs. */
  max-height: 40vh;
  overflow-y: auto;
  padding-right: 4px;
}

.modalOverlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.modalBox {
  background: var(--panel);
  border: 2px solid var(--accent-purple);
  border-radius: 0;
  padding: 20px;
  width: 100%;
  max-width: 420px;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.modalBox h3 {
  margin: 0 0 4px;
}

/* ---- admin: ratings + live-match roster/position editor ---- */
.adminBlock {
  margin-bottom: 28px;
}

.adminBlock h3 {
  margin-bottom: 4px;
}

.adminRatingsGrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 10px;
}

.adminRatingsGrid input[type="text"] {
  width: 100%;
  margin: 6px 0;
}

.adminRatingsGrid table {
  max-height: 360px;
  display: block;
  overflow-y: auto;
}

@media (max-width: 700px) {
  .adminRatingsGrid {
    grid-template-columns: 1fr;
  }
}

.adminLiveMatch {
  border: 2px solid var(--border);
  border-radius: 0;
  margin-bottom: 8px;
  background: var(--panel);
  overflow: hidden;
}

.adminLiveMatchHead {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 8px 12px;
  background: transparent;
  border: none;
  border-radius: 0;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}

.adminLiveMatchHead:hover:not(:disabled) {
  background: var(--accent-purple-tint);
  color: var(--text);
}

.adminLiveMatchBody {
  padding: 10px 12px 14px;
  border-top: 1px solid var(--border);
}

.adminLiveMatchTeams {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

@media (max-width: 700px) {
  .adminLiveMatchTeams {
    grid-template-columns: 1fr;
  }
}

.adminLiveMatchTeams .heroIcon {
  width: 22px;
  height: 22px;
  border-radius: 0;
  vertical-align: middle;
}

.adminSaveBtn {
  margin-top: 10px;
}

.adminSaveResult {
  margin-left: 10px;
  font-size: 0.82rem;
  color: var(--muted);
}

.modalCloseBtn {
  position: absolute;
  top: 6px;
  right: 8px;
  background: transparent;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--muted);
  padding: 4px 8px;
}

.modalCloseBtn:hover:not(:disabled) {
  background: transparent;
  color: var(--accent-purple);
}

.modalBox .draftControlLabel select,
.modalBox .draftControlLabel input {
  width: 100%;
}

/* Desktop top nav rules -- placed here (not next to .topNav's display:none
   default near the top) because #mobileHeader and .menuBtn each have their
   own unconditional base rule later in the cascade than that would have
   been; putting the override last guarantees it wins regardless. */
@media (min-width: 701px) {
  #mobileHeader,
  .menuBtn {
    display: none;
  }

  /* Boxed toolbar (matching the rest of the site's bordered-panel language,
     rather than an edge-to-edge bleed) with flat tab-style links inside --
     the Dotabuff/ProTracker look: a solid bar, no per-link button chips,
     a filled rounded-rect on the active/hovered tab instead of an
     underline. Every zone centers its own content on the cross-axis with
     plain align-items (no height:100%/stretch tricks, which needs the
     parent to have a resolved height to stretch against and was why the
     center links sat higher than the title/profile buttons). */
  /* Three columns, the middle one auto-sized between two equal 1fr sides:
     the section tabs therefore sit exactly in the middle of the bar no
     matter how wide the logo and the profile button happen to be (with
     space-between they drifted right of centre). */
  /* grid-template-columns used to be 1fr auto 1fr -- a mirrored pair of
     flexible tracks either side of the tabs, which kept them dead-centre
     in the bar. Changed to 1fr auto auto: only the brand's own track
     absorbs the free space now, so the tabs sit clustered toward the
     right (next to the profile button) instead of centred -- per
     feedback on the look reference. */
  .topNav {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    column-gap: 16px;
    max-width: 1180px;
    margin: 0 auto 32px;
    padding: 20px 0 18px;
    background: none;
    border: none;
    border-bottom: 3px solid var(--accent-purple);
    border-radius: 0;
  }

  /* nowrap matters: with the global overflow-wrap:anywhere the logo's min-content
     width collapses to one letter, and the grid column then squeezes it. */
  .topNavTitle {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    font-family: var(--font-logo);
    font-size: 1.25rem;
    font-weight: 400;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #f3edfd;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
  }

  .topNavTitle:hover:not(:disabled) {
    opacity: 0.8;
  }

  /* It's a plain "go home" click, not a form control -- no focus ring. */
  .topNavTitle:focus {
    outline: none;
  }

  /* Logo + a small round "?" (opens "Как это работает") perched at the
     logo's top-right corner like a superscript. */
  .topNavBrand {
    display: flex;
    align-items: flex-start;
    gap: 3px;
    justify-self: start;
  }

  .topNavHelp {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 17px;
    height: 17px;
    margin-top: 1px;
    padding: 0;
    border: 1.5px solid var(--accent-purple);
    border-radius: 50%;
    background: transparent;
    color: var(--accent-purple-dark);
    font-size: 0.62rem;
    font-weight: 800;
    line-height: 1;
    cursor: pointer;
  }

  .topNavHelp:focus {
    outline: none;
  }

  .topNavHelp:hover:not(:disabled),
  .topNavHelp--active,
  .topNavHelp--active:hover:not(:disabled) {
    background: var(--accent-purple);
    border-color: var(--accent-purple);
    color: #ffffff;
  }

  /* Equal-width columns (1fr tracks in a shrink-to-fit grid all take the
     widest label's size), each tab centred in its own cell: with five
     sections the third one is at the bar's exact centre and the rest are
     spaced evenly around it. */
  .topNavCenter {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    justify-items: center;
    align-items: center;
    column-gap: 4px;
  }

  .topNavRight {
    display: flex;
    align-items: center;
    gap: 10px;
    justify-self: end;
  }

  /* line-height was 1.8 -- generous leading on a normal font, but pixel
     fonts don't distribute that extra space symmetrically above/below the
     glyphs the way a normal font's ascent/descent does, which is what
     read as "the active fill sits off-centre vertically". Tight
     line-height (so the font contributes almost no extra space of its
     own) plus flex-centering the button's own box is what actually
     centers it reliably, since padding -- unlike line-height's internal
     half-leading -- is always exactly symmetric. */
  .topNavBtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 0;
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 0.72rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    padding: 10px 14px;
    line-height: 1;
    white-space: nowrap;
  }

  .topNavBtn:focus {
    outline: none;
  }

  .topNavBtn:hover:not(:disabled) {
    background: var(--accent-purple-tint);
    color: var(--accent-purple-dark);
  }

  /* The active tab is a solid flat block -- same move as the reference's
     "FREE" highlight chip, not a soft tint. */
  .topNavBtn--active,
  .topNavBtn--active:hover:not(:disabled) {
    background: var(--accent-purple);
    color: #1e1e1e;
  }

  .topNavRight .topNavBtn {
    border: 2px solid var(--accent-purple);
    padding: 6px 12px;
  }

  .topNavRight .topNavBtn:hover:not(:disabled) {
    background: var(--accent-purple);
    color: #ffffff;
  }

  .topNavUserBtn {
    font-weight: 700;
  }

  /* The top nav already highlights which page you're on -- repeating its
     name as an <h2> inside the page too is redundant there (mobile keeps
     it, since it has no persistent nav to lean on instead). */
  .statsSection h2,
  .howItWorksSection h2 {
    display: none;
  }

  /* Profile sits just slightly in from the right edge (it used to have
     "Выйти" next to it, which moved to the profile page itself). */
  .topNavRight {
    margin-right: 6px;
  }
}

/* Five sections + logo/help + profile stop fitting one row on a narrower
   desktop window: tighten the tabs in two steps, and below ~820px put the
   tabs on a row of their own under the logo/profile line. */
/* Sizes below were tuned for the old sans-serif nav font -- Press Start 2P
   runs noticeably wider per character at the same rem value, so these are
   scaled down from what they used to be, not just carried over. */
/* The single-row layout (logo + 5 tabs + profile all on one line) only
   has room to work down to ~1150px with Press Start 2P -- it runs wider
   per character than the sans-serif font these breakpoints were
   originally tuned for, and unlike that font, .topNavTitle/.topNavBtn
   stay white-space:nowrap, so when the row's natural content width
   exceeds the available space there is nowhere to wrap to: the grid
   track overflows and the overlapping-text bug reported live follows.
   Pushed the "stack tabs on their own row" cutoff up from 985px to
   1150px -- a wider safety margin instead of chasing font-size numbers
   further. min-width: 0 on the two shrinkable tracks is the other half
   of the fix: an auto-sized grid track does not shrink past its own
   content's natural width unless told it is allowed to. */
@media (min-width: 701px) and (max-width: 1150px) {
  .topNavBrand,
  .topNavCenter {
    min-width: 0;
  }

  .topNav {
    grid-template-columns: 1fr auto;
    row-gap: 4px;
    column-gap: 10px;
    padding: 10px 14px;
  }

  .topNavTitle {
    font-size: 0.95rem;
  }

  /* Tabs on their own full-width row below the logo/profile line, not
     squeezed into the same row -- the only reliable fix at this width. */
  .topNavCenter {
    grid-column: 1 / -1;
    grid-row: 2;
    column-gap: 2px;
  }

  .topNavCenter .topNavBtn {
    padding: 7px 9px;
    font-size: 0.62rem;
  }

  .topNavRight {
    margin-right: 4px;
  }
}

/* ============================================================================
   site-shell.css (shared by Dota/MLBB/LoL, loaded AFTER this file) carries
   its OWN complete :root palette and its OWN complete .topNav/.topNavTitle/
   .topNavBtn/.gameTag system, targeting the exact same selectors as this
   file. For any property both files set on the same selector/:root at tied
   specificity, the file loaded LATER wins -- which has been site-shell.css,
   silently undoing pieces of this redesign one property at a time all
   session (the gradient-text logo coming back, rounded nav/game-tag
   corners, even the whole palette, since both stylesheets declare the same
   --accent-purple/--bg/etc custom property names on :root).

   Fix: redeclare everything under body[data-game="dota"] instead of
   editing site-shell.css itself (which MLBB/LoL also load -- touching it
   would leak this redesign onto sites that never asked for it). A rule
   naming the actual <body data-game="dota"> element beats one naming an
   ancestor (:root/<html>) regardless of stylesheet order -- that's normal
   inheritance, not a specificity tie -- and a class/attribute selector
   this specific also outweighs site-shell's bare selectors and even its
   #siteTitle id rule once combined with the attribute selector's own
   specificity tier. This is the ONE place in the file relying on load
   order/cascade mechanics to win against another stylesheet; everywhere
   else in this file just needed its own correct value. ============== */
body[data-game="dota"] {
  --bg: #1e1e1e;
  --panel: #252526;
  --border: #3c3c3c;
  --text: #d4d4d4;
  --muted: #9d9d9d;
  --accent-purple: #7c3aed;
  --accent-purple-dark: #c4b5fd;
  --accent-purple-deep: #5b21b6;
  --accent-purple-tint: #2a2140;
  --accent-green: #4ec9b0;
  --accent-green-tint: #123832;
}

body[data-game="dota"] #siteTitle,
body[data-game="dota"] .topNavTitle,
body[data-game="dota"] .topNavTitle:hover {
  background: none;
  -webkit-background-clip: unset;
  background-clip: unset;
  color: #f3edfd;
}

body[data-game="dota"] .gameTag,
body[data-game="dota"] .gameSwitchMenu,
body[data-game="dota"] .gameSwitchMenu a {
  border-radius: 0;
}

@media (min-width: 701px) {
  body[data-game="dota"] .topNav {
    border-radius: 0;
    border: none;
    border-bottom: 3px solid var(--accent-purple);
    background: none;
  }

  body[data-game="dota"] .topNavCenter {
    grid-column: auto;
    grid-row: auto;
    justify-items: center;
  }

  body[data-game="dota"] .topNavBtn {
    border-radius: 0;
    color: var(--muted);
  }

  body[data-game="dota"] .topNavBtn--active,
  body[data-game="dota"] .topNavBtn--active:hover {
    background: var(--accent-purple);
    color: #1e1e1e;
  }

  body[data-game="dota"] .topNavRight .topNavBtn {
    border-radius: 0;
  }
}

@media (min-width: 701px) and (max-width: 1150px) {
  body[data-game="dota"] .topNavCenter {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}
/* ============================================================================ */

/* The dark palette earlier in this file is the default; this follows the
   OS/browser's own light-mode preference instead of forcing dark on
   everyone. Deliberately placed last in the file -- CSS resolves two
   same-specificity rules by source order regardless of which is wrapped in
   a media query, so an earlier override here would just lose to the later
   unconditional dark-tuned body/scrollbar rules above. Only the tones that
   actually differ between themes are overridden -- --accent-purple/
   --accent-purple-deep are solid fills with white text on top either way,
   so they don't need a light-mode variant. */
@media (prefers-color-scheme: light) {
  :root {
    --bg: #faf8ff;
    --panel: #ffffff;
    --border: #d9cff0;
    --text: #221d33;
    --muted: #625b76;
    --accent-purple-dark: #5b21b6;
    --accent-purple-tint: #f3edfd;
    --accent-green: #16a34a;
    --accent-green-tint: #eafbf0;
    color-scheme: light;
  }

  /* The body[data-game="dota"] block above (added to win against
     site-shell.css's competing :root) is unconditional/dark-only on its
     own -- being more specific than :root, it would otherwise silently
     win over this light-mode :root override too and force dark mode
     regardless of OS preference. Same values as the :root block just
     above, re-declared at the matching specificity so light mode still
     works for this site specifically. */
  body[data-game="dota"] {
    --bg: #faf8ff;
    --panel: #ffffff;
    --border: #d9cff0;
    --text: #221d33;
    --muted: #625b76;
    --accent-purple-dark: #5b21b6;
    --accent-purple-tint: #f3edfd;
    --accent-green: #16a34a;
    --accent-green-tint: #eafbf0;
  }

  body {
    background:
      radial-gradient(circle at 8% 0%, rgba(124, 58, 237, 0.10), transparent 45%),
      radial-gradient(circle at 95% 100%, rgba(168, 85, 247, 0.08), transparent 45%),
      var(--bg);
  }

  * {
    scrollbar-color: #c1c1c1 var(--bg);
  }

  *::-webkit-scrollbar-thumb {
    background: #c1c1c1;
  }

  *::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }
}

/* background-attachment: fixed is known to repaint/jump on mobile browsers
   (the fixed layer has to be recomposited against the visual viewport on
   every scroll frame, worse still while the address bar collapses/expands
   mid-scroll) -- this is very likely the "gradient flies off, content looks
   like it scrolls" glitch reported on phones. Scoped to mobile only since
   the fixed attachment is fine (and intentional) on desktop. */
@media (max-width: 700px) {
  html {
    /* Disables the elastic bounce past the top/bottom edge on browsers
       that respect it (modern Safari/Chrome on mobile) -- that bounce is
       what makes content look like it "уезжает" (drifts) briefly and,
       combined with any background seam, what made the gradient look
       broken at the bottom of the page. */
    overscroll-behavior-y: none;
  }

  body {
    background-attachment: scroll;
  }

  /* Same-size boxes as always, just nudged down -- on a phone the empty
     tail below a short, result-less draft page reads as broken, so split
     that leftover space above the grid instead of leaving it all below --
     a bit more than before now that the removed "Назад" button left extra
     room up top. */
  .draftTeams {
    margin-top: 40px;
  }
}

#mistakeQuotaNote {
  text-align: center;
}
